如果想要在场景中实现动画效果,需要使场景以一定的时间间隔进行渲染。
示例浏览地址: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 返回的。
- clearInterval
<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>