Timelines
Timelines sequence multiple tween segments, callbacks, and labels over time. Under the hood, each segment spawns Tween entities lazily as the playhead reaches them, which are then processed by the batch TweenSystem.
Creating a timeline
Section titled “Creating a timeline”import { AnimationTimeSource } from '@shell/animate';
const animate = resources.get('animate');
const tl = animate.timeline({ loop: -1, // -1 = infinite, 0 = no loop alternate: true, // ping-pong direction each loop autoplay: true, // start immediately (default) playbackRate: 1, // speed multiplier timeSource: AnimationTimeSource.Simulation,});TimelineOptions
Section titled “TimelineOptions”| Property | Type | Default | Description |
|---|---|---|---|
loop | number | 0 | Number of loops (-1 = infinite) |
alternate | boolean | false | Alternate direction each loop |
autoplay | boolean | true | Start playback immediately |
playbackRate | number | 1 | Speed multiplier (2 = 2x speed) |
timeSource | AnimationTimeSource | AnimationTimeSource.Simulation | Clock used by the playhead and every child tween |
A timeline owns one time source for its playhead, callbacks, loops, offsets, and child tweens. Segment options cannot select a different clock. Wall-time timelines use the ticker’s unscaled frame delta and stop advancing when the ticker is paused or stopped.
Adding segments
Section titled “Adding segments”tl.add(entity, Position, { x: 100, duration: 500 }, 0) // absolute time 0 .add(entity, Position, { y: 200, duration: 500 }, '+=200') // 200ms after previous end .set(entity, Opacity, { value: 0 }, '<') // same start as previous .call(() => console.log('halfway'), 350) // callback at 350ms .label('midpoint', 350) // named position .add(entity, Position, { x: 0, duration: 500 }, 'midpoint'); // at labelPosition types
Section titled “Position types”| Position | Meaning |
|---|---|
number | Absolute time in milliseconds |
'+=N' | N ms after the previous segment ends |
'-=N' | N ms before the previous segment ends |
'<' | Same start time as the previous segment |
'<+=N' | N ms after the previous segment starts |
'<-=N' | N ms before the previous segment starts |
'labelName' | At the named label position |
undefined | Sequential — at the end of the timeline |
Methods
Section titled “Methods”| Method | Description |
|---|---|
add(entity, component, properties, position?) | Add a tween segment |
set(entity, component, properties, position?) | Add a zero-duration tween (immediate property set) |
call(callback, position?) | Schedule a callback at a position |
label(name, position?) | Define a named position for later reference |
play() | Start or resume playback |
pause() | Pause playback and all active tween handles |
reverse() | Flip playback direction |
restart() | Reset to the beginning and start playing |
seek(time) | Jump to a specific time in milliseconds |
stretch(newDuration) | Scale all segments to a new total duration |
cancel() | Stop, despawn all tweens, and remove from active list |
complete() | Jump to the end and fire completion |
then(callback?) | Returns a Promise<void> that resolves on completion |
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
currentTime | number | Current playback time in ms |
totalDuration | number | Total timeline duration in ms |
isPlaying | boolean | Whether the timeline is playing |
Looping and alternate
Section titled “Looping and alternate”When loop is set and the timeline reaches the end, it loops. With alternate: true, playback reverses direction each loop (ping-pong). Segments and callbacks are reset at the start of each loop.
Callbacks and labels
Section titled “Callbacks and labels”Callbacks fire once when the playhead passes their position:
tl.call(() => console.log('started'), 0);tl.call(() => console.log('finished'), 'end');tl.label('end', 2000);Labels can be created at any position and referenced by name in subsequent add(), set(), or call() calls.
Stretching
Section titled “Stretching”Scale the entire timeline proportionally:
tl.stretch(5000); // Expand or shrink to 5 seconds totalAll segment offsets, durations, and label positions are multiplied by the ratio.
Promises
Section titled “Promises”Await timeline completion:
await tl.then();// orawait tl.then(() => console.log('done'));Integration with systems
Section titled “Integration with systems”Timelines are advanced automatically by the TimelineSystem registered at PostUpdate. You do not need to call __update manually.