animations[] is the declarative state-animation surface. Each animation
targets one element id and either changes one live object or performs a
previous/next visual handoff.
Try it in the Playground.
animations[]| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
id |
string | Yes | - | Animation id. |
targetId |
string | Yes | - | Element id targeted in this render state. |
type |
string | Yes | - | update or transition. |
tween |
object | Update | - | Standard update properties and filter timelines grouped by id. |
playback |
object | No | defaults | Continuity, speed, and looping controls. |
prev |
object | Transition | - | Motion applied to the captured previous surface. |
next |
object | Transition | - | Motion applied to the captured next surface. |
mask |
object | Transition | - | Image-driven transition reveal field. |
compositor |
object | Transition | - | Inline shader effect with its own required tween.progress. |
complete |
object | No | - | Parsed configuration; public completion is currently render-wide. |
Every animation requires a stable id, targetId, and type.
updateupdate changes properties on one live display object. Use it for motion,
opacity, scale, rotation, blur, or independently targeted shader parameters
where the element remains the same object.
The intended authoring contract is update-only. Use transition for a
previous/next replacement handoff, including enter, exit, and replacement
effects. Some element plugins still execute update tweens during add/delete for
legacy compatibility; new content should not depend on that behavior.
transitiontransition captures the visual before and after a state change and hands off
between those surfaces. Use it for:
targetIdA transition may compose prev, next, mask, and compositor. Missing
previous or next content is treated as transparent. When both mask and
compositor are present, the mask executes before the custom compositor passes.
These properties are valid under type: update:
| Property | Meaning |
|---|---|
x, y |
Absolute position in the parent coordinate space. |
translateX |
Offset in units of the target's own width. |
translateY |
Offset in units of the target's own height. |
alpha |
Opacity. |
scaleX |
Horizontal scale. |
scaleY |
Vertical scale. |
rotation |
Rotation in degrees. |
blurX |
Horizontal blur.x strength. |
blurY |
Vertical blur.y strength. |
width |
Rect geometry width. |
height |
Rect geometry height. |
fill |
Rect fill color, gradient geometry, or gradient stops. |
border |
Rect border width, color, or alpha. |
cornerRadius |
Rect uniform or independent corner radii. |
filters |
Parameter timelines grouped by inline shader filter id. |
x cannot be combined with translateX in one tween, and y cannot be
combined with translateY.
blurX and blurY animate only blur strength. Static blur settings such as
quality, kernelSize, and repeatEdgePixels are not tween targets.
width, height, fill, border, and cornerRadius are valid only for
rect targets. See Rect Node for their nested timeline
shape and gradient-stop indexing.
Put filter timelines inside the normal update tween, grouped by filter id:
animations:
- id: pulse-glow
targetId: portrait
type: update
tween:
alpha:
keyframes:
- duration: 500
value: 1
filters:
glow:
strength:
keyframes:
- duration: 500
value: 1
easing: easeInOutSine
tint:
keyframes:
- duration: 500
value: [0.4, 0.7, 1]
progress:
initialValue: 0
keyframes:
- duration: 500
value: 1
Ordinary properties and multiple filter ids may coexist in one tween.
Parameter keys refer to top-level effect parameters (or legacy uniforms).
The authored progress key targets the selected filter's uProgress.
Shader values may be a finite number or a numeric array with length 2, 3, 4, 9, or 16. Arrays interpolate and apply relative keyframes component by component. Values must have the same shape as the target parameter.
Only one active animation may write a particular
targetId + filterId + parameter channel. uTime/time is a read-only
deterministic clock and cannot be tweened.
Each update property accepts:
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
initialValue |
value | No | current property value | Value sampled before the first segment. |
keyframes |
array | Yes | - | Ordered animation segments. |
Each keyframe accepts:
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
value |
value | Yes | - | Target value compatible with the animated channel. |
delay |
number | No | 0 |
Milliseconds to hold the previous value first. |
duration |
number | Yes | - | Milliseconds used to reach this value after delay. |
easing |
string | No | linear |
Easing used by the segment reaching this keyframe. |
relative |
boolean | No | false |
Treat value as a delta from the preceding value. |
animations:
- id: card-shift
targetId: card
type: update
tween:
x:
initialValue: 100
keyframes:
- duration: 450
value: 800
easing: easeOutQuad
alpha:
keyframes:
- duration: 300
value: 1
easing: linear
Set delay on a keyframe to hold the preceding value before that keyframe's
interpolation starts. A delay on the first keyframe holds initialValue, or
the current live value when initialValue is omitted. A delay on a later
keyframe creates an empty space between the two movements:
tween:
x:
initialValue: 100
keyframes:
- delay: 300
duration: 400
value: 500
easing: easeOutQuad
- delay: 800
duration: 400
value: 900
easing: easeInQuad
This track holds 100 for 300 ms, moves to 500 over 400 ms, holds 500
for 800 ms, then moves to 900 over 400 ms. Its total duration is 1900 ms.
delay is measured in milliseconds and must be a finite number greater than
or equal to zero. It contributes to completion time, scales with
playback.speed, and repeats as part of a loop. delay: 0 is equivalent to
omitting it. duration describes only the interpolation after the hold.
The same delay behavior applies to ordinary properties, rect style and
geometry tracks, shader filter parameters, transition prev/next surfaces,
mask progress, and compositor progress or parameters.
Update properties also support auto, which generates one segment from the
current live value to the value in the next render state:
animations:
- id: card-shift
targetId: card
type: update
tween:
x:
auto:
delay: 200
duration: 450
easing: easeOutQuad
y:
auto:
duration: 450
easing: easeOutQuad
| Field | Type | Required | Default |
|---|---|---|---|
delay |
number | No | 0 |
duration |
number | Yes | - |
easing |
string | No | linear |
auto and keyframes are mutually exclusive for one property. auto is not
supported on prev.tween or next.tween. auto.delay holds the current live
value before moving toward the next render state's value.
Supported easing names are:
lineareaseInQuad, easeOutQuad, easeInOutQuadeaseInCubic, easeOutCubic, easeInOutCubiceaseInQuart, easeOutQuart, easeInOutQuarteaseInQuint, easeOutQuint, easeInOutQuinteaseInSine, easeOutSine, easeInOutSineeaseInExpo, easeOutExpo, easeInOutExpoeaseInCirc, easeOutCirc, easeInOutCirceaseInBack, easeOutBack, easeInOutBackeaseInBounce, easeOutBounce, easeInOutBounceeaseInElastic, easeOutElastic, easeInOutElasticplayback:
continuity: persistent
speed: 1
loop: true
| Field | Type | Default | Notes |
|---|---|---|---|
continuity |
string | render |
render or persistent. |
speed |
number | 1 |
Finite multiplier greater than zero. |
loop |
boolean | false |
Infinite repetition; valid only for type: update. |
speed: 2 runs twice as fast and speed: 0.5 runs at half authored speed.
continuity: render, or omitting playback, ties the animation to the current
render. A later changed render may cancel it. If the animation is authored
again later, it starts from the beginning.
Finite render-scoped animations contribute to the global renderComplete
event.
continuity: persistent allows the same in-flight animation to continue across
unrelated later renders instead of restarting.
For an update, continuity requires:
idtargetIdtween, filter timelines, and playbackFor a transition, continuity additionally requires unchanged prev, next,
mask, inline compositor including its tween, and playback configuration,
plus the same owned target subtree.
Persistent transitions keep their original captured handoff. They do not retarget or rebuild snapshots when unrelated content changes.
Persistent animations do not contribute to renderComplete.
playback.loop: true repeats the complete update timeline indefinitely.
Looping transitions are rejected.
Loops:
playback.speedrenderCompletecompleteanimations:
- id: background-breathe
targetId: background
type: update
playback:
continuity: persistent
loop: true
tween:
scaleX:
initialValue: 1
keyframes:
- duration: 3000
value: 1.05
easing: easeInOutSine
- duration: 3000
value: 1
easing: easeInOutSine
scaleY:
initialValue: 1
keyframes:
- duration: 3000
value: 1.05
easing: easeInOutSine
- duration: 3000
value: 1
easing: easeInOutSine
prev.tween and next.tween independently animate captured surfaces.
Supported properties:
x, ytranslateX, translateYalphascaleX, scaleYrotationx and y use absolute parent coordinates. translateX: 1 moves by one
animated subject width, while translateY: -1 moves by one subject height
upward.
Transition sides use manual keyframes:
animations:
- id: scene-push-left
targetId: scene-root
type: transition
prev:
tween:
translateX:
initialValue: 0
keyframes:
- duration: 500
value: -1
easing: easeInOutCubic
next:
tween:
translateX:
initialValue: 1
keyframes:
- duration: 500
value: 0
easing: easeInOutCubic
mask is valid only on type: transition. It accepts either the existing
single-object shape or a non-empty array; a single object is normalized to a
one-entry array. Its entries can be combined with prev and next surface
motion. Overlapping entries use the per-pixel maximum reveal, so the strongest
mask wins without compounding soft edges. A delayed entry contributes zero
reveal until its start time.
Common fields:
| Field | Type | Default | Notes |
|---|---|---|---|
kind |
string | - | Required: single or sequence. |
channel |
string | red |
red, green, blue, or alpha. |
invert |
boolean | false |
Reverses the sampled reveal field. |
delay |
integer | 0 |
Milliseconds before the mask becomes active. |
progress |
object | immediate | Manual keyframe timeline from 0 to 1. |
mask:
- kind: single
texture: spiral-mask
channel: red
softness: 0.08
delay: 200
progress:
initialValue: 0
keyframes:
- duration: 900
value: 1
easing: linear
texture is required. softness controls the feathered reveal threshold.
delay keeps the mask completely inactive and holds the previous surface
unchanged. After that time, the progress timeline begins. It is additive with a
delay on the first progress keyframe: mask delay controls activation, while
keyframe delay holds the initial progress after activation.
For a top-level portable gsap transition, put timing on the action targeting
the indexed transitionMask; mask-entry delay is not accepted in that
authoring mode.
mask:
- kind: sequence
channel: alpha
sample: linear
progress:
initialValue: 0
keyframes:
- duration: 1000
value: 1
easing: linear
frames:
- at: 0
texture: masks/frame-0
- at: 0.5
texture: masks/frame-1
- at: 1
texture: masks/frame-2
Sequence rules:
at values0 and last frame at 1sample: hold by default, or sample: linearsoftness is not supportedcompositor is a transition-only inline shader effect that receives the
captured previous and next surfaces. It may define one source or an ordered
passes chain.
When a compositor is present:
compositor.tween.progress is required and maps to uProgressprev.tween and next.tween may still animate the captured surfacesmesh.gridmask may be used and executes before custom compositor passesprogressanimations:
- id: shader-crossfade
targetId: scene-root
type: transition
compositor:
type: shader
parameters:
vignette: 0.15
source:
webgl:
fragment: |
// GLSL fragment source
webgpu:
source: |
// WGSL source with mainVertex and mainFragment
tween:
progress:
initialValue: 0
keyframes:
- duration: 800
value: 1
easing: easeInOutCubic
vignette:
keyframes:
- duration: 800
value: 0.35
See Shaders for source layouts, built-in inputs, multi-pass rules, parameter and texture binding, deterministic time, mesh behavior, and alpha requirements.
animations:
- id: title-enter
targetId: title
type: transition
next:
tween:
alpha:
initialValue: 0
keyframes:
- duration: 300
value: 1
easing: linear
animations:
- id: title-exit
targetId: title
type: transition
prev:
tween:
alpha:
initialValue: 1
keyframes:
- duration: 300
value: 0
easing: linear
animations:
- id: chip-pulse
targetId: chip
type: update
tween:
x:
keyframes:
- duration: 120
value: 20
easing: linear
relative: true
- duration: 120
value: -20
easing: linear
relative: true
- duration: 120
value: 0
easing: linear
relative: true
update and transition in the
same render state.renderComplete for the interrupted state with aborted: true.eventHandler.renderComplete event to know when finite tracked tweens,
text reveals, and non-looping video have settled.