@motion-script/core / Scene
Class: Scene
Defined in: nodes/scene/scene-node.ts:85
A self-contained unit of a project's timeline.
A scene is not a node and is not composed. It owns a root Rect
(a viewport-sized world container) and a generator that builds into it. This
is what makes scene-level hot reloading work: each scene file is its own HMR
boundary (import scene from './scene?scene'), and a scene can be swapped in
place without rebuilding the rest of the timeline.
Authored with createScene — you never construct one directly:
// scenes/intro.tsx export default createScene(function* (stage) { stage.set({ fill: 'bg' }); stage.add(<Rect … />); yield* …; });
The runtime drives a scene through reset → bindAssets → ellapse → build → prepareLayoutAssets → layout → prepareRenderAssets → prepareAudioAssets → render → dispose, each forwarding to the root. Image/video/paint and font
assets are no longer hand-declared — they're inferred automatically from the
same render()/layout() calls (TrackRenderContext/TrackMeasureScope,
see Precomp.precompScene). prepareLayoutAssets/prepareRenderAssets
remain only for opaque async setup (e.g. Code's syntax grammar);
prepareAudioAssets is the one asset concern that's neither drawable nor a
simple async load — a playing clip's frame-ranged timeline registration.
The scene's authoring methods (add/set/to/camera/paint/sounds) all act
on its RootNode root. They're merged with a BuildStage into
the Stage a generator receives — see Scene.build.
Constructors
Constructor
new Scene(
generator):Scene
Defined in: nodes/scene/scene-node.ts:133
Parameters
generator
Returns
Scene
Properties
__precompKey?
optional__precompKey?:string
Defined in: nodes/scene/scene-node.ts:121
Identity of this scene's content, for a PrecompCache.
Distinct from __sceneHotId, which identifies the timeline slot a scene belongs to and therefore stays the same across an edit — that is exactly what hot replacement needs, and exactly what a measurement cache must not key on, since it would serve the pre-edit frame count forever.
A host that sets this should derive it from everything the pass depends on — the scene's own content, the viewport, and the fps — so that equal keys really do imply equal passes. Because it travels on the scene instance, a pass that completes after the host has moved on is still recorded against the build it actually measured, rather than whatever is current when it lands.
Falls back to __sceneHotId when unset (see storeKeyOf), which is
the right key for the Vite plugin's store — it validates entries by
re-hashing each one's recorded source dependencies instead.
__sceneHotId?
optional__sceneHotId?:string
Defined in: nodes/scene/scene-node.ts:100
Stable identity of the scene's source module, stamped by the ?scene Vite
transform (the scene file's path relative to the project root). Used to
route a hot update back to the right timeline slot. undefined outside the
dev-server ?scene pipeline.
name
name:
string="Scene"
Defined in: nodes/scene/scene-node.ts:125
Human-readable name for the timeline/errors. Defaults to "Scene"; the
?scene transform overrides it with the file's basename.
root
readonlyroot:RootNode
Defined in: nodes/scene/scene-node.ts:89
The world container this scene builds into. Viewport-sized, top-level. A RootNode: a layouting Rect that also acts as the scene camera.
Accessors
align
Get Signature
get align():
Anchor
Defined in: nodes/scene/scene-node.ts:227
Alignment of the root's children within the viewport.
Returns
Set Signature
set align(
value):void
Defined in: nodes/scene/scene-node.ts:228
Parameters
value
Returns
void
assets
Get Signature
get assets():
AssetCatalog
Defined in: nodes/scene/scene-node.ts:254
The asset catalog bound to the scene (via bindAssets).
Returns
clock
Get Signature
get clock():
Readonly<NodeClock>
Defined in: nodes/scene/scene-node.ts:249
Internal timing state of the root (scene-relative clock).
Returns
Readonly<NodeClock>
fill
Get Signature
get fill():
Fill
Defined in: nodes/scene/scene-node.ts:210
The root's background fill.
Returns
Set Signature
set fill(
value):void
Defined in: nodes/scene/scene-node.ts:211
Parameters
value
Returns
void
flow
Get Signature
get flow():
FlowMode
Defined in: nodes/scene/scene-node.ts:220
The root's layout mode for children: horizontal / vertical / freeform.
Returns
Set Signature
set flow(
value):void
Defined in: nodes/scene/scene-node.ts:221
Parameters
value
Returns
void
gap
Get Signature
get gap():
GapSize
Defined in: nodes/scene/scene-node.ts:224
Spacing between the root's children along the layout's main axis. Set via stage.set({ gap }).
Returns
heading
Get Signature
get heading():
number
Defined in: nodes/scene/scene-node.ts:245
Camera view rotation in degrees (clockwise).
Returns
number
Set Signature
set heading(
value):void
Defined in: nodes/scene/scene-node.ts:246
Parameters
value
number
Returns
void
origin
Get Signature
get origin():
Vector2
Defined in: nodes/scene/scene-node.ts:241
World-space point that maps to the centre of the viewport.
Returns
Set Signature
set origin(
value):void
Defined in: nodes/scene/scene-node.ts:242
Parameters
value
Returns
void
overlay
Get Signature
get overlay():
Fill
Defined in: nodes/scene/scene-node.ts:214
The root's overlay.
Returns
Set Signature
set overlay(
value):void
Defined in: nodes/scene/scene-node.ts:215
Parameters
value
Returns
void
padding
Get Signature
get padding():
Insets
Defined in: nodes/scene/scene-node.ts:231
Inner spacing between the viewport edges and the root's children.
Returns
Set Signature
set padding(
value):void
Defined in: nodes/scene/scene-node.ts:232
Parameters
value
Returns
void
viewportSize
Get Signature
get viewportSize():
Size2D|null
Defined in: nodes/scene/scene-node.ts:145
The full viewport this scene renders its world against.
Returns
Size2D | null
zoom
Get Signature
get zoom():
number
Defined in: nodes/scene/scene-node.ts:237
Camera magnification factor. > 1 zooms in; < 1 zooms out.
Returns
number
Set Signature
set zoom(
value):void
Defined in: nodes/scene/scene-node.ts:238
Parameters
value
number
Returns
void
Methods
add()
add(
node):void
Defined in: nodes/scene/scene-node.ts:162
Add a node (or array of nodes) as a child of the scene's root.
Parameters
node
Node<NodeProps> | Node<NodeProps>[]
Returns
void
bindAssets()
bindAssets(
context):void
Defined in: nodes/scene/scene-node.ts:338
Bind the asset catalog to the scene's whole node subtree.
Parameters
context
Returns
void
bindContext()
bindContext(
context,runInit):void
Defined in: nodes/scene/scene-node.ts:348
Push inherited context (theme/data/seed/text-style and user tokens) down
the scene's whole subtree. runInit true at start-of-pass (also fires each
node's init); false for the per-frame structural re-push. Mirrors
bindAssets. See Node.bindContext.
Parameters
context
runInit
boolean
Returns
void
build()
build(
stage):FrameGenerator
Defined in: nodes/scene/scene-node.ts:313
Produce this scene's frame generator. The generator is handed a single
Stage object that exposes both surfaces: this scene's authoring
methods (add/set/to/zoomTo/sounds/…) and the build stage's
determinism (viewport/fps/random/noise/seed).
The merge is a view created with the scene as its prototype (so authoring
resolves to real Scene members) overlaid with the stage's own properties
and its methods bound to the stage (so determinism keeps the stage's
this). One view is built per build pass.
Parameters
stage
BuildStage<Scene>
Returns
dispose()
dispose():
void
Defined in: nodes/scene/scene-node.ts:401
Returns
void
ellapse()
ellapse(
totalTime):void
Defined in: nodes/scene/scene-node.ts:353
Advance the scene's clock and per-frame sampling for the whole subtree.
Parameters
totalTime
number
Returns
void
fillTo()
fillTo(
to,duration,options?):FrameGenerator
Defined in: nodes/scene/scene-node.ts:200
Animate the root fill (the scene-wide background).
Parameters
to
duration
number
options?
Returns
headingTo()
headingTo(
heading,duration,ease?):FrameGenerator
Defined in: nodes/scene/scene-node.ts:193
Animate the camera view rotation (heading) in degrees.
Parameters
heading
number
duration
number
ease?
Returns
layout()
layout(
rect,scope):void
Defined in: nodes/scene/scene-node.ts:364
Lay the scene's world out against the given (full-viewport) bounds.
Parameters
rect
scope
Returns
void
overlayTo()
overlayTo(
to,duration,options?):FrameGenerator
Defined in: nodes/scene/scene-node.ts:205
Animate the root overlay (painted over fill + children, viewport-wide).
Parameters
to
duration
number
options?
Returns
panTo()
panTo(
lookAt,duration,ease?):FrameGenerator
Defined in: nodes/scene/scene-node.ts:188
Animate the camera focus point (lookAt) — the world point at viewport centre.
Parameters
lookAt
duration
number
ease?
Returns
playSound()
playSound(
src,opts?):FrameGenerator
Defined in: nodes/scene/scene-node.ts:285
Play a sound on the scene's audio timeline. Blocks for the clip's duration.
Use as yield* stage.playSound(...) inside a scene generator.
Parameters
src
string | Sound
opts?
Omit<SoundProps, "src">
Returns
prepareAudioAssets()
prepareAudioAssets(
tracker):void
Defined in: nodes/scene/scene-node.ts:396
Collect the scene's audio-scheduling requests — nodes with a playing clip (e.g. Video) and managed sounds (startSound/ playSound). Has no layout dependency, so it can run either side of layout; kept after by convention.
Parameters
tracker
Returns
void
prepareLayoutAssets()
prepareLayoutAssets():
void
Defined in: nodes/scene/scene-node.ts:378
Fire the scene's pre-layout async setup (e.g. Code's syntax
grammar). Called before layout; fire-and-forget, see
Node.prepareLayoutAssets.
Returns
void
prepareRenderAssets()
prepareRenderAssets():
void
Defined in: nodes/scene/scene-node.ts:386
Fire the scene's pre-render async setup. Called after layout; fire-and-forget, see Node.prepareRenderAssets.
Returns
void
render()
render(
context):void
Defined in: nodes/scene/scene-node.ts:369
Render the scene's world into context.
Parameters
context
Returns
void
reset()
reset():
void
Defined in: nodes/scene/scene-node.ts:321
Clear all dynamically-added children and managed sounds, and reset the clock.
Returns
void
sample()
sample():
void
Defined in: nodes/scene/scene-node.ts:359
Seed per-frame derived state (motion) without a full ellapse.
Returns
void
set()
set(
props):void
Defined in: nodes/scene/scene-node.ts:171
Set one or more reactive props on the root container.
Parameters
props
align?
Alignment of children within the content box: a named position
('center', 'topLeft', …) or an explicit per-axis pivot Vector2
(x: -1 left … +1 right, y: -1 bottom … +1 top).
blend?
"color" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "difference" | "exclusion" | "hue" | "saturation" | "luminosity" | "normal" | "pass-through" | (() => "color" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "difference" | "exclusion" | "hue" | "saturation" | "luminosity" | "normal" | "pass-through")
Layer blend mode. 'pass-through' (default) does not isolate the node — its opacity scales each child/fill while they blend against the backdrop. Any other mode isolates the node and blends its flattened result against the backdrop.
bottomCenter?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
bottomLeft?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
bottomRight?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
center?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
centerLeft?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
centerRight?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
childPositioning?
ChildPositioning | (() => ChildPositioning)
Frame of reference this node lays its children out in. 'relative'
(default) positions them inside this node's own content box; 'absolute'
pins them to the stage instead, so their x/y are scene-root
coordinates and this node's flow/gap/padding no longer place them.
Overridden per child by relativeToParent.
children?
NodeChildren | (() => NodeChildren)
Child nodes. A single Node, or an arbitrarily-nested array of them
— the constructor flattens nesting (.flat(Infinity)), so .map() results
can be dropped in directly as a child without spreading, like React.
clip?
boolean | (() => boolean)
When true, content drawn outside this node's outline is clipped away (see Node.clipSelf).
colSpan?
number | (() => number)
How many grid columns this child spans. Default 1.
column?
number | (() => number)
1-based column index for explicit grid placement. Undefined = auto-placed.
effects?
fill?
Background fill layer(s). Each item can be a CSS color string, a fill
prop object, an already-resolved fill, or a FillChain from the
Fills builder. Painted behind the scene's children.
flex?
number | (() => number)
Proportional share of the free space along the parent's main axis,
relative to sibling fill children (like Flutter's Expanded(flex:)).
Only meaningful when this node fills the main axis — in a row that's
width:'fill', in a column height:'fill'. Two siblings with flex 2
and 1 split the free space 2:1. Defaults to 1. Specifying flex without
an explicit width/height defaults both to 'fill'.
flow?
Layout mode for children: flex horizontal / vertical, or overlapping freeform.
gap?
Spacing between children along the layout's main axis.
heading?
number | (() => number)
Rotation of the camera view in degrees (clockwise).
height?
SizeInput | (() => SizeInput)
lookAt?
World-space point that maps to the centre of the viewport.
opacity?
number | (() => number)
overlay?
Overlay layer(s) — same loose values as fill, but painted over the fill and the children (clipped to the viewport). Use for textures laid across the whole scene, e.g. a VHS-grain image or video.
padding?
Inner spacing between this node's edges and its content/children.
pivot?
Pivot point for rotation and scale. Either a named anchor ('center',
'topRight', 'bottomLeft', … — the node align vocabulary) or an explicit
Vector2: (0,0)=center, (-1,1)=top-left, (1,-1)=bottom-right. Set
automatically when an anchor positioning prop is used.
relativeToParent?
RelativeToParent | (() => RelativeToParent)
This node's own override of its parent's childPositioning.
'inherit' (default) takes whatever the parent declared; 'relative' and
'absolute' opt this one node in or out regardless.
rotation?
number | (() => number)
row?
number | (() => number)
1-based row index for explicit grid placement. Undefined = auto-placed.
rowSpan?
number | (() => number)
How many grid rows this child spans. Default 1.
scale?
number | (() => number)
seed?
string | number | (() => string | number)
Origin seed for this node's Node.random source. Defaults to 0.
Set it to give the node a reproducible-but-distinct random stream without
re-seeding by hand. The constructor adopts it as random's origin, and the
runtime rebuilds the node each playback pass, so draws stay reproducible
across scrub/precomp/HMR.
size?
SizeInput | (() => SizeInput)
Sets width and height to the same value in one go. Pure sugar: at
construction time, an author-facing size is expanded into width/
height before either is applied. Explicit width or height takes
precedence over size (mirroring padding's side-vs-shorthand rule),
so { size: 200, width: 100 } yields width: 100, height: 200.
Reactive bindings and to()/set() targets both work the same as
width/height — size: 'fill', size: () => ..., or
node.to({ size: 300 }, 0.5) are all valid.
topCenter?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
topLeft?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
topRight?
Vector2 | (() => Vector2) | (() => Vector2 | (() => Vector2))
width?
SizeInput | (() => SizeInput)
x?
number | (() => number)
y?
number | (() => number)
zoom?
number | (() => number)
Camera magnification factor. Values > 1 zoom in; < 1 zoom out.
Returns
void
setViewport()
setViewport(
size):void
Defined in: nodes/scene/scene-node.ts:150
Record the full viewport (called by the playback engine).
Parameters
size
Returns
void
startSound()
startSound(
src,opts?):Sound
Defined in: nodes/scene/scene-node.ts:262
Start a sound on the scene's audio timeline without blocking, and return the Sound handle. Pair with stopSound to end playback.
Parameters
src
string | Sound
opts?
Omit<SoundProps, "src">
Returns
stopSound()
stopSound(
sound):void
Defined in: nodes/scene/scene-node.ts:276
Stop a sound started via startSound. No-op if it isn't playing.
Parameters
sound
Returns
void
to()
to(
props,duration,easing?):AnimationBuilder<RootProps>
Defined in: nodes/scene/scene-node.ts:176
Animate any root props in one call — yield* stage.to({ zoom: 2, fill: 'red' }, 1).
Parameters
props
Partial<RootProps>
duration
number
easing?
Returns
zoomTo()
zoomTo(
zoom,duration,ease?):FrameGenerator
Defined in: nodes/scene/scene-node.ts:183
Animate the camera magnification (zoom). > 1 zooms in; < 1 zooms out.
Parameters
zoom
number
duration
number