Animation systems
Quick answer
This tutorial separates keyframe animation driven by AnimationMixer from procedural motion driven by clock deltas. It loads glTF clips with GLTFLoader, plays them through mixer.clipAction, and blends states with crossFadeTo, fadeIn and setEffectiveWeight. It also advances rotation and height per frame using clock.getDelta so playback stays frame-rate independent. The tutorial stresses one shared clock for both systems. Readers can combine imported clips with code-driven movement without drift.
Key points
- Call mixer.update with delta seconds from clock.getDelta, never milliseconds.
- Use crossFadeTo after reset so a finished action does not freeze on its last frame.
- Give every cloned model its own AnimationMixer, because mixers cannot be shared.
Example
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
const mixers = [];
new GLTFLoader().load('/models/turbine.glb', function (gltf) {
const model = gltf.scene;
scene.add(model);
const mixer = new THREE.AnimationMixer(model);
mixers.push(mixer);
gltf.animations.forEach(function (clip) {
const action = mixer.clipAction(clip);
action.setLoop(THREE.LoopRepeat, Infinity);
action.clampWhenFinished = false;
action.play();
});
});
const clock = new THREE.Clock();
renderer.setAnimationLoop(function () {
const dt = clock.getDelta();
mixers.forEach(function (m) { m.update(dt); });
renderer.render(scene, camera);
});const actions = {};
gltf.animations.forEach(function (clip) {
actions[clip.name] = mixer.clipAction(clip);
});
function switchTo(name, duration) {
const next = actions[name];
if (!next) return;
Object.keys(actions).forEach(function (key) {
const action = actions[key];
if (action !== next && action.isRunning()) {
action.crossFadeTo(next, duration || 0.4, false);
}
});
next.reset().setEffectiveWeight(1).fadeIn(duration || 0.4).play();
}
switchTo('rotate', 0.6);
Notes
- Passing a Date.now() difference makes animation run about a thousand times too fast.
- Clips may carry namespace prefixes, so print gltf.animations before using clip names.
English edition written for Atlaslog. Code is taken from the original Chinese page and runs unchanged.
Atlaslog (2026). Animation systems. https://www.jingweizhi.com/en/three/tutorials/animation.html (accessed 2026-11-03).