JavaScript 3D library providing WebGL and WebGPU renderers for creating interactive 3D graphics in web browsers
—
Three.js provides a comprehensive keyframe-based animation system for animating object properties over time. The animation system supports timeline control, blending, and complex animation sequencing with multiple tracks and interpolation modes.
Central animation control system that manages animation playback for objects and their hierarchies.
/**
* Animation mixer for controlling multiple animation clips on objects
*/
class AnimationMixer extends EventDispatcher {
/**
* Create animation mixer for specified root object
* @param root - Root object that will be animated
*/
constructor(root: Object3D);
/** Root object being animated */
root: Object3D;
/** Current time in seconds */
time: number;
/** Time scale multiplier for all animations */
timeScale: number;
/**
* Create action for animation clip
* @param clip - Animation clip to create action for
* @param optionalRoot - Optional specific root for this action
* @returns Animation action ready for playback control
*/
clipAction(clip: AnimationClip, optionalRoot?: Object3D): AnimationAction;
/**
* Create action for animation clip by name
* @param name - Name of animation clip to find
* @param optionalRoot - Optional specific root for this action
* @returns Animation action or null if not found
*/
clipActionByName(name: string, optionalRoot?: Object3D): AnimationAction | null;
/**
* Get existing action for animation clip
* @param clip - Animation clip to find action for
* @param optionalRoot - Optional specific root for this action
* @returns Existing animation action or null
*/
existingAction(clip: AnimationClip, optionalRoot?: Object3D): AnimationAction | null;
/**
* Stop all currently active actions
* @returns This mixer for chaining
*/
stopAllAction(): AnimationMixer;
/**
* Update animations by specified time delta
* @param deltaTimeInSeconds - Time elapsed since last update in seconds
* @returns This mixer for chaining
*/
update(deltaTimeInSeconds: number): AnimationMixer;
/**
* Set time for all actions directly
* @param timeInSeconds - Time to set in seconds
* @returns This mixer for chaining
*/
setTime(timeInSeconds: number): AnimationMixer;
/**
* Get list of all actions on root or descendant objects
* @returns Array of all animation actions
*/
getRoot(): Object3D;
/**
* Deallocate all memory used by this mixer
*/
uncacheClip(clip: AnimationClip): void;
/**
* Deallocate memory used for root object
*/
uncacheRoot(root: Object3D): void;
/**
* Deallocate memory used for action
*/
uncacheAction(clip: AnimationClip, optionalRoot?: Object3D): void;
}Usage Example:
import { AnimationMixer, Clock } from 'three';
// Create mixer for loaded model
const mixer = new AnimationMixer(gltfScene);
// Create actions for loaded animations
const walkAction = mixer.clipAction(walkClip);
const runAction = mixer.clipAction(runClip);
// Configure and play animations
walkAction.play();
runAction.setWeight(0); // Start with walk only
// Animation loop
const clock = new Clock();
function animate() {
const deltaTime = clock.getDelta();
mixer.update(deltaTime);
requestAnimationFrame(animate);
renderer.render(scene, camera);
}Container for animation data defining property changes over time using keyframe tracks.
/**
* Container for keyframe track data representing an animation sequence
*/
class AnimationClip {
/**
* Create animation clip from keyframe tracks
* @param name - Name identifier for this clip
* @param duration - Length of animation in seconds (-1 for auto-calculate)
* @param tracks - Array of keyframe tracks defining property animations
* @param blendMode - How this clip blends with others
*/
constructor(name?: string, duration?: number, tracks?: KeyframeTrack[], blendMode?: AnimationBlendMode);
/** Unique name for this animation clip */
name: string;
/** Duration of animation in seconds */
duration: number;
/** Array of keyframe tracks defining property animations */
tracks: KeyframeTrack[];
/** Blend mode for combining with other animations */
blendMode: AnimationBlendMode;
/**
* Create copy of this animation clip
* @returns New animation clip with copied data
*/
clone(): AnimationClip;
/**
* Optimize clip by removing unnecessary keyframes
* @returns This clip for chaining
*/
optimize(): AnimationClip;
/**
* Reset duration based on track lengths
* @returns This clip for chaining
*/
resetDuration(): AnimationClip;
/**
* Trim clip to specified time range
* @param startTime - Start time in seconds
* @param endTime - End time in seconds
* @returns This clip for chaining
*/
trim(): AnimationClip;
/**
* Validate all tracks in this clip
* @returns True if valid
*/
validate(): boolean;
}
// Animation blend modes
type AnimationBlendMode =
| typeof NormalAnimationBlendMode // 2500 - Replace existing values
| typeof AdditiveAnimationBlendMode; // 2501 - Add to existing valuesUsage Example:
import { AnimationClip, VectorKeyframeTrack, NumberKeyframeTrack } from 'three';
// Create keyframe tracks
const positionTrack = new VectorKeyframeTrack(
'.position', // Property path
[0, 1, 2], // Times
[0, 0, 0, 10, 0, 0, 0, 0, 0] // Values (x,y,z for each time)
);
const opacityTrack = new NumberKeyframeTrack(
'.material.opacity', // Property path
[0, 1, 2], // Times
[1, 0.5, 1] // Values
);
// Create animation clip
const fadeAndMove = new AnimationClip('fadeAndMove', 2, [
positionTrack,
opacityTrack
]);Playback control interface for animation clips with timing, weights, and state management.
/**
* Controls playback of an animation clip with timing and blending options
*/
class AnimationAction {
/** Animation clip being controlled */
clip: AnimationClip;
/** Animation mixer managing this action */
mixer: AnimationMixer;
/** Current playback time in seconds */
time: number;
/** Playback speed multiplier */
timeScale: number;
/** Influence weight for blending (0-1) */
weight: number;
/** Number of repetitions (Infinity for endless) */
repetitions: number;
/** Whether action is currently paused */
paused: boolean;
/** Whether action is currently enabled */
enabled: boolean;
/** Whether to clamp when animation reaches end */
clampWhenFinished: boolean;
/** Whether to automatically start when mixed */
zeroSlopeAtStart: boolean;
/** Whether to smoothly end interpolation */
zeroSlopeAtEnd: boolean;
/** Loop mode for animation playback */
loop: AnimationActionLoopStyles;
/**
* Start or resume playback
* @returns This action for chaining
*/
play(): AnimationAction;
/**
* Stop playback and reset to beginning
* @returns This action for chaining
*/
stop(): AnimationAction;
/**
* Pause playback at current time
* @returns This action for chaining
*/
pause(): AnimationAction;
/**
* Pause all other actions and play this one
* @returns This action for chaining
*/
stopFading(): AnimationAction;
/**
* Reset action to initial state
* @returns This action for chaining
*/
reset(): AnimationAction;
/**
* Check if action is currently running
* @returns True if action is playing
*/
isRunning(): boolean;
/**
* Check if action is scheduled to start
* @returns True if action is scheduled
*/
isScheduled(): boolean;
/**
* Set effective weight with fade in/out
* @param weight - Target weight (0-1)
* @param duration - Fade duration in seconds
* @returns This action for chaining
*/
fadeIn(duration: number): AnimationAction;
/**
* Fade out action weight to zero
* @param duration - Fade duration in seconds
* @returns This action for chaining
*/
fadeOut(duration: number): AnimationAction;
/**
* Cross-fade to another action
* @param fadeOutAction - Action to fade out
* @param duration - Cross-fade duration in seconds
* @param warp - Whether to synchronize durations
* @returns This action for chaining
*/
crossFadeFrom(fadeOutAction: AnimationAction, duration: number, warp?: boolean): AnimationAction;
/**
* Cross-fade from this action to another
* @param fadeInAction - Action to fade in
* @param duration - Cross-fade duration in seconds
* @param warp - Whether to synchronize durations
* @returns This action for chaining
*/
crossFadeTo(fadeInAction: AnimationAction, duration: number, warp?: boolean): AnimationAction;
/**
* Gradually change playback speed
* @param timeScale - Target time scale
* @param duration - Warp duration in seconds
* @returns This action for chaining
*/
warp(startTimeScale: number, endTimeScale: number, duration: number): AnimationAction;
/**
* Set loop mode and repetition count
* @param mode - Loop style constant
* @param repetitions - Number of loops (Infinity for endless)
* @returns This action for chaining
*/
setLoop(mode: AnimationActionLoopStyles, repetitions: number): AnimationAction;
/**
* Set effective weight immediately
* @param weight - Weight value (0-1)
* @returns This action for chaining
*/
setEffectiveWeight(weight: number): AnimationAction;
/**
* Get current effective weight
* @returns Current effective weight
*/
getEffectiveWeight(): number;
/**
* Set effective time scale immediately
* @param timeScale - Time scale multiplier
* @returns This action for chaining
*/
setEffectiveTimeScale(timeScale: number): AnimationAction;
/**
* Get current effective time scale
* @returns Current effective time scale
*/
getEffectiveTimeScale(): number;
/**
* Get total duration accounting for time scale and repetitions
* @returns Total duration in seconds
*/
getClip(): AnimationClip;
/**
* Get animation mixer controlling this action
* @returns Animation mixer instance
*/
getMixer(): AnimationMixer;
/**
* Get root object being animated
* @returns Root object
*/
getRoot(): Object3D;
}
// Loop style constants
type AnimationActionLoopStyles =
| typeof LoopOnce // 2200 - Play once and stop
| typeof LoopRepeat // 2201 - Repeat from beginning
| typeof LoopPingPong; // 2202 - Reverse direction each loopBase classes for defining property animations over time with various interpolation modes.
/**
* Base class for keyframe-based property animation tracks
*/
abstract class KeyframeTrack {
/**
* Create keyframe track for animating property
* @param name - Property path (e.g. '.position.x', '.rotation')
* @param times - Array of time values in seconds
* @param values - Array of property values at each time
* @param interpolation - Interpolation mode between keyframes
*/
constructor(name: string, times: ArrayLike<number>, values: ArrayLike<any>, interpolation?: InterpolationModes);
/** Property path being animated */
name: string;
/** Time values for keyframes */
times: Float32Array;
/** Property values at each keyframe */
values: Float32Array;
/** Type name for this track */
ValueTypeName: string;
/** Time interpolation mode */
interpolation: InterpolationModes;
/**
* Get interpolated value at specified time
* @param time - Time in seconds
* @returns Interpolated value
*/
evaluate(time: number): any;
/**
* Create copy of this track
* @returns New keyframe track with copied data
*/
clone(): this;
/**
* Scale all time values
* @param timeScale - Scale factor for times
* @returns This track for chaining
*/
scale(timeScale: number): this;
/**
* Trim track to specified time range
* @param startTime - Start time in seconds
* @param endTime - End time in seconds
* @returns This track for chaining
*/
trim(startTime: number, endTime: number): this;
/**
* Shift all keyframe times by offset
* @param timeOffset - Time offset in seconds
* @returns This track for chaining
*/
shift(timeOffset: number): this;
/**
* Optimize track by removing redundant keyframes
* @returns This track for chaining
*/
optimize(): this;
/**
* Validate track data consistency
* @returns True if track is valid
*/
validate(): boolean;
}
/**
* Keyframe track for animating Vector3 properties
*/
class VectorKeyframeTrack extends KeyframeTrack {
/**
* Create vector keyframe track
* @param name - Property path (e.g. '.position', '.scale')
* @param times - Array of time values
* @param values - Array of vector values [x,y,z,x,y,z,...]
* @param interpolation - Interpolation mode
*/
constructor(name: string, times: ArrayLike<number>, values: ArrayLike<number>, interpolation?: InterpolationModes);
}
/**
* Keyframe track for animating number properties
*/
class NumberKeyframeTrack extends KeyframeTrack {
/**
* Create number keyframe track
* @param name - Property path (e.g. '.opacity', '.intensity')
* @param times - Array of time values
* @param values - Array of number values
* @param interpolation - Interpolation mode
*/
constructor(name: string, times: ArrayLike<number>, values: ArrayLike<number>, interpolation?: InterpolationModes);
}
/**
* Keyframe track for animating Quaternion rotations
*/
class QuaternionKeyframeTrack extends KeyframeTrack {
/**
* Create quaternion keyframe track
* @param name - Property path (e.g. '.quaternion')
* @param times - Array of time values
* @param values - Array of quaternion values [x,y,z,w,x,y,z,w,...]
* @param interpolation - Interpolation mode
*/
constructor(name: string, times: ArrayLike<number>, values: ArrayLike<number>, interpolation?: InterpolationModes);
}
/**
* Keyframe track for animating Color properties
*/
class ColorKeyframeTrack extends KeyframeTrack {
/**
* Create color keyframe track
* @param name - Property path (e.g. '.color', '.emissive')
* @param times - Array of time values
* @param values - Array of color values [r,g,b,r,g,b,...]
* @param interpolation - Interpolation mode
*/
constructor(name: string, times: ArrayLike<number>, values: ArrayLike<number>, interpolation?: InterpolationModes);
}
/**
* Keyframe track for animating string/discrete properties
*/
class StringKeyframeTrack extends KeyframeTrack {
/**
* Create string keyframe track for discrete values
* @param name - Property path
* @param times - Array of time values
* @param values - Array of string values
*/
constructor(name: string, times: ArrayLike<number>, values: ArrayLike<string>);
}
/**
* Keyframe track for animating boolean properties
*/
class BooleanKeyframeTrack extends KeyframeTrack {
/**
* Create boolean keyframe track
* @param name - Property path
* @param times - Array of time values
* @param values - Array of boolean values
*/
constructor(name: string, times: ArrayLike<number>, values: ArrayLike<boolean>);
}
// Interpolation modes
type InterpolationModes =
| typeof InterpolateDiscrete // Step interpolation
| typeof InterpolateLinear // Linear interpolation
| typeof InterpolateSmooth; // Smooth/cubic interpolationUtility functions for creating, modifying, and managing animation data.
/**
* Utility functions for animation system
*/
class AnimationUtils {
/**
* Convert track array to hierarchy of clips
* @param tracks - Array of keyframe tracks
* @returns Array of animation clips
*/
static arraySlice(array: any[], from: number, to: number): any[];
/**
* Create clip from morph target animation
* @param name - Animation name
* @param morphTargetNames - Names of morph targets
* @param fps - Frames per second
* @returns Animation clip for morph targets
*/
static makeSameType(source: KeyframeTrack, times: ArrayLike<number>, values: ArrayLike<any>): KeyframeTrack;
/**
* Get keyframe track constructor by name
* @param typeName - Track type name
* @returns Track constructor function
*/
static getKeyframeOrder(times: ArrayLike<number>): number[];
/**
* Sort keyframes by time and remove duplicates
* @param track - Keyframe track to sort
* @returns Sorted track
*/
static sortedArray(values: any[], stride: number, order: number[]): any[];
/**
* Create animation clip from object hierarchy
* @param root - Root object to extract animation from
* @param name - Name for created clip
* @param fps - Target framerate
* @returns Animation clip extracted from object
*/
static flattenJSON(jsonKeys: string[], times: number[], values: any[], valuePropertyName: string): KeyframeTrack[];
/**
* Utility to sub-sample keyframe track
* @param track - Source track
* @param newTimes - New time values
* @returns Sub-sampled track
*/
static subclip(sourceClip: AnimationClip, name: string, startFrame: number, endFrame: number, fps?: number): AnimationClip;
}System for managing animations across multiple objects sharing similar structure.
/**
* Group of objects that can share animation data and playback timing
*/
class AnimationObjectGroup {
/**
* Create animation object group
* @param objects - Objects to group together
*/
constructor(...objects: Object3D[]);
/** UUID for this group */
uuid: string;
/** Statistics about group usage */
stats: {
bindingsPerObject: number;
objects: {
total: number;
inUse: number;
};
};
/**
* Add objects to this group
* @param objects - Objects to add
*/
add(...objects: Object3D[]): void;
/**
* Remove objects from group
* @param objects - Objects to remove
*/
remove(...objects: Object3D[]): void;
/**
* Remove all objects from group
*/
uncache(...objects: Object3D[]): void;
}Low-level animation system components for binding tracks to object properties and mixing multiple values.
/**
* Binds animation tracks to object properties using property paths
*/
class PropertyBinding {
/**
* Create property binding for animation track
* @param rootNode - Root object containing the property
* @param path - Property path (e.g., '.position', '.rotation.x', '.material.opacity')
* @param parsedPath - Pre-parsed property path (internal use)
*/
constructor(rootNode: Object3D, path: string, parsedPath?: any);
/** Root object containing the property */
rootNode: Object3D;
/** Property path string */
path: string;
/** Parsed property path components */
parsedPath: any;
/** Target object containing the property */
node: any;
/** Final property being animated */
nodeProperty: any;
/**
* Get current property value
* @param targetArray - Array to store result in
*/
getValue(targetArray: ArrayLike<number>): void;
/**
* Set property value from array
* @param sourceArray - Array containing new values
*/
setValue(sourceArray: ArrayLike<number>): void;
/**
* Bind property for animation
*/
bind(): void;
/**
* Unbind property
*/
unbind(): void;
/**
* Create property binding from animation track
* @param root - Root object
* @param track - Keyframe track to bind
* @returns Property binding instance
*/
static create(root: Object3D, track: KeyframeTrack): PropertyBinding;
/**
* Parse property path into components
* @param path - Property path string
* @returns Parsed path object
*/
static parseTrackName(path: string): any;
/**
* Find property node in object hierarchy
* @param root - Root object to search from
* @param nodeName - Name of node to find
* @returns Found object or null
*/
static findNode(root: Object3D, nodeName: string): Object3D | null;
}
/**
* Mixes multiple property values for animation blending
*/
class PropertyMixer {
/**
* Create property mixer for blending multiple values
* @param binding - Property binding to mix values for
* @param typeName - Type name for the property values
* @param valueSize - Number of components per value
*/
constructor(binding: PropertyBinding, typeName: string, valueSize: number);
/** Property binding being mixed */
binding: PropertyBinding;
/** Type name for values */
typeName: string;
/** Number of components per value */
valueSize: number;
/** Buffer for accumulating mixed values */
buffer: ArrayLike<number>;
/** Current cumulative weight */
cumulativeWeight: number;
/** Whether cumulative weight was used */
cumulativeWeightAdditive: number;
/** Whether binding has been applied */
useCount: number;
/** Reference count for this mixer */
referenceCount: number;
/**
* Accumulate weighted value into buffer
* @param accuIndex - Index in accumulator
* @param weight - Blend weight
* @param values - Source values array
* @param valueOffset - Offset in values array
*/
accumulate(accuIndex: number, weight: number, values: ArrayLike<number>, valueOffset: number): void;
/**
* Accumulate additive value into buffer
* @param accuIndex - Index in accumulator
* @param weight - Blend weight
* @param values - Source values array
* @param valueOffset - Offset in values array
*/
accumulateAdditive(accuIndex: number, weight: number, values: ArrayLike<number>, valueOffset: number): void;
/**
* Apply accumulated values to property
* @param accuIndex - Index in accumulator
*/
apply(accuIndex: number): void;
/**
* Save current property state
* @param accuIndex - Index to save at
*/
saveOriginalState(accuIndex: number): void;
/**
* Restore saved property state
* @param accuIndex - Index to restore from
*/
restoreOriginalState(accuIndex: number): void;
}// Animation-specific type definitions
type AnimationBlendMode = number;
type AnimationActionLoopStyles = number;
type InterpolationModes = number;
// Loop constants
declare const LoopOnce: 2200;
declare const LoopRepeat: 2201;
declare const LoopPingPong: 2202;
// Blend mode constants
declare const NormalAnimationBlendMode: 2500;
declare const AdditiveAnimationBlendMode: 2501;
// Interpolation constants
declare const InterpolateDiscrete: 2300;
declare const InterpolateLinear: 2301;
declare const InterpolateSmooth: 2302;Complex Animation Setup:
import * as THREE from 'three';
// Create mixer for character
const mixer = new THREE.AnimationMixer(character);
// Load multiple animation clips
const idleClip = character.animations.find(clip => clip.name === 'idle');
const walkClip = character.animations.find(clip => clip.name === 'walk');
const runClip = character.animations.find(clip => clip.name === 'run');
// Create actions
const idleAction = mixer.clipAction(idleClip);
const walkAction = mixer.clipAction(walkClip);
const runAction = mixer.clipAction(runClip);
// Configure actions
idleAction.play();
walkAction.setWeight(0).play();
runAction.setWeight(0).play();
// Animation state management
let currentAction = idleAction;
function transitionTo(newAction, duration = 0.5) {
if (currentAction !== newAction) {
currentAction.fadeOut(duration);
newAction.reset().fadeIn(duration).play();
currentAction = newAction;
}
}
// Update loop
const clock = new THREE.Clock();
function animate() {
const deltaTime = clock.getDelta();
mixer.update(deltaTime);
requestAnimationFrame(animate);
renderer.render(scene, camera);
}Install with Tessl CLI
npx tessl i tessl/npm-three