02 - three.js 笔记 - 使用setInterval和requestAnimationFrame实现动画效果

如果想要在场景中实现动画效果,需要使场景以一定的时间间隔进行渲染。
示例浏览地址:http://www.ithanmang.com/threejshome/201806/20180623/02-add-animation.html

1 setInterval

在H5 和 jsAPI接口之前使用的方法是 setInterval 方法

  • setInterval
    作用:在播放动画时,按照一定的时间间隔就调用传入的方法或对象。
  • 格式如下:
    setInterval( function,interval[arg1,...argn] )或者setInterval( object,methodName,interval[arg1,...argn] )
    第一种是默认语法,第二种是专家模式中使用的语法。
    参数:function,是一个函数名或者是一个匿名函数、object,指示一个对象,methodName是参数object中的方法名、interval 是时间间隔参数,单位是毫秒。
    看下面的示例:在页面显示当前系统时间

    /**
     * 动态添加 html 元素到div
     */
    function showTime(){
    
        var time = new Date();
    
        var hour = time.getHours();
        var minutes = time.getMinutes();
        var seconds = time.getSeconds();
        document.getElementById('dynamicTime').innerHTML = "<h1> 当前系统时间 "+hour+" : "+minutes+" : "+seconds+" </h1>"
    }
    
    /**
     * 参数 function : showTime
     * 间隔 interval : 1000 毫秒
     */
    setInterval(showTime, 1000);

    效果
    这里写图片描述
    当然这种效果使用 setTimeout 方法也能实现。

    • clearInterval
      与 setInterval 对应的方法清除对 setInterval 方法的调用效果。
      使用如下,clearInterval(参数 ),这个参数是 setInterval 返回的。
<script>
    var i = 10;
    function fun(){
        console.log('每隔一毫秒调用一次!'+i);
        document.getElementById('dynamicTime').innerHTML = "<h1>倒计时:"+i+"</h1>";
        if (i == -1){
            clearInterval(flag);
            document.getElementById('dynamicTime').innerHTML = "<h1> 倒计时结束! </h1>";
        }
        i--;
      }

 var flag = setInterval(fun, 1000);
</script>

这是一个倒计时的示例,当 i 等于-1 的时候会停止动画效果。

2 requestAnimationFrame

当然使用 setInterval 方法可以实现动画效果但是,setInterval() 方法有一定的缺点,

setInterval() 方法,不考虑浏览器中发生的事情,如果你正在浏览其他页面,这个函数仍然会每隔几毫秒就会被调用一次,除此之外,setInterval() 方法并没有跟显示器的重画同步,着可能会导致较高的CPU使用,降低系统效率。—《three.js 开发指南》

现在的浏览器都解决了这个问题,即使用requestAnimationFrame() 函数,这个函数的时间间隔是浏览器定义的,我们可以在指定的函数里面实现绘画操作。

var i = 0;
function animation() {
    requestAnimationFrame(animation);
    console.log(i++);
}
animation();

打开控制台可以看到,在不断的输出 i 的值。
因此,我们可以使用这个方法来时实现立方体绕着坐标轴旋转。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>加入动画效果</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
    <script src="../libs/jquery-1.9.1.js"></script>
    <script src="../libs/build/three.js"></script>

</head>
<body>

<div id="WebGL-output"></div>
<script>

    $(function () {

        // 创建场景
        var scene = new THREE.Scene();

        // 创建相机
        var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);

        // 创建渲染器
        var webGLRenderer = new THREE.WebGLRenderer();

        // 配置相机
        camera.position.set(200, 150, 200);
        camera.lookAt(new THREE.Vector3(0, 0, 0));

        // 配置渲染器
        webGLRenderer.antialias = true;
        webGLRenderer.autoClear = true;
        webGLRenderer.setClearColor(0x050505);
        webGLRenderer.setSize(window.innerWidth, window.innerHeight);

        webGLRenderer.shadowMap.enabled = true;

        // 创建灯光
        var ambientLight = new THREE.AmbientLight({color: 0x404040});
        scene.add(ambientLight);

        // 添加光源
        var spotLight = new THREE.SpotLight(0xcccccc);
        spotLight.position.set(-100, 300, 10);
        spotLight.castShadow = true;
        scene.add(spotLight);


        // 创建平面
        var planeGeometry = new THREE.PlaneGeometry(200, 400);
        var planeMaterial = new THREE.MeshLambertMaterial({color: 0xCCCCCC});
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);

        plane.receiveShadow = true;

        // 绕x轴旋转90度
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.y = -10;
        plane.position.x = -10;
        plane.position.z = -80;
        scene.add(plane);

        // 创建立方体
        var cubeGeometry = new THREE.CubeGeometry(50, 50, 50);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff});
        var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.position.y = 35;
        cube.position.x = 10;
        cube.position.z = -30;
        cube.castShadow = true;
        scene.add(cube);

        // 把渲染的页面添加到div
        $("#WebGL-output").append(webGLRenderer.domElement);


        function render(){
            // 让立方体 绕坐标轴旋转
            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;
            cube.rotation.z += 0.01;

            // 开始渲染
            webGLRenderer.render(scene, camera);
        }
        加入动画效果
        function animate() {
            requestAnimationFrame(animate);
            render();
        }
        animate();

        // setInterval(function () {
        //     render();
        // },10);

    });

</script>

</body>
</html>

猜你喜欢

转载自blog.csdn.net/ithanmang/article/details/80785513