Control Three.js Animation Speed Globally

This article explains how to control the playback speed of all animations globally in Three.js using the AnimationMixer class. You will learn how to use the timeScale property to speed up, slow down, pause, or reverse multiple animations simultaneously with a single line of code.

In Three.js, the AnimationMixer is the player for animations on specific objects. Instead of adjusting the speed of each individual animation clip or action, you can control the playback speed of every animation managed by a mixer globally using its timeScale property.

The timeScale Property

The timeScale property is a scaling factor for the mixer’s internal clock. The default value is 1.0, which plays animations at their normal, intended speed.

To change the global speed, modify this property directly on your AnimationMixer instance:

// Create the mixer
const mixer = new THREE.AnimationMixer(mesh);

// Play all animations at double speed
mixer.timeScale = 2.0;

// Play all animations in slow motion (half speed)
mixer.timeScale = 0.5;

// Pause all animations
mixer.timeScale = 0.0;

// Play all animations in reverse at normal speed
mixer.timeScale = -1.0;

Implementation Example

To see how this fits into a standard Three.js application, look at the render loop integration below:

import * as THREE from 'three';

// Setup scene, camera, renderer, and clock
const clock = new THREE.Clock();
const mixer = new THREE.AnimationMixer(characterMesh);

// Load and play an animation action
const action = mixer.clipAction(animationClip);
action.play();

// Globally slow down all animations managed by this mixer to half-speed
mixer.timeScale = 0.5;

// Animation loop
function animate() {
    requestAnimationFrame(animate);

    // Get the time elapsed since the last frame
    const delta = clock.getDelta();

    // Update the mixer. The timeScale automatically scales this delta value.
    mixer.update(delta);

    renderer.render(scene, camera);
}

animate();

By updating mixer.timeScale, the delta time passed to mixer.update(delta) is multiplied by your scale factor. This ensures smooth, hardware-independent playback speed adjustments across all active animation clips at once.