6.3简单属性动画 Three.js 动画与交互:6.3 简单属性动画详解 动画是让3D场景栩栩如生的关键。在Three.js中,我们可以通过多种方式实现动画,其中最基础也是最常用的方法之一就是简单属性动画。简单属性动画通过在一段时间内改变对象的属性值来实现动画效果,例如位置、旋转、缩放、颜色等。 6.3.1 简单属性动画的核心概念 简单属性动画的核心在于通过在每一帧更新对象的属性值,从而产生动画效果。 我们需要明确以下几个关键概念: 目标对象 (Target Object): 需要进行动画的对象,例如 , 等。 目标属性 (Target Property): 需要改变的对象的属性,例如 , , , 等。 起始值 (Start Value): 动画开始时属性的初始值。
动画是让3D场景栩栩如生的关键。在Three.js中,我们可以通过多种方式实现动画,其中最基础也是最常用的方法之一就是简单属性动画。简单属性动画通过在一段时间内改变对象的属性值来实现动画效果,例如位置、旋转、缩放、颜色等。
简单属性动画的核心在于通过在每一帧更新对象的属性值,从而产生动画效果。 我们需要明确以下几个关键概念:
目标对象 (Target Object): 需要进行动画的对象,例如 THREE.Mesh, THREE.Object3D 等。
目标属性 (Target Property): 需要改变的对象的属性,例如 position.x, rotation.y, scale.z, material.color 等。
起始值 (Start Value): 动画开始时属性的初始值。
结束值 (End Value): 动画结束时属性的目标值。
持续时间 (Duration): 动画从开始到结束所需要的时间,通常以毫秒为单位。
缓动函数 (Easing Function): 控制动画速度变化的函数,决定动画的平滑程度。常见的缓动函数包括线性缓动、加速缓动、减速缓动等。
动画循环 (Animation Loop): 不断更新属性值并渲染场景的循环,通常使用 requestAnimationFrame 实现。
Tween.js 实现简单属性动画虽然可以直接在动画循环中手动更新属性值,但使用专门的动画库可以更方便地管理和控制动画。 Tween.js 是一个轻量级的JavaScript动画库,非常适合实现简单属性动画。
1. 引入 Tween.js:
首先,你需要将 Tween.js 引入到你的项目中。 可以通过 npm 安装:
npm install @tweenjs/tween.js
或者直接在HTML文件中引入CDN链接:
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/18.6.4/Tween.min.js"></script>
2. 创建 Tween 实例:
接下来,你需要创建一个 TWEEN.Tween 实例,并指定目标对象、目标属性、起始值、结束值、持续时间以及缓动函数。
import * as TWEEN from '@tweenjs/tween.js' import * as THREE from 'three'; // 创建一个立方体 const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); // 定义动画的起始值和结束值 const startPosition = { x: 0, y: 0, z: 0 }; const endPosition = { x: 5, y: 3, z: 2 }; // 创建 Tween 实例 const tween = new TWEEN.Tween(cube.position) // 目标对象和目标属性 .to(endPosition, 2000) // 结束值和持续时间(毫秒) .easing(TWEEN.Easing.Quadratic.InOut) // 缓动函数 .onUpdate(() => { // 在每一帧更新对象的位置 // cube.position.x = currentPosition.x; // cube.position.y = currentPosition.y; }) .onComplete(() => { console.log("动画完成!"); });
代码解释:
new TWEEN.Tween(cube.position): 创建一个 Tween 实例,并将 cube.position 作为目标对象和目标属性。 这意味着我们将要改变立方体的位置。
.to(endPosition, 2000): 指定动画的结束值 endPosition 和持续时间 2000 毫秒。
.easing(TWEEN.Easing.Quadratic.InOut): 设置缓动函数为 TWEEN.Easing.Quadratic.InOut,这是一种二次方的缓动函数,动画开始和结束时速度较慢,中间速度较快。 Tween.js 提供了多种缓动函数,你可以根据需要选择合适的缓动函数。
.onUpdate(() => { ... }): 注册一个回调函数,在动画的每一帧都会被调用。 你可以在这个回调函数中更新对象的属性值。 在例子中,我们使用了 cube.position 属性直接更新,所以可以省略这个回调函数。
.onComplete(() => { ... }): 注册一个回调函数,在动画完成后会被调用。
3. 启动动画:
调用 tween.start() 启动动画。
tween.start();
4. 在动画循环中更新 Tween:
在动画循环中,你需要调用 TWEEN.update() 来更新 Tween 实例,使其能够根据时间和缓动函数计算出当前属性值。
function animate() { requestAnimationFrame( animate ); TWEEN.update(); // 更新 Tween 实例 renderer.render( scene, camera ); } animate();
完整代码示例:
import * as THREE from 'three'; import * as TWEEN from '@tweenjs/tween.js' // 创建场景、相机和渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // 创建一个立方体 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 ); camera.position.z = 5; // 定义动画的起始值和结束值 const startPosition = { x: 0, y: 0, z: 0 }; const endPosition = { x: 5, y: 3, z: 2 }; // 创建 Tween 实例 const tween = new TWEEN.Tween(cube.position) // 目标对象和目标属性 .to(endPosition, 2000) // 结束值和持续时间(毫秒) .easing(TWEEN.Easing.Quadratic.InOut) // 缓动函数 .onComplete(() => { console.log("动画完成!"); }); // 启动动画 tween.start(); // 动画循环 function animate() { requestAnimationFrame( animate ); TWEEN.update(); // 更新 Tween 实例 renderer.render( scene, camera ); } animate();
Tween.js 还支持动画链和动画组,可以让你创建更复杂的动画效果。
1. 动画链 (Chaining):
使用 .chain() 方法可以将多个 Tween 实例连接起来,形成一个动画链。 当第一个动画完成后,会自动启动下一个动画。
const tween1 = new TWEEN.Tween(cube.position) .to({ x: 5 }, 1000) .easing(TWEEN.Easing.Linear.None); const tween2 = new TWEEN.Tween(cube.rotation) .to({ y: Math.PI * 2 }, 1000) .easing(TWEEN.Easing.Linear.None); tween1.chain(tween2); // 将 tween2 连接到 tween1 之后 tween1.start();
2. 动画组 (Groups):
使用 TWEEN.Group 可以将多个 Tween 实例组合在一起,同时启动和控制这些动画。
const group = new TWEEN.Group(); const tween1 = new TWEEN.Tween(cube.position, group) .to({ x: 5 }, 1000) .easing(TWEEN.Easing.Linear.None); const tween2 = new TWEEN.Tween(cube.rotation, group) .to({ y: Math.PI * 2 }, 1000) .easing(TWEEN.Easing.Linear.None); tween1.start(); tween2.start(); // 在动画循环中更新动画组 function animate() { requestAnimationFrame( animate ); group.update(); // 更新动画组 renderer.render( scene, camera ); } animate();
缓动函数决定了动画的速度变化。 Tween.js 提供了多种内置的缓动函数,你可以通过 TWEEN.Easing 对象访问它们。 常见的缓动函数包括:
Linear: 线性缓动,速度恒定。
Quadratic: 二次方缓动,加速或减速。
Cubic: 三次方缓动,加速或减速更明显。
Quartic: 四次方缓动,加速或减速更加明显。
Quintic: 五次方缓动,加速或减速非常明显。
Sinusoidal: 正弦缓动,产生平滑的加速和减速效果。
Exponential: 指数缓动,产生非常快速的加速或减速效果。
Circular: 圆形缓动,产生类似于圆形运动的效果。
Elastic: 弹性缓动,产生弹性振荡的效果。
Back: 回退缓动,先向后退一步,然后再向前进。
Bounce: 弹跳缓动,产生弹跳的效果。
每种缓动函数都有三种变体:
In: 动画开始时速度较慢,然后逐渐加速。
Out: 动画开始时速度较快,然后逐渐减速。
InOut: 动画开始和结束时速度较慢,中间速度较快。
例如,TWEEN.Easing.Quadratic.In 表示二次方加速缓动,TWEEN.Easing.Quadratic.Out 表示二次方减速缓动,TWEEN.Easing.Quadratic.InOut 表示二次方先加速后减速缓动。
你可以通过调整缓动函数来改变动画的风格,使其更符合你的需求。
简单属性动画可以应用于各种场景,例如:
物体移动: 改变物体的位置,使其在场景中移动。
物体旋转: 改变物体的旋转角度,使其旋转。
物体缩放: 改变物体的缩放比例,使其放大或缩小。
材质颜色变化: 改变材质的颜色,使其产生颜色渐变效果。
相机移动: 改变相机的位置或朝向,实现视角切换。
光照强度变化: 改变光照的强度,实现光照动画效果。
简单属性动画是Three.js中一种基础但强大的动画技术。 通过 Tween.js 等动画库,我们可以方便地创建和管理各种属性动画,为3D场景增添生动的效果。 掌握简单属性动画是学习更高级动画技术的基础,例如骨骼动画、粒子动画等。
希望本文能够帮助你理解和掌握Three.js中的简单属性动画,并在你的3D项目中应用它们。 通过实践和探索,你将能够创造出令人惊叹的动画效果!