Three.js provides a comprehensive animation system that uses keyframes to define how properties of objects change over time. This system allows for animating various aspects of an object, including position, scale, rotation, material properties (like color or opacity), bones of a skinned mesh, and morph targets.
KeyframeTrack: A KeyframeTrack is a timed sequence of keyframes that animates a specific property of an object. Three.js offers various subclasses for different data types (e.g., VectorKeyframeTrack for positions, QuaternionKeyframeTrack for rotations).AnimationClip: An AnimationClip is a reusable collection of one or more KeyframeTracks. It represents a complete animation sequence (e.g., a "walk" animation).AnimationMixer: The AnimationMixer is responsible for playing animations on a specific object in the scene. You typically create one AnimationMixer per animated object.AnimationAction: An AnimationAction schedules and controls the performance of an AnimationClip on an AnimationMixer. It provides controls for playing, pausing, looping, and adjusting the speed of an animation.KeyframeTracks by specifying time and value arrays for the properties you want to animate.AnimationClip: Combine one or more KeyframeTracks into an AnimationClip.AnimationMixer: Create an AnimationMixer instance, associating it with the object you want to animate.AnimationAction: Get an AnimationAction from the AnimationMixer using your AnimationClip.AnimationAction to play, pause, loop, or blend the animation.requestAnimationFrame), update the AnimationMixer with the elapsed time (deltaTime) to advance the animation.This example demonstrates a basic keyframe animation where a cube moves along the X-axis. Note that this requires a Three.js setup.
import * as THREE from 'three';
// Scene, Camera, Renderer setup (assuming these are already defined)
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Create a cube
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);
camera.position.z = 5;
// 1. Create a KeyframeTrack for position
const times = [0, 2, 4]; // Keyframe times in seconds
const values = [
0, 0, 0, // Position at time 0 (x, y, z)
2, 0, 0, // Position at time 2
0, 0, 0 // Position at time 4
];
const positionTrack = new THREE.VectorKeyframeTrack('cube.position', times, values);
// 2. Create an AnimationClip
const duration = 4; // Total duration of the animation
const clip = new THREE.AnimationClip('CubeMovement', duration, [positionTrack]);
// 3. Create an AnimationMixer
const mixer = new THREE.AnimationMixer(cube);
// 4. Create an AnimationAction
const action = mixer.clipAction(clip);
// 5. Play the animation
action.play();
const clock = new THREE.Clock();
// Animation loop
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
mixer.update(delta); // Update the mixer with elapsed time
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});