AnimationMixer
The AnimationMixer plays and blends reusable AnimationClip instances. A clip groups AnimationTrack objects, and each track updates an application property through an AnimationBinding. AnimationAction controls playback for an individual clip.
All times, durations, and interpolation keyframes use seconds.
Usageโ
import {AnimationClip, AnimationMixer, AnimationTrack} from '@luma.gl/engine';
let translation = [0, 0, 0];
const track = new AnimationTrack({
name: 'node.translation',
times: [0, 1, 2],
values: [
[0, 0, 0],
[1, 0, 0],
[1, 1, 0]
],
binding: {
id: 'node.translation',
getValue: () => translation,
setValue: value => {
translation = value;
}
}
});
const clip = new AnimationClip({name: 'move', tracks: [track]});
const mixer = new AnimationMixer([clip]);
mixer.clipAction('move').setLoop('repeat').play();
mixer.update(0.5);
// translation is [0.5, 0, 0].
For complete playback and deformation examples, see the animation programming guide.
AnimationMixerโ
constructor(clips?: AnimationClip[])โ
Creates a mixer and optionally registers its available clips.
const mixer = new AnimationMixer([walkClip, runClip]);
Propertiesโ
time: numberโ Elapsed mixer time, in seconds.timeScale: numberโ Global playback-speed multiplier. Negative values reverse all advancing actions.
addClip(clip: AnimationClip): thisโ
Registers an additional clip with the mixer.
clipAction(clip: AnimationClip | string, props?: AnimationActionProps): AnimationActionโ
Returns the action for a clip or registered clip name, creating it if necessary. The same action is returned on subsequent calls for that clip; initialization properties only apply when the action is first created.
getAction(name: string): AnimationAction | undefinedโ
Returns an existing action by clip name, without creating a new action.
update(deltaTime: number): thisโ
Advances the mixer by a relative duration in seconds, updates active actions, and writes their blended property values. Pass zero after changing an action's local time when its new pose must be applied immediately.
setTime(time: number): thisโ
Seeks to an absolute mixer time in seconds and immediately applies the resulting values. Paused actions retain their current local times.
stopAllAction(): thisโ
Stops and resets every action currently owned by the mixer.
AnimationActionโ
Create actions through mixer.clipAction(...) so they are registered with the mixer.
AnimationActionPropsโ
type AnimationActionProps = {
loop?: 'once' | 'repeat' | 'ping-pong';
repetitions?: number;
timeScale?: number;
weight?: number;
};
loopโ Playback mode; defaults to'repeat'.repetitionsโ Number of allowed traversals; defaults toInfinity.timeScaleโ Action-specific playback-speed multiplier; defaults to1.weightโ Relative contribution while blending; defaults to1.
Propertiesโ
clip: AnimationClipโ The action's source clip.mixer: AnimationMixerโ The owning mixer.time: numberโ Local clip time in seconds.timeScale: numberโ Local playback-speed multiplier.weight: numberโ Current blending weight.loop: AnimationLoopModeโ Current playback mode.repetitions: numberโ Maximum traversals for the current loop mode.paused: booleanโ Whether local playback time is frozen.playing: booleanโ Whether the action is actively playing.
Playback Methodsโ
play(): thisโ Starts or resumes playback.pause(): thisโ Freezes local playback time while preserving the current pose.resume(): thisโ Continues a paused action.stop(): thisโ Stops playback and resets local time.reset(): thisโ Resets local time and completed-loop state.setTime(time: number): thisโ Sets local clip time in seconds. Callmixer.update(0)to immediately apply the changed pose.setLoop(loop: AnimationLoopMode, repetitions?: number): thisโ Selects'once','repeat', or'ping-pong'; repetitions default toInfinity.setEffectiveTimeScale(timeScale: number): thisโ Changes action playback speed. Negative values play in reverse.setEffectiveWeight(weight: number): thisโ Changes blending weight; values are clamped to zero or greater.
Fading Methodsโ
fadeIn(duration: number): thisโ Fades the action toward full weight over the specified duration in seconds.fadeOut(duration: number): thisโ Fades the action toward zero weight over the specified duration in seconds.crossFadeTo(action: AnimationAction, duration: number): thisโ Starts the destination action at zero weight and crossfades between both actions.crossFadeFrom(action: AnimationAction, duration: number): thisโ Crossfades from the specified action into this action.
const walkAction = mixer.clipAction('walk').play();
const runAction = mixer.clipAction('run');
walkAction.crossFadeTo(runAction, 0.4);
When multiple actions update the same binding, their values are combined using their current weights. If the combined weight is below one, the original value from binding.getValue supplies the remaining contribution.
AnimationClipโ
An AnimationClip groups tracks intended to play together.
const clip = new AnimationClip({
name: 'walk',
tracks: [translationTrack, rotationTrack],
duration: 2
});
AnimationClipPropsโ
name: stringโ Name used to retrieve the clip or action.tracks: AnimationTrack[]โ Tracks evaluated together.duration?: numberโ Explicit duration in seconds. If omitted, the duration is the longest track duration.
Propertiesโ
name: stringโ Clip name.tracks: AnimationTrack[]โ Source tracks.duration: numberโ Playback duration in seconds.
AnimationTrackโ
An AnimationTrack samples one property and sends each result to an AnimationBinding.
AnimationTrackPropsโ
type AnimationTrackProps = {
name?: string;
times: readonly number[];
values: readonly (readonly number[])[];
interpolation?: 'STEP' | 'LINEAR' | 'CUBICSPLINE';
valueType?: 'vector' | 'quaternion';
binding: AnimationBinding;
};
timesโ Increasing keyframe times in seconds.valuesโ Numeric arrays associated with each keyframe. Scalars use one-element arrays.interpolationโ Interpolation mode; defaults to'LINEAR'.valueTypeโ'vector'by default. Set'quaternion'for shortest-path spherical interpolation and normalized quaternion results.bindingโ Property accessor updated when the track is evaluated.
For 'CUBICSPLINE', values contains three arrays per keyframe in [inTangent, value, outTangent] order.
Propertiesโ
name: stringโ Track name.times: readonly number[]โ Keyframe times in seconds.values: readonly (readonly number[])[]โ Keyframe values.interpolation: AnimationInterpolationโ Interpolation mode.valueType: AnimationValueTypeโ'vector'or'quaternion'.binding: AnimationBindingโ Bound property.duration: numberโ Final keyframe time, or zero for an empty track.sampler: AnimationSamplerโ Sampler view over the track's keyframes.
evaluate(time: number): number[] | nullโ
Samples the track at the specified time in seconds. Times outside its range clamp to the nearest endpoint. Track evaluation does not perform looping; looping is determined by the action.
AnimationBindingโ
type AnimationBinding = {
id?: string;
getValue?: () => readonly number[];
setValue: (value: number[]) => void;
};
idโ Stable property identifier. Use the same identifier when separately constructed bindings represent the same property.getValueโ Returns the initial property value used when action weights do not sum to one.setValueโ Applies the final blended property value.
Without an explicit id, the binding object identity determines whether tracks target the same property.
evaluateAnimationSamplerโ
The lower-level sampler can also be evaluated independently:
import {evaluateAnimationSampler} from '@luma.gl/engine';
const value = evaluateAnimationSampler(0.5, {
input: [0, 1],
output: [[0], [10]],
interpolation: 'LINEAR'
});
// value is [5].
evaluateAnimationSampler(time, sampler, valueType?): number[] | nullโ
time: numberโ Sample time in seconds.sampler.input: readonly number[]โ Keyframe times.sampler.output: readonly (readonly number[])[]โ Keyframe value arrays.sampler.interpolation?: AnimationInterpolationโ'STEP','LINEAR', or'CUBICSPLINE'.valueType?: AnimationValueTypeโ'vector'by default, or'quaternion'.
Returns the sampled numeric array, or null when the sampler does not contain usable keyframes. Quaternion linear interpolation uses spherical interpolation; cubic quaternion results are normalized.