Once you've brought your animations to life with Three.js, the next logical step is to give your users control over how and when those animations play. This section will explore the fundamental methods for managing animation playback, allowing you to create interactive and dynamic 3D experiences. We'll cover how to start, stop, pause, and even loop your animations, giving you granular control over the user's journey within your 3D scene.
Three.js provides a straightforward API for controlling animation playback through the AnimationMixer object. Remember that the AnimationMixer is responsible for playing back animations associated with a specific Object3D, such as a loaded glTF model. Each Object3D that has animations will typically have its own AnimationMixer.
To begin with, let's recall how you typically get an AnimationMixer and an animation action. You'll usually load a model, find its animations, and then create an action from one of those animations using the mixer.
const mixer = new THREE.AnimationMixer(model);
const clips = model.animations;
const action = mixer.clipAction(clips[0]);Now, let's dive into controlling the playback of these actions.
The most basic control is to start an animation. The play() method on an AnimationAction object begins playback. If the animation is already playing, calling play() again will typically restart it from the beginning. By default, animations will play once and then stop.
action.play();When you want to temporarily halt an animation, the pause() method is your go-to. It freezes the animation at its current frame. When you later call play() again, the animation will resume from where it was paused. This is useful for interactive scenarios where you might want to pause a character's animation while the user performs an action.
action.pause();The stop() method, on the other hand, completely halts the animation and resets its playback time to the beginning (time 0). If you call play() after stop(), the animation will start fresh from the very first frame. Use stop() when you want to completely cease an animation and prepare for it to be potentially restarted from its beginning.
action.stop();Many animations, especially for characters or continuous environmental effects, are intended to repeat. Three.js makes this easy by allowing you to set the loop property of an AnimationAction. The most common setting for looping is THREE.LoopRepeat.
action.loop = THREE.LoopRepeat;There are other loop modes as well: THREE.LoopOnce (the default, plays once and stops) and THREE.LoopPingPong (plays forward, then backward, then forward again, creating a smooth back-and-forth motion). You can combine setting the loop mode with calling play() to have your animation loop indefinitely.
action.loop = THREE.LoopRepeat;
action.play();Beyond basic playback, you can also influence the speed and direction of your animations. The setEffectiveTimeScale() method allows you to speed up or slow down an animation. A value greater than 1 will speed it up, while a value between 0 and 1 will slow it down. A value of 0 will effectively pause the animation, and a negative value will play it in reverse.
// Play at double speed
action.setEffectiveTimeScale(2.0);
// Play at half speed
action.setEffectiveTimeScale(0.5);
// Play in reverse
action.setEffectiveTimeScale(-1.0);You can also directly set the timeScale property, which achieves the same result. However, setEffectiveTimeScale is generally preferred as it accounts for any global time scale that might be applied.
action.timeScale = 2.0; // Equivalent to setEffectiveTimeScale(2.0)To control the direction explicitly without relying on negative time scale, you can set the yAxisIsUp property of the AnimationAction if you're working with specific types of animation data, but setEffectiveTimeScale is the more universal approach.
Imagine you have a character model with an idle animation and a walk animation. You might want buttons to trigger these animations, and perhaps a slider to control the playback speed. Here's a conceptual outline of how you might structure that.
graph TD
A[User Clicks 'Walk' Button] --> B{Get Walk Animation Action}
B --> C[Set Loop to Repeat]
C --> D[Set Time Scale to 1.0]
D --> E[Play Animation]
F[User Clicks 'Idle' Button] --> G{Get Idle Animation Action}
G --> H[Set Loop to Repeat]
H --> I[Set Time Scale to 1.0]
I --> J[Play Animation]
K[User Adjusts Speed Slider] --> L{Get Current Active Action}
L --> M[Set Time Scale based on Slider Value]
M --> N[Update Animation Speed]
This flowchart illustrates a common pattern: user input triggers an event, which then manipulates the animation actions to achieve the desired playback behavior. Remember to update the mixer in your animation loop for any changes to take effect:
const deltaTime = clock.getDelta();
mixer.update(deltaTime);By mastering these playback controls, you can transform static 3D models into dynamic and engaging characters and environments, opening up a world of interactive possibilities for your creators.