Documentation
    Preparing search index...

    Class AnimationMixer

    Plays an AnimationClip onto one target object (§17, §107).

    elapsed  0 ─────── d ─────── 2d ─────── 3d     (loop: 3, monotonic)
    clip     0 ─── d   0 ─── d   0 ─── d           (what tracks are sampled at)
    

    AnimationMixer.localTime is the clip-local position inside the current iteration and is what every track sees; AnimationMixer.elapsedTime is total played time and is what event bookkeeping runs in, because it only moves forward during forward playback. Looping then needs no special case: an event at clip time m occurs at m, m + d, m + 2d, … and the half-open crossing rule fires each of those exactly once.

    A mixer plays a single clip. Cross-fading, layering, and additive blending are §18/§19 material and are staged out of Phase 4 (plan P4-3); animating one target from two clips today means two mixers, and the shared §16 conflict registry then resolves any property they both write last-started-wins, with a warning.

    Index
    • get duration(): number

      Length of one iteration in seconds: the clip's own duration (§17), frozen at play. 0 while nothing is armed.

      Returns number

    • get elapsedTime(): number

      Total played time in seconds, across loop iterations.

      Returns number

    • get iteration(): number

      Zero-based index of the loop iteration currently playing.

      Returns number

    • get localTime(): number

      Clip-local position inside the current iteration, in seconds (§9).

      Returns number

    • get totalDuration(): number

      duration × loop — the elapsed time at which playback finishes. Infinity for loop(Infinity), and 0 for a zero-length clip (where 0 × Infinity would otherwise be NaN).

      Returns number

    • Advances playback by deltaSeconds × speed and writes the resulting pose. Called by the fixed-step AnimationSystem (plan P4-1) with the simulation's fixed delta; a mixer never advances itself and never reads a clock (§33).

      Clip events in the crossed range fire in time order, once each — including one exactly at the end of the range and excluding one exactly at its start, so consecutive advances neither miss an event nor repeat one. A delta that spans an iteration boundary fires the rest of that iteration's events, re-arms them, and continues into the next.

      A no-op unless the mixer is "running" and unfinished. The advance that reaches AnimationMixer.totalDuration clamps to it, writes the final pose, and releases the property claims (a finished mixer can still be scrubbed, exactly as a finished tween can).

      Parameters

      • deltaSeconds: number

      Returns this

      FourError INVALID_APPLICATION_STATE — the delta is negative or non-finite.

    • Sets the number of total iterations: loop(1) is the default single pass, loop(3) plays the clip three times, loop(Infinity) never ends. Clip events re-arm on every wrap, so a marker on a loop(3) playback fires three times.

      Legal mid-playback, like AnimationMixer.speed: it only changes AnimationMixer.totalDuration, which the next advance reads.

      Parameters

      • count: number

      Returns this

      FourError INVALID_APPLICATION_STATE — not an integer >= 1 or Infinity.

    • Resolves every track's binding, claims the properties (§16), and starts playback at clip time 0 — writing the pose for time 0 immediately, so the clip's first keyframes are visible without waiting for an advance.

      play(clip, options) is prepare(clip, options).play(). Calling it with no clip plays whatever AnimationMixer.prepare armed, which is the form Timeline uses.

      A no-op on a mixer that is not "idle" — replaying would have to re-resolve bindings that §16 says are resolved once. Build a new mixer, or seek(0).

      No event fires here, not even one at clip time 0: the cursor starts below zero and the first advance (even advance(0)) crosses it.

      Parameters

      Returns this

      FourError INVALID_APPLICATION_STATE — no clip was given or armed; options were passed without a clip; or a track's path resolves to a property whose type its adapter cannot write (see the module header).

      FourError from createBinding — a track path does not resolve.

    • Arms the mixer with a clip and its per-playback options without starting it, so something else can own its playback — a Timeline, which requires an "idle" child and calls play() itself, or a caller that wants to seek a pose before running.

      The same relationship tween(...) has to animate(...).play(): nothing is bound, captured, or claimed here.

      Parameters

      Returns this

      FourError INVALID_APPLICATION_STATE — the mixer has already been played, or an option is out of range.

    • Positions playback at timeSeconds of elapsed time and writes the pose for it — §16's scrubbing, and the positioning half of a snapshot restore (§34).

      Pure: seeking twice to the same time writes identical values, and seeking backwards is as valid as forwards. Neither AnimationMixer.state nor AnimationMixer.finished changes, so a seek is an evaluation and never a playback decision.

      The time is clamped to [0, totalDuration] — elapsed time, spanning every loop iteration, not one iteration's clip time. It therefore differs from Timeline.seek, which clamps to a single iteration: a mixer is placed on a timeline by its total duration, so a looping mixer driven by a timeline has to be addressable across its loops, and scrubbing a three-loop clip through all three loops is meaningful in a way that scrubbing a timeline "into iteration 2" is not. With the default loop(1) the two conventions coincide.

      Events are suppressed unless the playback opted in with { replayOnSeek: true }, in which case a forward seek fires the events it crosses (§16). A backward seek fires nothing and re-arms the events it rewound past, so replaying forwards crosses them again — which is exactly what "restoring a mid-clip snapshot positions playback without re-firing markers already crossed" needs.

      Root motion (§19, P7-5) is repositioned and not applied: a seek moves the clip clock, never the character (see MixerRootMotionOptions).

      Parameters

      • timeSeconds: number

      Returns this

      FourError INVALID_APPLICATION_STATE — the mixer has never been played, or the time is negative or non-finite.

    • Sets the playback speed multiplier — legal at any time, including mid-playback, because §107 lists it as a playback control.

      Must be positive and finite. Reverse playback is deliberately not speed(-1): §16 gives reversing to Timeline, and a negative multiplier here would make "the advance that finishes playback" ambiguous and event crossing (a forward notion) meaningless. Scrub backwards with AnimationMixer.seek.

      Parameters

      • multiplier: number

      Returns this

      FourError INVALID_APPLICATION_STATE — not finite and > 0.

    • Stops playback and releases every §16 property claim, leaving all animated values exactly where the last write put them.

      A stopped mixer never writes again — even a later AnimationMixer.seek is inert — and the properties it held are free for another writer to claim without a conflict warning. A no-op on an "idle" mixer, which holds nothing.

      Returns this