在 Three.js 动画系统中,AnimationAction
是用来控制动画的关键部分。它允许我们播放、暂停、停止动画,并对动画的速度、权重、循环行为进行控制。AnimationAction
与 AnimationMixer
和 AnimationClip
一起使用,能够轻松创建和管理复杂的动画效果。
本文将详细讲解 AnimationAction
的各种用法,包括它的属性、方法及其与其他 Three.js 组件的配合使用。并通过多个示例演示如何使用 AnimationAction
来实现不同的动画控制效果。
AnimationAction
是 Three.js 动画系统中的核心组件之一,表示的是动画混合器中的一个动画动作。通过 AnimationAction
对象,可以对 AnimationClip
(动画片段)进行播放、暂停、恢复、停止等操作,同时也可以控制动画的循环方式、速度、权重等。
AnimationAction
的混合。AnimationClip
的一个实例,负责控制动画的播放行为。为了演示 AnimationAction
的使用,首先我们需要创建一个场景,并添加一个可以应用动画的对象。
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);
在控制动画之前,我们需要创建一个 AnimationMixer
,它是用来管理所有动画的对象。每个 AnimationClip
都表示一个动画,而 AnimationAction
则用于控制该动画的行为。
const mixer = new THREE.AnimationMixer(cube);
我们将创建一个简单的动画片段,使立方体沿 Y 轴来回移动:
const positionKF = new THREE.VectorKeyframeTrack(
'.position', // 目标属性
[0, 1, 2], // 关键帧时间点
[0, 0, 0, // 起点位置
0, 2, 0, // 中间位置
0, 0, 0] // 终点位置
);
const clip = new THREE.AnimationClip('move', 2, [positionKF]);
通过 AnimationMixer
和 AnimationClip
创建一个 AnimationAction
,然后可以对动画进行控制。
const action = mixer.clipAction(clip);
action.play();
为了使动画正常播放,需要在渲染循环中更新 AnimationMixer
:
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
mixer.update(delta); // 更新动画
renderer.render(scene, camera);
}
animate();
到这里,我们已经创建了一个基本的动画。立方体会在 Y 轴上来回移动。
AnimationAction
提供了丰富的属性和方法,用于更精细地控制动画行为。以下将详细介绍常用的属性和方法,并通过示例展示如何使用。
play()
play()
方法用于开始或恢复动画的播放。
action.play();
paused
paused
属性控制动画是否暂停。如果将 paused
设置为 true
,动画会停止播放,设置为 false
则恢复播放。
action.paused = true; // 暂停动画
action.paused = false; // 恢复播放
stop()
stop()
方法停止动画播放,并将播放进度重置为初始状态。
action.stop();
reset()
reset()
方法将动画进度重置为初始状态,但不会停止动画。
action.reset();
playbackRate
playbackRate
属性控制动画的播放速度。默认值为 1
,可以通过设置不同的值来加快或减慢动画速度。
action.playbackRate = 2; // 两倍速度播放
action.playbackRate = 0.5; // 半速播放
time
time
属性表示动画的当前时间。通过设置 time
,可以跳到动画的指定时间点。
action.time = 1.5; // 跳到动画的 1.5 秒处
weight
weight
属性控制动画的权重,用于在多个动画混合时调整其影响程度。权重范围为 0
(无影响)到 1
(完全影响)。
action.weight = 0.5; // 混合权重为 50%
loop
loop
属性定义动画的循环方式,Three.js 提供了三种循环模式:
THREE.LoopOnce
:动画播放一次后停止。THREE.LoopRepeat
:动画无限循环。THREE.LoopPingPong
:动画往复循环。action.loop = THREE.LoopPingPong; // 动画来回播放
Three.js 支持同时播放多个动画,并通过调整权重实现动画的平滑过渡。下面的示例展示了如何混合两个动画。
我们再创建一个动画,使立方体沿 X 轴移动:
const positionKF2 = new THREE.VectorKeyframeTrack(
'.position',
[0, 1, 2],
[0, 0, 0, // 起点位置
2, 0, 0, // 中间位置
0, 0, 0] // 终点位置
);
const clip2 = new THREE.AnimationClip('moveX', 2, [positionKF2]);
const action2 = mixer.clipAction(clip2);
我们可以同时播放两个动画,并通过权重控制它们的影响:
action.play();
action2.play();
action.weight = 0.5; // 第一动画的权重
action2.weight = 0.5; // 第二动画的权重
这样,立方体会同时沿 X 轴和 Y 轴移动,产生一个斜向的动画效果。
下面是一个完整的示例,展示了如何在 Three.js 中使用 AnimationAction
控制动画:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js AnimationAction 示例</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script>
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);
const mixer = new THREE.AnimationMixer(cube);
const positionKF = new THREE.VectorKeyframeTrack(
'.position',
[0, 1, 2],
[0, 0, 0, 0, 2, 0, 0, 0, 0]
);
const clip = new THREE.AnimationClip('move', 2, [positionKF]);
const action = mixer.clipAction(clip);
action.play();
const positionKF2 = new THREE.VectorKeyframeTrack(
'.position',
[0, 1, 2],
[0, 0, 0, 2, 0, 0, 0, 0, 0]
);
const clip2 = new THREE.AnimationClip('moveX', 2, [positionKF2]);
const action2 = mixer.clipAction(clip2);
action2.play();
action.weight = 0.5;
action2.weight = 0.5;
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
mixer.update(delta);
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>
同样,不要忘记在窗口调整大小时更新渲染器和摄像机:
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
通过 AnimationAction
,你可以灵活地控制 Three.js 中的动画效果,实现丰富的动画场景。本文详细介绍了 AnimationAction
的基本用法、常用属性和方法,并结合示例演示了如何实现不同的动画效果。希望对你在 Three.js 动画开发中有所帮助!如有问题或建议,欢迎留言讨论。