6.1动画基础 Three.js 动画 (Animation) 与交互 (Interaction) 6.1 动画基础 6.1.1 动画原理 Three.js 中的动画本质上是在每一帧更新对象的位置、旋转、缩放等属性,从而产生连续运动的视觉效果。这个更新过程通常在渲染循环中完成。 渲染循环 (Render Loop) 渲染循环是 Three.js 动画的核心,它不断地执行以下步骤: 更新 (Update): 修改场景中对象的状态(位置、旋转、缩放等)。 渲染 (Render): 根据场景中的对象状态,将场景渲染到画布上。 6.1.2 使用 是浏览器提供的 API,用于在浏览器准备好重绘时通知我们。它比 或 更高效,因为它会根据浏览器的刷新率自动调整回调函数的执行频率。
Three.js 中的动画本质上是在每一帧更新对象的位置、旋转、缩放等属性,从而产生连续运动的视觉效果。这个更新过程通常在渲染循环中完成。
渲染循环 (Render Loop)
渲染循环是 Three.js 动画的核心,它不断地执行以下步骤:
更新 (Update): 修改场景中对象的状态(位置、旋转、缩放等)。
渲染 (Render): 根据场景中的对象状态,将场景渲染到画布上。
requestAnimationFramerequestAnimationFrame 是浏览器提供的 API,用于在浏览器准备好重绘时通知我们。它比 setInterval 或 setTimeout 更高效,因为它会根据浏览器的刷新率自动调整回调函数的执行频率。
代码示例:
// 创建场景、相机、渲染器... (省略) // 创建一个立方体 const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); // 动画函数 function animate() { requestAnimationFrame( animate ); // 更新立方体的旋转 cube.rotation.x += 0.01; cube.rotation.y += 0.01; // 渲染场景 renderer.render( scene, camera ); } // 启动动画 animate();
代码解释:
创建场景、相机、渲染器: 这是 Three.js 动画的基础,用于设置场景、观察视角和渲染输出。
创建立方体: 我们创建一个简单的立方体作为动画对象。
animate() 函数:
requestAnimationFrame( animate ):告诉浏览器在下次重绘之前调用 animate() 函数。
cube.rotation.x += 0.01; cube.rotation.y += 0.01;:更新立方体的 x 和 y 轴旋转角度。
renderer.render( scene, camera ):使用相机从指定视角渲染场景。
animate() 函数调用: 第一次调用 animate() 函数启动动画循环。
Clock 对象THREE.Clock 对象用于跟踪时间,可以更精确地控制动画速度。
代码示例:
// 创建场景、相机、渲染器... (省略) // 创建一个立方体 const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); // 创建 Clock 对象 const clock = new THREE.Clock(); // 动画函数 function animate() { requestAnimationFrame( animate ); // 获取时间差 const deltaTime = clock.getDelta(); // 更新立方体的旋转 (根据时间差调整旋转速度) cube.rotation.x += deltaTime; cube.rotation.y += deltaTime * 0.5; // 渲染场景 renderer.render( scene, camera ); } // 启动动画 animate();
代码解释:
创建 THREE.Clock 对象: const clock = new THREE.Clock();
clock.getDelta(): 获取自上次调用 getDelta() 以来经过的时间(以秒为单位)。
根据时间差调整旋转速度: cube.rotation.x += deltaTime; 使用 deltaTime 乘以旋转速度,可以使动画在不同帧率下保持一致的速度。
Tween.js 是一个强大的 JavaScript 动画库,可以轻松创建各种复杂的动画效果。它支持链式调用、缓动函数、回调函数等特性。
安装 Tween.js:
npm install @tweenjs/tween.js
代码示例:
import * as TWEEN from '@tweenjs/tween.js' // 创建场景、相机、渲染器... (省略) // 创建一个立方体 const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); // 创建 Tween 对象 const tween = new TWEEN.Tween( cube.position ) .to( { x: 5 }, 2000 ) // 移动到 x: 5,耗时 2 秒 .easing( TWEEN.Easing.Quadratic.InOut ) // 使用缓动函数 .repeat( Infinity ) // 无限循环 .yoyo( true ) // 来回运动 .start(); // 动画函数 function animate() { requestAnimationFrame( animate ); // 更新 Tween TWEEN.update(); // 渲染场景 renderer.render( scene, camera ); } // 启动动画 animate();
代码解释:
导入 Tween.js: import * as TWEEN from '@tweenjs/tween.js'
创建 TWEEN.Tween 对象:
new TWEEN.Tween( cube.position ):指定要动画的对象(立方体的位置)。
.to( { x: 5 }, 2000 ):指定目标属性(x 坐标为 5)和动画持续时间(2 秒)。
.easing( TWEEN.Easing.Quadratic.InOut ):指定缓动函数,使动画效果更自然。
.repeat( Infinity ):指定动画循环次数(无限循环)。
.yoyo( true ):指定动画是否来回运动。
.start():启动动画。
TWEEN.update(): 在每一帧更新 Tween 对象的状态。
缓动函数用于控制动画的速度变化,使动画效果更自然。Tween.js 提供了丰富的缓动函数,例如:
TWEEN.Easing.Linear.None:线性缓动
TWEEN.Easing.Quadratic.InOut:二次方缓动(先加速后减速)
TWEEN.Easing.Cubic.InOut:三次方缓动
TWEEN.Easing.Bounce.Out:弹跳缓动
Tween.js 允许你添加动画事件,在动画开始、结束、更新时执行自定义函数。
代码示例:
// 创建 Tween 对象 const tween = new TWEEN.Tween( cube.position ) .to( { x: 5 }, 2000 ) .onStart( () => { console.log( '动画开始' ); } ) .onUpdate( (object) => { console.log( '当前位置:', object.x ); } ) .onComplete( () => { console.log( '动画结束' ); } ) .start();
关键帧动画是一种更复杂的动画技术,它允许你定义对象在不同时间点的状态(位置、旋转、缩放等),然后 Three.js 会自动插值这些状态,生成连续的动画。
代码示例(简要说明):
定义关键帧: 创建一个包含时间点和对应对象状态的数组。
创建 THREE.KeyframeTrack 对象: 为每个属性(位置、旋转、缩放等)创建一个 KeyframeTrack 对象。
创建 THREE.AnimationClip 对象: 将 KeyframeTrack 对象添加到 AnimationClip 对象中。
创建 THREE.AnimationMixer 对象: 使用 AnimationMixer 对象播放动画。
关键帧动画通常用于骨骼动画,可以创建更逼真的角色动画。
本节介绍了 Three.js 动画的基础知识,包括动画原理、渲染循环、requestAnimationFrame、THREE.Clock、Tween.js 库、缓动函数、动画事件和关键帧动画。掌握这些基础知识,可以让你创建各种各样的动画效果,为你的 Three.js 项目增添活力。通过实践这些代码示例,你将更深入地理解 Three.js 动画的原理和实现方式。