Documentation
    Preparing search index...

    Class AnimationClip

    §17's animation clip: named, timed, tracks plus events.

    const clip = new AnimationClip({
    name: "wave",
    tracks: [rotationTrack, colorTrack],
    events: [{ time: 0.5, name: "footstep" }],
    });
    Index
    duration: number

    Clip length in seconds (§17, §7a). Metadata, not a limit: tracks clamp to their own key range and a player decides what happens past the end.

    events: readonly AnimationEvent[]

    The clip's events (§17), sorted by time.

    The constructor sorts a copy when the input is out of order and leaves an already-sorted input in its given order. The sort is stable, so events sharing a time keep their construction order and fire in it — a deterministic tie-break (§33) rather than whatever the engine's sort happened to do.

    name: string

    Clip name (§17).

    tracks: readonly AnimationTrackLike[]

    The clip's tracks, in evaluation order (§17).

    Order is the array's order, forever — insertion order, never sorted or de-duplicated (§33: iterate collections in insertion order only). Two tracks on the same path are allowed and the later one wins, because that is what applying them in order does; the mixer, which owns conflict policy (§16), is where a warning belongs.

    • Visits every event in the half-open interval (fromExclusive, toInclusive] — event.time > fromExclusive && event.time <= toInclusive — in time order, and returns how many were visited.

      Forward playback advances clip time in steps: (t₀ → t₁], (t₁ → t₂], … Because each step excludes its start and includes its end, consecutive steps partition the timeline: every event fires exactly once, and an event landing exactly on a step boundary fires with the step that reaches it, never with the one that leaves it. That is §16's "exactly once per forward crossing" reduced to arithmetic.

      Consequences worth stating outright:

      • an event at exactly toInclusive is visited; one at exactly fromExclusive is not;
      • an empty range (fromExclusive === toInclusive) visits nothing, so a paused player crossing no time fires nothing;
      • a reversed range (toInclusive < fromExclusive) visits nothing and returns 0. Reverse playback is not "the same thing backwards": §16 defines marker crossing as a forward notion, so a player running in reverse decides its own policy rather than getting a silent guess here;
      • an event at time 0 needs fromExclusive < 0 to fire. A player starting at 0 therefore begins its first step from a value below zero (or fires the zero-time events explicitly on start) — a deliberate consequence of the rule that no event fires twice.

      The visitor receives the event and its index into AnimationClip.events. Allocation-free with a hoisted visitor: the scan is a binary search for the first event past fromExclusive followed by a walk.

      Parameters

      Returns number

    • Index of the first event with time > timeExclusive, or events.length when there is none.

      The positioning primitive behind AnimationClip.eventsInRange, and the one a seek uses on its own: jumping to time t sets the cursor here so that already-crossed markers are skipped rather than re-fired (§16). Binary search; allocation-free.

      Parameters

      • timeExclusive: number

      Returns number

    • Samples every track at timeSeconds (clip-local) and hands each result to sink, in AnimationClip.tracks order (§33: insertion order only).

      Allocates nothing, provided the sink's outFor returns pre-allocated storage. This is the whole of the clip's contribution to the mixer's inner loop: ordered iteration, with the guarantee that a track's index here is the same index it had when the mixer resolved its binding.

      Parameters

      Returns void