KeyframeTrack
是 Three.js 动画系统中的核心组件之一。通过 KeyframeTrack
,我们可以定义物体在不同时间点的属性值,从而实现平滑过渡的动画效果。它通常与 AnimationClip
、AnimationMixer
、AnimationAction
等其他动画组件配合使用,来创建复杂的动画。
在本博客中,我们将详细讲解 KeyframeTrack
的使用,涵盖它的所有属性和方法,并结合其他组件,通过多个示例代码展示如何使用它来创建动画效果。
KeyframeTrack
用于定义某个对象属性(如位置、旋转、缩放等)在一段时间内的变化。它本质上是一条包含时间和属性值的“关键帧轨道”,通过插值这些关键帧来产生动画。
KeyframeTrack( name, times, values, interpolation )
name
:字符串,表示轨道的名称,通常以 '.'
分隔,用于指定对象的具体属性。例如:'mesh.position'
。times
:数组,表示动画关键帧发生的时间点。values
:数组,表示在每个时间点上属性的值。interpolation
:插值方式,默认是 THREE.InterpolateLinear
,也可以使用其他插值方法。Three.js 提供了多种具体的 KeyframeTrack
类型来处理不同类型的属性:
VectorKeyframeTrack
:用于矢量属性(如位置、缩放)的动画。QuaternionKeyframeTrack
:用于旋转(四元数)的动画。ColorKeyframeTrack
:用于颜色属性的动画。NumberKeyframeTrack
:用于数值属性的动画。BooleanKeyframeTrack
:用于布尔值属性的动画。StringKeyframeTrack
:用于字符串属性的动画。创建一个简单的物体位置变化动画:
import * as THREE from 'three';
// 场景和相机
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建一个简单的几何体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 创建位置关键帧动画
const times = [0, 1, 2]; // 关键帧时间点
const values = [0, 0, 0, 5, 5, 0, -5, 0, 0]; // 对应时间点的坐标
const positionTrack = new THREE.VectorKeyframeTrack('.position', times, values);
// 创建 AnimationClip
const clip = new THREE.AnimationClip('move', -1, [positionTrack]);
// 动画混合器
const mixer = new THREE.AnimationMixer(cube);
const action = mixer.clipAction(clip);
action.play();
// 渲染循环
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
// 更新混合器时间
const delta = clock.getDelta();
mixer.update(delta);
renderer.render(scene, camera);
}
animate();
通过四元数旋转物体:
const times = [0, 1, 2]; // 时间
const values = [
0, 0, 0, 1, // 初始旋转(四元数)
0.707, 0, 0, 0.707, // 旋转90度
0, 0, 0, 1 // 恢复原状
];
const rotationTrack = new THREE.QuaternionKeyframeTrack('.quaternion', times, values);
const clip = new THREE.AnimationClip('rotate', -1, [rotationTrack]);
const mixer = new THREE.AnimationMixer(cube);
const action = mixer.clipAction(clip);
action.play();
改变物体颜色的动画:
const times = [0, 1, 2];
const values = [1, 0, 0, 0, 1, 0, 0, 0, 1]; // RGB颜色变化
const colorTrack = new THREE.ColorKeyframeTrack('.material.color', times, values);
const clip = new THREE.AnimationClip('colorChange', -1, [colorTrack]);
const mixer = new THREE.AnimationMixer(cube);
const action = mixer.clipAction(clip);
action.play();
修改物体的不透明度(opacity)动画:
const times = [0, 1, 2];
const values = [1, 0.5, 0]; // 透明度变化
const opacityTrack = new THREE.NumberKeyframeTrack('.material.opacity', times, values);
cube.material.transparent = true; // 使材质透明以支持透明度
const clip = new THREE.AnimationClip('fade', -1, [opacityTrack]);
const mixer = new THREE.AnimationMixer(cube);
const action = mixer.clipAction(clip);
action.play();
控制物体可见性:
const times = [0, 1, 2];
const values = [true, false, true]; // 可见性变化
const visibilityTrack = new THREE.BooleanKeyframeTrack('.visible', times, values);
const clip = new THREE.AnimationClip('visibilityChange', -1, [visibilityTrack]);
const mixer = new THREE.AnimationMixer(cube);
const action = mixer.clipAction(clip);
action.play();
虽然比较少见,但可以通过 StringKeyframeTrack
改变对象的某些字符串属性:
const times = [0, 1, 2];
const values = ['first', 'second', 'third'];
const stringTrack = new THREE.StringKeyframeTrack('.name', times, values);
const clip = new THREE.AnimationClip('nameChange', -1, [stringTrack]);
const mixer = new THREE.AnimationMixer(cube);
const action = mixer.clipAction(clip);
action.play();
KeyframeTrack
本身提供了一些用于控制和获取轨道信息的方法和属性:
name
:轨道的名称。times
:包含关键帧时间点的数组。values
:包含关键帧值的数组。ValueTypeName
:轨道值的类型。TimeBufferType
:时间缓冲区的类型,通常为 Float32Array
。ValueBufferType
:值缓冲区的类型。getValueSize()
:返回每个关键帧的值的大小。对于位置、颜色等,通常是 3;对于四元数,则是 4。validate()
:验证时间和值数组是否匹配。optimize()
:删除冗余关键帧,优化轨道。const isValid = positionTrack.validate(); // 验证轨道是否有效
positionTrack.optimize(); // 优化轨道
KeyframeTrack
通常不会单独使用,而是与 AnimationClip
和 AnimationMixer
配合使用:
AnimationClip
:包含一个或多个 KeyframeTrack
的动画片段。AnimationMixer
:管理和控制动画片段的播放。我们通过这些组件将 KeyframeTrack
转化为可以播放的动画。
// 定义关键帧轨道
const positionTrack = new THREE.VectorKeyframeTrack('.position', times, values);
// 创建动画剪辑
const clip = new THREE.AnimationClip('move', -1, [positionTrack]);
// 创建混合器和动作
const mixer = new THREE.AnimationMixer(cube);
const action = mixer.clipAction(clip);
// 播放动画
action.play();
import * as THREE from 'three';
// 初始化场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建几何体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 创建位置、旋转、颜色和透明度的关键帧轨道
const positionTrack = new THREE.VectorKeyframeTrack('.position', [0, 2, 4], [0, 0, 0, 2, 2, 0, 0, 0, 0]);
const rotationTrack = new THREE.QuaternionKeyframeTrack('.quaternion', [0, 2, 4], [0, 0, 0, 1, 0.707, 0, 0.707, 0, 0, 0, 1]);
const colorTrack = new THREE.ColorKeyframeTrack('.material.color', [0, 2, 4], [1, 0, 0, 0, 1, 0, 0, 0, 1]);
const opacityTrack = new THREE.NumberKeyframeTrack('.material.opacity', [0, 2, 4], [1, 0.5, 0]);
// 创建动画剪辑
const clip = new THREE.AnimationClip('complexAnimation', -1, [positionTrack, rotationTrack, colorTrack, opacityTrack]);
// 创建动画混合器并播放
const mixer = new THREE.AnimationMixer(cube);
const action = mixer.clipAction(clip);
action.play();
// 渲染循环
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
mixer.update(delta); // 更新混合器
renderer.render(scene, camera); // 渲染场景
}
animate();
KeyframeTrack
是 Three.js 动画系统的重要组成部分,通过它我们可以实现丰富多彩的动画效果。在本篇博客中,我们详细介绍了 KeyframeTrack
的使用,涵盖了多种类型的关键帧轨道及其结合使用的示例。掌握 KeyframeTrack
的用法将使您在 Three.js 中实现复杂动画变得轻松而高效。希望这些示例和代码能够帮助您更好地理解 Three.js 动画系统的强大功能。