这一小节主要学习动画。
在JavaScript中的动画,其实就是渲染一帧,停顿一会儿,再渲染一帧。所以我们需要在每一帧都更新物体和重新渲染。
调用window.requestAnimationFrame();
函数来实现。
The purpose of requestAnimationFrame
is to call the function provided on the next frame.
We are going to call the same function on each new frame.
就是requestAnimationFrame
函数的目的是提供下一帧的画面,而不是做了一个动画,只是看起来像动画一样。
会在每一帧上调用这个函数,连起来就像动画了。
function render() {if (cube.position.x > 10) {cube.position.x = 0;}cube.position.x += 0.01cube.rotation.z += 0.05renderer.render(scene, camera);//渲染下一帧的时候就会调用render函数//这两个都是一样的requestAnimationFrame(render);window.requestAnimationFrame(render);
}render()
在不同的电脑上,会有不同的帧率,这就会导致相同的代码,在有的电脑上,动画就会快一点,有的则会慢一点。
We need to know how much time it's been since the last tick.
Use Date.now()
to get the current timestamp.
所以我们要知道和最新的帧画面和现在间隔了多久,使用Date.now()
来获取准确的时间戳。
Subtract the previous time to get the deltaTime
.
Use the deltaTime
in the animation.
减去上一个时间戳就可以得到时间差,将时间差用在动画中,这样的动画就不会有差异。
let time = Date.now();function render() {const currentTime = Date.now();const deltaTime = currentTime - time;time = currentTime;cube.rotation.y += 0.01 * deltaTime;renderer.render(scene, camera);requestAnimationFrame(render);
}render()
不同的电脑会得到不同的deltaTime
,帧率高的deltaTime
就会小,每一帧移动的就小,帧率低的deltaTime
就会大,每一帧移动的就大。将deltaTime
和累加的值相乘,这样就达到了动画的平衡。
同时可以使用THREE.js中内置的Clock来解决问题。
实例化Clock
并使用其getElapsedTime()
方法
// Clock
const clock = new THREE.Clock();
function render() {// if (cube.position.x > 10) {// cube.position.x = 0;// }// cube.position.x += 0.01// cube.rotation.x += 0.01const elapesdTime = clock.getElapsedTime();cube.rotation.y = elapesdTime// cube.rotation.z += 0.01renderer.render(scene, camera);requestAnimationFrame(render);
}
getElapsedTime()
获得的是时钟的总运行时间,单位为秒
同时,还可以在render()
函数中这样写
//一秒钟转一圈的话
cube.rotation.y = elapesdTime * Math.PI * 2;
//也可以使用上sin,cos函数,实现往返周期性运动,下面是围绕着z轴的圆周运动
cube.position.y = Math.sin(elapesdTime);
cube.position.x = Math.cos(elapesdTime);
使用library,来获取更多的控制
If you want to have more control,create tweens,create timelines,etc.you can use a library like GSAP
//安装,引入GSAPnpm install --save gsap@3.5.1import gsap from 'gsap';
//使用gsap创建一个tween
//第一个参数是模型的位置,第二个参数是一个对象,里面包含duration(周期),delay(延迟),x(位移)
//这句话的意思就是延迟一秒之后将cube沿着x轴在两秒内移动2单位
gsap.to(cube.position, { duration: 2, delay: 1, x: 2 });