AnimationMixer
是 Three.js 动画系统中的核心组件,用于管理、播放和混合多个 AnimationClip
(动画片段)。通过 AnimationMixer
,我们可以对动画进行精确的控制,包括播放、暂停、停止和混合多个动画效果。本文将详细介绍 AnimationMixer
的使用方法,涵盖其属性、方法,并结合 AnimationClip
和 AnimationAction
展示动画的创建和控制。
AnimationMixer
是一个动画混合器类,主要负责管理场景中一个 3D 对象(如网格、骨骼等)的动画。一个对象可以包含多个动画片段(AnimationClip
),AnimationMixer
提供了接口来对这些动画进行播放、暂停、停止和混合等操作。
要使用 AnimationMixer
,我们通常需要执行以下步骤:
Mesh
)。AnimationClip
)。AnimationMixer
并将其绑定到 3D 对象。AnimationMixer
创建并控制动画实例(AnimationAction
)。AnimationMixer
。下面,我们将通过示例逐步展示这些操作。
首先,我们需要创建一个基本的 Three.js 场景,设置渲染器、摄像机和一个简单的几何对象。为了演示,我们将使用一个简单的立方体。
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z = 5;
创建一个简单的立方体,并将其添加到场景中。
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);
AnimationClip
定义了动画的内容,它由一组关键帧(KeyframeTrack
)组成。在这个示例中,我们将使用 VectorKeyframeTrack
来控制立方体沿 Y 轴的移动。
const times = [0, 1, 2]; // 定义动画时间点
const values = [0, 0, 0, 0, 2, 0, 0, 0, 0]; // 在不同时间点的位置
const positionKF = new THREE.VectorKeyframeTrack('.position', times, values);
// 创建 AnimationClip
const clip = new THREE.AnimationClip('moveUp', 2, [positionKF]);
现在,我们需要创建 AnimationMixer
并将其绑定到我们的立方体对象,然后通过它来播放动画。
AnimationMixer
需要绑定到一个 3D 对象(在本例中是立方体 cube
),从而控制其动画。
const mixer = new THREE.AnimationMixer(cube);
使用 AnimationMixer
的 clipAction
方法创建一个 AnimationAction
,并调用 play()
方法开始播放动画。
const action = mixer.clipAction(clip);
action.play();
在渲染循环中,我们需要不断更新 AnimationMixer
以驱动动画。可以通过 Clock
来计算每一帧的时间差,并将其传递给 mixer.update()
。
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta(); // 获取时间增量
mixer.update(delta); // 更新动画混合器
renderer.render(scene, camera);
}
animate();
AnimationMixer
的当前时间,通常通过 update()
方法自动更新。timeScale
设置为 0.5,动画播放速度将减半;设置为 2,则动画速度加倍。mixer.timeScale = 0.5; // 动画以半速播放
AnimationAction
,用来控制 AnimationClip
的播放。deltaTime
是从上次更新到现在经过的时间。AnimationClip
,通常用于节省内存。AnimationAction
是控制动画播放的关键组件,它由 AnimationMixer
创建并管理。通过 AnimationAction
,我们可以控制动画的播放、暂停、停止、混合等行为。
通过 play()
和 pause()
方法,可以控制动画的播放和暂停。
action.play(); // 播放动画
action.paused = true; // 暂停动画
可以通过 setLoop()
方法设置动画的循环方式。Three.js 提供了三种循环模式:
THREE.LoopOnce
:动画只播放一次。THREE.LoopRepeat
:动画重复播放。THREE.LoopPingPong
:动画来回播放。action.setLoop(THREE.LoopPingPong, Infinity); // 设置动画来回循环播放
AnimationMixer
支持多个动画的混合播放。可以通过设置 AnimationAction
的 weight
属性来控制不同动画的混合比例。
action.weight = 0.5; // 设置当前动画的权重为 0.5
通过 stop()
方法可以停止当前动画的播放。
action.stop(); // 停止动画
在实际项目中,我们通常需要为同一个对象创建多个动画,并在不同的时刻混合播放。AnimationMixer
提供了丰富的接口来实现这种需求。
我们再创建一个沿 X 轴移动的动画,并将其与之前的 Y 轴动画混合播放。
const times2 = [0, 1, 2];
const values2 = [0, 0, 0, 2, 0, 0, 0, 0, 0];
const positionKF2 = new THREE.VectorKeyframeTrack('.position', times2, values2);
const clip2 = new THREE.AnimationClip('moveSide', 2, [positionKF2]);
const action2 = mixer.clipAction(clip2);
action2.play();
我们可以通过调整 action
和 action2
的 weight
属性来实现动画的平滑过渡。
action.weight = 0.5;
action2.weight = 0.5;
这样,立方体将同时沿 Y 轴和 X 轴移动,产生对角线方向的移动效果。
AnimationMixer
允许我们监听动画播放过程中的事件,如动画完成、循环等。可以通过 mixer.addEventListener()
来监听这些事件。
mixer.addEventListener('finished', (event) => {
console.log('动画播放完成');
});
我们还可以监听动画的循环事件,特别是在需要处理动画状态切换时非常有用。
mixer.addEventListener('loop', (event) => {
console.log('动画循环');
});
在实际应用中,我们需要在窗口大小发生变化时,更新摄像机和渲染器的参数,以确保动画的正确显示。
window.addEventListener('
resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
AnimationMixer
是 Three.js 动画系统中的核心组件,提供了灵活的接口来管理、控制和混合动画。本文详细介绍了如何创建、使用 AnimationMixer
,并通过多种示例展示了 AnimationClip
和 AnimationAction
的综合使用。通过对动画时间、权重和循环的精确控制,我们可以创建出复杂、流畅的动画效果。
希望本文能够帮助你深入理解和掌握 Three.js 的动画系统!如果你有任何问题或建议,欢迎留言讨论。