MotionScript

@motion-script/core


@motion-script/core / Camera

Class: Camera

Defined in: nodes/layout/camera-node.ts:44

Camera node — a card that holds its own little world. It draws itself like a Rect (fill, stroke, shadow, corners), then renders its children through a viewport transform defined by zoom, centerOn, and heading. The camera's own layout rect is both the card and the viewport bounds; the world is clipped to that rect so nothing spills outside the card.

Unlike Rect it runs no flex/stack layout — children are laid out stack-style (centered) and then viewed through the camera transform.

Extends

Constructors

Constructor

new Camera(props): Camera

Defined in: nodes/layout/camera-node.ts:58

Parameters

props

NodeConfig<Camera, CameraProps>

Returns

Camera

Overrides

ShapeNode.constructor

Properties

__mappers?

optional __mappers?: Map<string, (ext, prev?) => any>

Defined in: nodes/base/node.ts:325

Maps external prop value → internal cell value for fields that need it.

Inherited from

ShapeNode.__mappers


__signals?

optional __signals?: Map<string, Signal<any>>

Defined in: nodes/base/node.ts:321

Inherited from

ShapeNode.__signals


__tweens?

optional __tweens?: Map<string, TweenFn<any>>

Defined in: nodes/base/node.ts:323

Inherited from

ShapeNode.__tweens


__upgraders?

optional __upgraders?: Map<string, () => Signal<any>>

Defined in: nodes/base/node.ts:322

Inherited from

ShapeNode.__upgraders


_children

protected _children: Node<NodeProps>[] = []

Defined in: nodes/base/node.ts:387

Inherited from

ShapeNode._children


_lastScope?

optional _lastScope?: MeasureScope

Defined in: nodes/base/node.ts:373

The MeasureScope threaded through the last measure pass, retained so off-tree work (e.g. the animated child-insert in node-lifecycle.ts) can measure a not-yet-attached child in isolation — measuring its natural size without adding it to this node's layout flow, so siblings don't shift for a frame. Undefined until this node is first measured. @internal.

Inherited from

ShapeNode._lastScope


_props?

protected optional _props?: NodeConfig<any, CameraProps>

Defined in: nodes/base/node.ts:298

The raw props this node was constructed with, retained past construction so a provider's provideContext can see which keys the author explicitly passed on every bind walk (e.g. DefaultTextStyle contributes only the style keys it was given). Authored identity — deliberately kept through dispose so a reused instance re-derives context from the next walk.

Inherited from

ShapeNode._props


_stateStack

_stateStack: Map<string, SignalSnapshot<any>>[] = []

Defined in: nodes/base/node.ts:910

Internal

LIFO stack of save() snapshot layers. Underscore-internal so the reactive companion can read it; not authoring surface.

Inherited from

ShapeNode._stateStack


blend

blend: "color" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "difference" | "exclusion" | "hue" | "saturation" | "luminosity" | "normal" | "pass-through"

Defined in: nodes/base/node.ts:336

Inherited from

ShapeNode.blend


clip

clip: boolean

Defined in: nodes/base/node.ts:344

When true, content drawn by this node's children is clipped to its outline (see clipSelf).

Inherited from

ShapeNode.clip


colSpan

colSpan: number

Defined in: nodes/base/node.ts:359

Inherited from

ShapeNode.colSpan


column

column: number | undefined

Defined in: nodes/base/node.ts:357

Inherited from

ShapeNode.column


constraints

protected constraints: SizeConstraints

Defined in: nodes/base/node.ts:363

Inherited from

ShapeNode.constraints


cornerRadius

cornerRadius: RectCornerRadius

Defined in: nodes/layout/camera-node.ts:54


cornerStyle

cornerStyle: RectCornerStyle

Defined in: nodes/layout/camera-node.ts:56


effects

effects: Effect

Defined in: nodes/base/node.ts:337

Inherited from

ShapeNode.effects


end

end: number

Defined in: nodes/geometry/shape-node.ts:82

Inherited from

ShapeNode.end


fill

fill: Fill

Defined in: nodes/geometry/shape-node.ts:65

Inherited from

ShapeNode.fill


flex

flex: number

Defined in: nodes/base/node.ts:346

Inherited from

ShapeNode.flex


gapScale

gapScale: number

Defined in: nodes/base/node.ts:356

Per-child weight for the flex gap this node contributes to its parent's main axis, in [0, 1]. Default 1 = a full gap on each side (normal layout). Driven 0 → 1 (insert) / 1 → 0 (remove) by the animated addChildAt/removeChildAt overloads so the surrounding gap opens/closes in lockstep with the child's box instead of popping — see addChildAtAnimated. Read only by flex containers off their children; authors have no reason to set it directly. @internal.

Inherited from

ShapeNode.gapScale


heading

heading: number

Defined in: nodes/layout/camera-node.ts:51

View rotation in degrees (default: 0).


height

height: SizeInput

Defined in: nodes/base/node.ts:332

Inherited from

ShapeNode.height


id

readonly id: string

Defined in: nodes/base/node.ts:319

Inherited from

ShapeNode.id


lookAt

lookAt: Vector2

Defined in: nodes/layout/camera-node.ts:49

World-space point the viewport centres on (default: {x:0, y:0}).


opacity

opacity: number

Defined in: nodes/base/node.ts:335

Inherited from

ShapeNode.opacity


overlay

overlay: Fill

Defined in: nodes/geometry/shape-node.ts:70

Inherited from

ShapeNode.overlay


padding

padding: Insets

Defined in: nodes/base/node.ts:338

Inherited from

ShapeNode.padding


pivot

readonly pivot: Anchor

Defined in: nodes/base/node.ts:341

Inherited from

ShapeNode.pivot


random

readonly random: Random

Defined in: nodes/base/node.ts:317

Per-node seeded randomness, available to every subclass without threading a Random in from the stage. Defaults to seed 0; set the origin via the NodeProps.seed prop, or re-seed in the constructor with this.random.reset(seed) / this.random.seed = seed.

Draws are reproducible across scrub/precomp/HMR out of the box: the runtime rebuilds a fresh node (and thus a fresh source at its constructor-set seed) on every playback pass rather than reusing a source that has advanced — so a draw taken during construction always starts from the seed head, no per-pass rewind needed.

Inherited from

ShapeNode.random


rotation

rotation: number

Defined in: nodes/base/node.ts:334

Inherited from

ShapeNode.rotation


row

row: number | undefined

Defined in: nodes/base/node.ts:358

Inherited from

ShapeNode.row


rowSpan

rowSpan: number

Defined in: nodes/base/node.ts:360

Inherited from

ShapeNode.rowSpan


scale

scale: number

Defined in: nodes/base/node.ts:333

Inherited from

ShapeNode.scale


shadow

shadow: Shadow

Defined in: nodes/geometry/shape-node.ts:76

Inherited from

ShapeNode.shadow


start

start: number

Defined in: nodes/geometry/shape-node.ts:79

Inherited from

ShapeNode.start


stroke

stroke: Stroke

Defined in: nodes/geometry/shape-node.ts:73

Inherited from

ShapeNode.stroke


width

width: SizeInput

Defined in: nodes/base/node.ts:331

Inherited from

ShapeNode.width


x

x: number

Defined in: nodes/base/node.ts:329

Inherited from

ShapeNode.x


y

y: number

Defined in: nodes/base/node.ts:330

Inherited from

ShapeNode.y


zoom

zoom: number

Defined in: nodes/layout/camera-node.ts:47

Magnification factor (default: 1).

Accessors

assets

Get Signature

get assets(): AssetCatalog

Defined in: nodes/base/node.ts:274

Returns

AssetCatalog

Inherited from

ShapeNode.assets


bottomCenter

Get Signature

get bottomCenter(): Vector2

Defined in: nodes/base/node.ts:1264

Returns

Vector2

Inherited from

ShapeNode.bottomCenter


bottomLeft

Get Signature

get bottomLeft(): Vector2

Defined in: nodes/base/node.ts:1249

Returns

Vector2

Inherited from

ShapeNode.bottomLeft


bottomRight

Get Signature

get bottomRight(): Vector2

Defined in: nodes/base/node.ts:1254

Returns

Vector2

Inherited from

ShapeNode.bottomRight


center

Get Signature

get center(): Vector2

Defined in: nodes/base/node.ts:1235

Center of the node — equivalent to its x/y position (0,0 is the center of the layout cell).

Returns

Vector2

Inherited from

ShapeNode.center


centerLeft

Get Signature

get centerLeft(): Vector2

Defined in: nodes/base/node.ts:1269

Returns

Vector2

Inherited from

ShapeNode.centerLeft


centerRight

Get Signature

get centerRight(): Vector2

Defined in: nodes/base/node.ts:1274

Returns

Vector2

Inherited from

ShapeNode.centerRight


children

Get Signature

get children(): Node<NodeProps>[]

Defined in: nodes/base/node.ts:1375

Returns

Node<NodeProps>[]

Inherited from

ShapeNode.children


clock

Get Signature

get clock(): Readonly<NodeClock>

Defined in: nodes/base/node.ts:970

Internal timing state.

Returns

Readonly<NodeClock>

Inherited from

ShapeNode.clock


global

Get Signature

get global(): WorldTransform

Defined in: nodes/base/node.ts:1339

Resolved world-space transform — the same anchor points and metrics as the local getters (center, topRight, rotation, …) but folded through the full ancestor chain, so values are absolute scene coordinates rather than parent-relative ones. See WorldTransform. Every field is reactive.

Examples
// Read another node's absolute corner, regardless of its parent:
const p = other.global.topRight;   // world-space {x, y}

### Reading vs. placing
`global` is for *reading* world coordinates. `x`/`y` (and the anchor props)
are **parent-relative**, so assigning a world value to them does not by
itself place this node in world space — it offsets it from this node's own
parent. To land exactly on another node regardless of either parent,
subtract this node's parent's world contribution:
// Place this node's origin exactly on `other`, any parent:
new Rect({
  x: () => other.global.x - (myParent.global.x),
  y: () => other.global.y - (myParent.global.y),
});

When both nodes share the same parent origin (e.g. both at the scene root),
`x: () => other.global.x` already lands on target with no compensation.
Returns

WorldTransform

Inherited from

ShapeNode.global


layoutRect

Get Signature

get protected layoutRect(): BoxBounds

Defined in: nodes/base/node.ts:376

The allocated bounding box from the last layout pass. Reactive — reads inside callbacks are tracked.

Returns

BoxBounds

Inherited from

ShapeNode.layoutRect


measuredHeight

Get Signature

get measuredHeight(): number

Defined in: nodes/base/node.ts:1221

Returns

number

Inherited from

ShapeNode.measuredHeight


measuredRect

Get Signature

get measuredRect(): BoxBounds

Defined in: nodes/base/node.ts:385

Internal

Returns

BoxBounds

Inherited from

ShapeNode.measuredRect


measuredWidth

Get Signature

get measuredWidth(): number

Defined in: nodes/base/node.ts:1217

Returns

number

Inherited from

ShapeNode.measuredWidth


name

Get Signature

get name(): string

Defined in: nodes/base/node.ts:584

Returns

string

Inherited from

ShapeNode.name


parent

Get Signature

get parent(): Node<NodeProps> | null

Defined in: nodes/base/node.ts:270

Returns

Node<NodeProps> | null

Inherited from

ShapeNode.parent


properties

Get Signature

get properties(): P

Defined in: nodes/base/node.ts:580

Returns

P

Inherited from

ShapeNode.properties


topCenter

Get Signature

get topCenter(): Vector2

Defined in: nodes/base/node.ts:1259

Returns

Vector2

Inherited from

ShapeNode.topCenter


topLeft

Get Signature

get topLeft(): Vector2

Defined in: nodes/base/node.ts:1239

Returns

Vector2

Inherited from

ShapeNode.topLeft


topRight

Get Signature

get topRight(): Vector2

Defined in: nodes/base/node.ts:1244

Returns

Vector2

Inherited from

ShapeNode.topRight

Methods

_cameraScope()

_cameraScope(): CameraScope

Defined in: nodes/layout/camera-node.ts:143

Internal

Returns

CameraScope

Overrides

ShapeNode._cameraScope


_confinesChildren()

_confinesChildren(): boolean

Defined in: nodes/base/node.ts:1606

Internal

Returns

boolean

Inherited from

ShapeNode._confinesChildren


_hitTestSelf()

_hitTestSelf(local, tolerance): boolean

Defined in: nodes/base/node.ts:1661

Internal

Dispatch seam so node-picking.ts can reach the protected override.

Parameters

local

Vector2

tolerance

number

Returns

boolean

Inherited from

ShapeNode._hitTestSelf


_localBounds()

_localBounds(): BoxBounds

Defined in: nodes/base/node.ts:1656

Internal

Returns

BoxBounds

Inherited from

ShapeNode._localBounds


_localMatrix()

_localMatrix(): Matrix2D

Defined in: nodes/base/node.ts:1293

Internal

Composed with the camera scopes in between by runtime/node-picking.ts.

Returns

Matrix2D

Inherited from

ShapeNode._localMatrix


_prepareStep()

_prepareStep(to, duration, easing?): TweenStepper

Defined in: nodes/base/node.ts:617

Resolve a single to() step into a flat TweenStepper — all the per-key setup (anchor handling, mapper, numeric-vs-custom routing) happens once here, then advance(dt) is allocation-free. Used by both the generator path (_toGen) and the batched parallel path.

Parameters

to

Partial<P>

duration

number

easing?

EasingFunction

Returns

TweenStepper

Inherited from

ShapeNode._prepareStep


_sampleMotion()

protected _sampleMotion(): void

Defined in: nodes/base/node.ts:1514

Compute this frame's motion (velocity/direction/speed/angular/scale) into _renderState as a backward difference against the previous frame, and roll the history forward. Velocity is 0/{0,0} when no trustworthy delta exists — the first frame, or after a non-monotonic time jump (only 0 < dt <= MAX is trusted, so a scrub that resets the clock reads as "unknown" rather than a spurious huge velocity). The world position matches applyTransform (layoutRect + x, layoutRect - y, y-down). Called via sample every frame; layout-dependent fields (rects/elapsed) are filled in by beforeRender at draw time.

Returns

void

Inherited from

ShapeNode._sampleMotion


_spaceRects()

protected _spaceRects(): SpaceRects

Defined in: nodes/base/node.ts:1777

Reference rects for fills with space:'parent', expressed in this node's local space (origin = this node's positioned centre, y-down to match the canvas). The viewport (space:'global') is resolved by the renderer, which knows the surface size. Rotation/scale of this node are not folded in — the rect is the axis-aligned parent box, which is what gradients expect.

Returns

SpaceRects

Inherited from

ShapeNode._spaceRects


_toGen()

_toGen(to, duration, easing?): FrameGenerator

Defined in: nodes/base/node.ts:697

Parameters

to

Partial<P>

duration

number

easing?

EasingFunction

Returns

FrameGenerator

Inherited from

ShapeNode._toGen


_writeProp()

_writeProp(field, value): void

Defined in: nodes/base/node.ts:567

Internal

Hot-path prop write (mapper- and binding-aware). Public-but-underscored like _toGen/_prepareStep so reactive companions in this directory can call it; not part of the authoring surface.

Parameters

field

string

value

unknown

Returns

void

Inherited from

ShapeNode._writeProp


add()

add(child): void

Defined in: nodes/base/node.ts:1398

Compose this node's internal children — the constructor-friendly entry point a custom composite calls to build its own subtree (a single node or an array, JSX included). Sugar over addChild/addChildren: it works the same before the node is linked into the tree (in the constructor) as after, so a composite builds its structure from props right in its constructor — no init-style hook, no idempotency guard, since the constructor runs once.

Accepts the same shape as the children prop — a single node, or an arbitrarily-nested array (.flat(Infinity)), with non-Node entries (false/null/undefined from cond && <Node/>) filtered out — so this.add(items.map(...)) or this.add(cond && <Text/>) work directly.

Parameters

child

NodeChildren

Returns

void

Example

constructor(props?) {
  super(props);
  this.add(<Rect ref={this.rowRef} group="row">{…}</Rect>);
}

Inherited from

ShapeNode.add


addChild()

addChild(child): void

Defined in: nodes/base/node.ts:1408

Parameters

child

Node

Returns

void

Inherited from

ShapeNode.addChild


addChildAt()

Call Signature

addChildAt(child, index): void

Defined in: nodes/base/node.ts:1437

Parameters
child

Node

index

number

Returns

void

Inherited from

ShapeNode.addChildAt

Call Signature

addChildAt(child, index, duration, easing?): FrameGenerator

Defined in: nodes/base/node.ts:1438

Parameters
child

Node

index

number

duration

number

easing?

EasingFunction

Returns

FrameGenerator

Inherited from

ShapeNode.addChildAt


addChildren()

addChildren(children): void

Defined in: nodes/base/node.ts:1424

Parameters

children

Node<NodeProps>[]

Returns

void

Inherited from

ShapeNode.addChildren


adoptDetached()

protected adoptDetached(node): void

Defined in: nodes/base/node.ts:1105

Adopt a detached node for binding only — its asset catalog, inherited context and clock — without making it a child.

Tree membership supplies three things a node cannot work without: the asset catalog (a webfont never shapes and an <Image> never loads without it), the resolved context map (theme tokens), and a ticking clock. Layout and painting are not among them. So a node used purely as a source of pixels — a Tex.surface(...) subtree rasterized onto 3D geometry — can be bound by whatever consumes it and laid out on demand, instead of having to sit in a particular place in the tree.

Safe to call every frame: bindAssets short-circuits on an unchanged catalog, resolveContext is fired only on the adoptee's first bind, and ellapse is idempotent for a repeated time.

Parameters

node

Node

Returns

void

Inherited from

ShapeNode.adoptDetached


afterRender()

afterRender(ctx): void

Defined in: nodes/base/node.ts:1781

Parameters

ctx

RenderContext

Returns

void

Inherited from

ShapeNode.afterRender


applyClip()

protected applyClip(ctx): boolean

Defined in: nodes/base/node.ts:1681

Open clipSelf()'s outline as a clip scope, confining whatever is drawn until the matching ctx.endClip() to the shape. Returns true when a clip was actually opened (so the caller knows to close it) and false when the node has no outline (the default).

Parameters

ctx

RenderContext

Returns

boolean

Inherited from

ShapeNode.applyClip


applyDefaultSize()

protected applyDefaultSize(props?): void

Defined in: nodes/base/node.ts:492

Figma-style smart default for width/height: hug-to-content when the node is given children, fill-the-parent when it's empty — so a plain new Rect({ children: [...] }) shrink-wraps like a Figma auto-layout frame, while an empty one behaves like a background/spacer. Called once from the constructor (skipped when flex is set, since that already implies 'fill'), so it's the baseline every Node gets for free.

Subclasses with their own sizing convention (Text hugs single-line text but fills when wrapping/autofit; Path/RichText always hug; FlexNode always hugs) override this — typically a one-line replacement — instead of duplicating the children-check in their constructor.

Parameters

props?

NodeConfig<any, CameraProps>

Returns

void

Inherited from

ShapeNode.applyDefaultSize


applyProp()

protected applyProp<Ext, Int>(field, initial, options?): void

Defined in: nodes/base/node.ts:558

Declare a reactive prop on this node. Creates a Signal-backed accessor for field, applies an initial value (callback → reactive binding; otherwise constant), and registers optional tween/mapper metadata used by set() and to().

Subsequent calls for the same field reuse the existing cell and act as a value assignment, so subclasses can override a parent's default by calling applyProp again without losing the cell or its bindings.

Type Parameters

Ext

Ext

Int

Int = Ext

Parameters

field

string

initial

Ext | (() => Ext) | undefined

options?

PropOptions<Ext, Int>

Returns

void

Inherited from

ShapeNode.applyProp


applyTransform()

protected applyTransform(ctx): void

Defined in: nodes/base/node.ts:1524

Push this node's transform (position, scale, rotate, opacity, effects).

Parameters

ctx

RenderContext

Returns

void

Inherited from

ShapeNode.applyTransform


beforeRender()

beforeRender(ctx): void

Defined in: nodes/base/node.ts:1757

Parameters

ctx

RenderContext

Returns

void

Inherited from

ShapeNode.beforeRender


bindAssets()

bindAssets(context): void

Defined in: nodes/base/node.ts:1011

Parameters

context

AssetCatalog

Returns

void

Inherited from

ShapeNode.bindAssets


bindContext()

bindContext(parent, runResolve): void

Defined in: nodes/base/node.ts:1074

Push inherited context down this subtree, mirroring bindAssets.

runResolve separates the two responsibilities the walk has:

  • true (first bind of this instance / a freshly-added child): also invoke resolveContext, which applies inherited context values to the already-built structure. It runs once per instance (the runtime rebuilds rather than replaying), so it must not depend on being re-fired.
  • false (per-frame structural re-push): only refresh _context so subtrees added this frame inherit it — must not re-fire resolveContext, which would clobber an in-flight tween's value every frame.

Parameters

parent

ContextMap

runResolve

boolean

Returns

void

Inherited from

ShapeNode.bindContext


clearChildren()

clearChildren(): void

Defined in: nodes/base/node.ts:1432

Returns

void

Inherited from

ShapeNode.clearChildren


clipPathSelf()

protected clipPathSelf(): Clip | null

Defined in: nodes/base/node.ts:1673

An optional clip path that cuts through this node's own content and its children — unlike clip, which only confines children to the node's outline and leaves the node's own fill/stroke untouched. Returning null (the default) applies no such cut. Media nodes (Image, Video) expose this as an author-facing clipPath prop so a path can carve the painted frame and everything stacked on it as one.

Returns

Clip | null

Inherited from

ShapeNode.clipPathSelf


clipSelf()

protected clipSelf(): Clip

Defined in: nodes/layout/camera-node.ts:119

This node's outline as a Clip command list — the single source of truth for every clip the node needs: its clip boundary (when clip is true) and the silhouette its backdrop effects (backdrop-flagged filters, magnify) are confined to. Returning null (the default) means the node has no clip outline, so its children render unclipped and it gets no backdrop effects. Nodes with a definite box (shapes via ShapeNode, layout containers like FlexNode) override this to describe their geometry — and so behave the same way for clip and effect area.

Returns

Clip

Overrides

ShapeNode.clipSelf


dispose()

dispose(): void

Defined in: nodes/base/node.ts:1912

Returns

void

Inherited from

ShapeNode.dispose


ellapse()

ellapse(totalTime): void

Defined in: nodes/base/node.ts:974

Parameters

totalTime

number

Returns

void

Inherited from

ShapeNode.ellapse


fadeTo()

fadeTo(opacity, duration, ease?): FrameGenerator

Defined in: nodes/base/node.ts:747

Animate opacity to the target value.

Parameters

opacity

number

Target opacity in the range [0, 1].

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* node.fadeTo(0, 0.3);   // fade out
yield* node.fadeTo(1, 0.3);   // fade in

Inherited from

ShapeNode.fadeTo


fillTo()

fillTo(to, duration, options?): FrameGenerator

Defined in: nodes/geometry/shape-node.ts:137

Parameters

to

Fill

duration

number

options?

TweenOptions<FillResolved[]>

Returns

FrameGenerator

Inherited from

ShapeNode.fillTo


headingTo()

headingTo(heading, duration, ease?): FrameGenerator

Defined in: nodes/layout/camera-node.ts:96

Animate the view rotation (heading) in degrees (clockwise).

Parameters

heading

number

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* camera.headingTo(45, 0.4);

hitTestSelf()

protected hitTestSelf(local, tolerance): boolean

Defined in: nodes/geometry/shape-node.ts:131

Shapes hit on their outline, not their box: a click in the empty corner of a star's bounding box should fall through to whatever is behind it. The outline is the very one this node already declares for clipping (Node.clipSelf), so what is grabbable and what is drawn can never drift. Shapes that declare no outline (Text, RichText, Path) keep the base box test, which is what selection should do for them anyway.

Parameters

local

Vector2

tolerance

number

Returns

boolean

Inherited from

ShapeNode.hitTestSelf


isAutoSize()

isAutoSize(axis): boolean

Defined in: nodes/base/node.ts:1365

Parameters

axis

"width" | "height"

Returns

boolean

Inherited from

ShapeNode.isAutoSize


layout()

layout(rect, scope): void

Defined in: nodes/base/node.ts:1810

Default layout: record rect, then stack-layout children (see layoutChildren). This is what makes a plain Node — and any ShapeNode leaf (Ellipse, Polygon, …) that doesn't override layout — able to nest children out of the box, the same way Image (via Rect) does, just with simple centered stacking instead of flex/stack. Subclasses with their own child-layout (Rect, MaskGroup, Camera, BooleanGroup) override this and call setLayoutRect instead, so children aren't laid out twice.

Parameters

rect

BoxBounds

scope

MeasureScope

Returns

void

Inherited from

ShapeNode.layout


layoutChildren()

protected layoutChildren(rect, scope): void

Defined in: nodes/base/node.ts:1824

Stack-layout this node's children, centered within rect's content area: each child is measured against the padded inner box and given a BoxBounds centered on it (sized to its own measured size, capped to the content area), offsetting from center via its own x/y. Called by the default layout; nodes that run their own child-layout (Rect's flex/stack, Camera's viewport, …) override layout instead and don't call this.

Parameters

rect

BoxBounds

scope

MeasureScope

Returns

void

Inherited from

ShapeNode.layoutChildren


measure()

measure(constraints, scope): Partial<Size2D>

Defined in: nodes/base/node.ts:1841

Default measure: resolve width/height, hugging children stack-style on any "hug" axis. A "hug" axis shrink-wraps to the largest child extent on that axis (children overlap and are centered — they don't sum), plus this node's padding — the same content size layoutChildren lays them out in. A fixed or "fill" axis resolves as before.

This is what lets a plain Node — and any ShapeNode leaf (Ellipse, Polygon, Camera, …) that doesn't override measure — hug its children out of the box, matching how Rect's "stack" mode measures rather than collapsing to 0 (which resolving "hug" against a content size of 0 used to do, so a hugging non-Rect container rendered nothing).

Parameters

constraints

SizeConstraints

scope

MeasureScope

Returns

Partial<Size2D>

Inherited from

ShapeNode.measure


moveTo()

moveTo(x, y, duration, ease?): FrameGenerator

Defined in: nodes/base/node.ts:715

Animate both x and y to the given position.

Parameters

x

number

y

number

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* node.moveTo(200, 100, 0.5, ease.outCubic);

Inherited from

ShapeNode.moveTo


moveX()

moveX(x, duration, ease?): FrameGenerator

Defined in: nodes/base/node.ts:725

Animate only the horizontal position (x).

Parameters

x

number

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* node.moveX(300, 0.4);

Inherited from

ShapeNode.moveX


moveY()

moveY(y, duration, ease?): FrameGenerator

Defined in: nodes/base/node.ts:735

Animate only the vertical position (y).

Parameters

y

number

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* node.moveY(-50, 0.4);

Inherited from

ShapeNode.moveY


onRender()

onRender(ctx): void

Defined in: nodes/base/node.ts:1731

Parameters

ctx

RenderContext

Returns

void

Inherited from

ShapeNode.onRender


overlayTo()

overlayTo(to, duration, options?): FrameGenerator

Defined in: nodes/geometry/shape-node.ts:148

Parameters

to

Fill

duration

number

options?

TweenOptions<FillResolved[]>

Returns

FrameGenerator

Inherited from

ShapeNode.overlayTo


panTo()

panTo(lookAt, duration, ease?): FrameGenerator

Defined in: nodes/layout/camera-node.ts:86

Pan the camera — animate lookAt, the world-space point that maps to the centre of the viewport.

Parameters

lookAt

Vector2

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* camera.panTo({ x: 200, y: -100 }, 0.6, ease.inOutQuad);

prepareAudio()

prepareAudio(_tracker): void

Defined in: nodes/base/node.ts:1197

Register this node's audio scheduling needs on the timeline — the one asset concern that's neither drawable (like images/video/paint, inferred via TrackRenderContext) nor a simple async load (see prepareLayout): a playing clip has to be declared into the frame-ranged timeline AssetManager/AudioDevice use to keep audio in sync while scrubbing. No-op by default; Video overrides it.

Parameters

_tracker

AssetTracker

Returns

void

Inherited from

ShapeNode.prepareAudio


prepareAudioAssets()

prepareAudioAssets(tracker, path?): void

Defined in: nodes/base/node.ts:1207

Walk the subtree registering each node's audio requests (see prepareAudio). Stamps the owning node's structural path onto any audio requests emitted, so the timeline can draw each clip on its own bar — purely for display, playback ignores ownerPath.

Parameters

tracker

AssetTracker

path?

string = ""

Returns

void

Inherited from

ShapeNode.prepareAudioAssets


prepareLayout()

prepareLayout(): void | Promise<void | Disposer>

Defined in: nodes/base/node.ts:1130

Opaque async setup needed before layout — e.g. Code's syntax grammar, which tokenization/measurement depends on. Runs in the precomp pass ahead of layout, so the node cannot read its layoutRect here (it hasn't been laid out yet). Image/video/paint and font requests are no longer declared here — they're inferred automatically from the same render()/layout() calls a node already makes (see TrackRenderContext/TrackMeasureScope). No-op by default.

The framework does not await the returned promise inline (precomp stays fully synchronous) — it's fired once per frame and, when nothing changed, should return synchronously (void). Memoize like Video's syncVideo() does: key off whatever prop drives the async work and skip re-running when the key is unchanged. When the promise resolves to a Disposer, it replaces (and disposes) any previous one for this node+phase, and runs when this node is disposed.

Returns

void | Promise<void | Disposer>

Inherited from

ShapeNode.prepareLayout


prepareLayoutAssets()

prepareLayoutAssets(): void

Defined in: nodes/base/node.ts:1154

Walk the subtree firing each node's pre-layout async setup (see prepareLayout). Fire-and-forget: does not block precomp's synchronous per-frame pass.

Returns

void

Inherited from

ShapeNode.prepareLayoutAssets


prepareRender()

prepareRender(): void | Promise<void | Disposer>

Defined in: nodes/base/node.ts:1141

Opaque async setup needed before render, with the node's layoutRect available (runs after layout). No-op by default — no built-in node currently needs this timing, but it's kept symmetric with prepareLayout for custom nodes whose async setup depends on knowing their rendered size. See prepareLayout for the contract.

Returns

void | Promise<void | Disposer>

Inherited from

ShapeNode.prepareRender


prepareRenderAssets()

prepareRenderAssets(): void

Defined in: nodes/base/node.ts:1174

Walk the subtree firing each node's pre-render async setup (see prepareRender). Fire-and-forget: does not block precomp's synchronous per-frame pass.

Returns

void

Inherited from

ShapeNode.prepareRenderAssets


provideContext()

protected provideContext(parent): ContextMap

Defined in: nodes/base/node.ts:1058

Providers override this to attach their token(s) to the ContextMap handed to descendants. Base passes the parent's map through unchanged.

Parameters

parent

ContextMap

Returns

ContextMap

Inherited from

ShapeNode.provideContext


reinit()

reinit(force?): void

Defined in: nodes/base/node.ts:544

Public entry point to reinitProps. A Scene owns its root node by composition (it no longer is a node), so it can't reach the protected reinitProps directly — it calls this on its root before a rebuild to restore default-baseline signals after a prior dispose, and with force to also reset live-but-tweened props back to their defaults.

Parameters

force?

boolean = false

Returns

void

Inherited from

ShapeNode.reinit


reinitProps()

protected reinitProps(force?): void

Defined in: nodes/base/node.ts:532

Re-create this node's reactive signals from their

Parameters

force?

boolean = false

Returns

void

Inherited from

ShapeNode.reinitProps


removeChild()

removeChild(child): Node<NodeProps> | null

Defined in: nodes/base/node.ts:1416

Parameters

child

Node

Returns

Node<NodeProps> | null

Inherited from

ShapeNode.removeChild


removeChildAt()

Call Signature

removeChildAt(index): Node<NodeProps> | null

Defined in: nodes/base/node.ts:1451

Parameters
index

number

Returns

Node<NodeProps> | null

Inherited from

ShapeNode.removeChildAt

Call Signature

removeChildAt(index, duration, easing?): FrameGenerator

Defined in: nodes/base/node.ts:1452

Parameters
index

number

duration

number

easing?

EasingFunction

Returns

FrameGenerator

Inherited from

ShapeNode.removeChildAt


render()

render(ctx): void

Defined in: nodes/base/node.ts:1785

Parameters

ctx

RenderContext

Returns

void

Inherited from

ShapeNode.render


renderChildren()

renderChildren(ctx): void

Defined in: nodes/layout/camera-node.ts:149

Parameters

ctx

RenderContext

Returns

void

Overrides

ShapeNode.renderChildren


renderContentWithEffects()

protected renderContentWithEffects(ctx, body): void

Defined in: nodes/base/node.ts:1726

Run body (this node's own painting + children) inside the node's effect and clip-path scopes — the shared content-rendering envelope every node uses so effects behave identically regardless of how a node draws. The caller is expected to have already pushed the node's transform (applyTransform). The envelope, outermost-first:

  1. applyBackdropEffects — filters/warps the backdrop beneath the node, confined to its clipSelf silhouette.
  2. A foreground effect scope (posterize wrapping bulge) capturing everything body paints, so those shader effects warp/band the lot.
  3. A clipPathSelf clip cutting through both the node's own paint and its children.

Nodes with a bespoke onRender (boolean, mask, …) call this with their custom body to gain the same effect support as a standard shape, instead of duplicating the scope bookkeeping.

Parameters

ctx

RenderContext

body

() => void

Returns

void

Inherited from

ShapeNode.renderContentWithEffects


renderOverlay()

protected renderOverlay(ctx): void

Defined in: nodes/geometry/shape-node.ts:108

Paint the node's overlay layer — over its own fill and its children, but under the stroke — clipped to the node's silhouette. Called from onRender after children render and before renderStroke. No-op by default; ShapeNode paints the resolved overlay as a fill of its silhouette so a texture (e.g. VHS grain) sits over the whole subtree.

Parameters

ctx

RenderContext

Returns

void

Inherited from

ShapeNode.renderOverlay


renderSelf()

protected renderSelf(draw): void

Defined in: nodes/layout/camera-node.ts:115

Hook for custom nodes that draw their own content (raw Graphics commands, etc.) without subclassing ShapeNode. Called from onRender between the transform push and the children render, the same slot ShapeNode.renderSelf occupies. No-op by default — drawing nothing here doesn't change the render flow at all.

Parameters

draw

RenderContext

Returns

void

Overrides

ShapeNode.renderSelf


renderStroke()

protected renderStroke(ctx): void

Defined in: nodes/geometry/shape-node.ts:116

Paint the node's stroke last — over its fill, children, and overlay. Deferred out of renderSelf (which now draws only shadow+fill) so the stroke frames the whole subtree and sits above any overlay. Called from onRender after renderOverlay. No-op by default; ShapeNode strokes its silhouette.

Parameters

ctx

RenderContext

Returns

void

Inherited from

ShapeNode.renderStroke


reparent()

Call Signature

reparent(newParent): void

Defined in: nodes/base/node.ts:1886

Parameters
newParent

Node

Returns

void

Inherited from

ShapeNode.reparent

Call Signature

reparent(newParent, duration, easing?): FrameGenerator

Defined in: nodes/base/node.ts:1887

Parameters
newParent

Node

duration

number

easing?

EasingFunction

Returns

FrameGenerator

Inherited from

ShapeNode.reparent


resolveContext()

protected resolveContext(_ctx): void

Defined in: nodes/base/node.ts:1052

Hook for applying inherited context values to this node, once, after the node is linked into the tree and the context walk has resolved its ancestors' providers — the first moment useContext returns real values (the constructor runs before the node is linked, so it can't read context).

Runs exactly once per node instance: the runtime rebuilds the subtree on every reset/scrub/precomp rather than replaying this hook, so there is no "each pass" re-entry to guard against — never call clearChildren or write idempotency ceremony here.

Composition rule

Structure (which children exist, and how many) is built in the constructor via add from props — never here, and never from context. This hook applies context-derived values only: read the resolved value from ctx (or useContext) and write it onto the already-built structure, typically through refs captured in the constructor.

Parameters

_ctx

ContextMap

Returns

void

Example

// constructor: this.add(<Rect ref={this.accent} … />)   // structure from props
protected override resolveContext(ctx: ContextMap): void {
  this.accent().set({ fill: ctx.get(ThemeToken).accent }); // value from context
}

Inherited from

ShapeNode.resolveContext


resolveSizeInput()

resolveSizeInput(sizeInput, availableSize, childrenSize): number

Defined in: nodes/base/node.ts:1369

Parameters

sizeInput

SizeInput

availableSize

number

childrenSize

number

Returns

number

Inherited from

ShapeNode.resolveSizeInput


restore()

Call Signature

restore(): void

Defined in: nodes/base/node.ts:945

Pop the most recent save snapshot and roll this node back to it.

Called with no duration (or 0), every prop is reapplied instantly — plain values are set, reactive bindings are re-bound. Called with a positive duration, the numeric props (and any with a custom tween) animate toward their saved values over that many seconds; once the tween finishes the full snapshot is reapplied, which re-binds any reactive props and snaps non-tweenable props (e.g. strings) to their saved values.

A no-op (returns immediately) if there is nothing on the stack.

Returns

void

Inherited from

ShapeNode.restore

Call Signature

restore(duration, easing?): FrameGenerator

Defined in: nodes/base/node.ts:946

Pop the most recent save snapshot and roll this node back to it.

Called with no duration (or 0), every prop is reapplied instantly — plain values are set, reactive bindings are re-bound. Called with a positive duration, the numeric props (and any with a custom tween) animate toward their saved values over that many seconds; once the tween finishes the full snapshot is reapplied, which re-binds any reactive props and snaps non-tweenable props (e.g. strings) to their saved values.

A no-op (returns immediately) if there is nothing on the stack.

Parameters
duration

number

Seconds to animate the rollback over. Omit for an instant restore.

easing?

EasingFunction

Optional easing for the animated restore.

Returns

FrameGenerator

Inherited from

ShapeNode.restore


rotateTo()

rotateTo(rotation, duration, ease?): FrameGenerator

Defined in: nodes/base/node.ts:757

Animate rotate to the target angle (degrees, clockwise).

Parameters

rotation

number

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* node.rotateTo(180, 0.6, ease.inOutQuad);

Inherited from

ShapeNode.rotateTo


sample()

sample(): void

Defined in: nodes/base/node.ts:999

Per-frame sampling of derived render state (currently motion). Recurses to children so the whole subtree is sampled in one pass. Called from ellapse every frame; kept as a named seam so the priming path can seed the same state without a full ellapse (see StateEvaluator.resetSlot).

Returns

void

Inherited from

ShapeNode.sample


save()

save(): void

Defined in: nodes/base/node.ts:926

Push a snapshot of this node's current state onto its save stack.

Every reactive prop (x, y, scale, opacity, fill, …) is captured, preserving reactive bindings — a prop bound to () => other().x is saved as the binding, not just its resolved value, so restore re-binds it rather than freezing the value. Calls stack: each save() pushes a new layer, and each restore pops the most recent one.

Returns

void

Example

node.save();
yield* node.moveTo(200, 0, 1);
yield* node.restore(1);   // animate back to where it was saved

Inherited from

ShapeNode.save


scaleTo()

scaleTo(scale, duration, ease?): FrameGenerator

Defined in: nodes/base/node.ts:768

Animate scale to the target factor.

Parameters

scale

number

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* node.scaleTo(1.5, 0.4);   // grow
yield* node.scaleTo(0,   0.3);   // shrink to nothing

Inherited from

ShapeNode.scaleTo


set()

set(props): void

Defined in: nodes/base/node.ts:588

Parameters

props
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))

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.

cornerRadius?

RectCornerRadius | (() => RectCornerRadius)

Corner radius in pixels — uniform, per-corner, or per-axis.

cornerStyle?

RectCornerStyle | (() => RectCornerStyle)

How each corner is shaped once it has a radius: 'rounded' or 'angled'.

effects?

Effect | (() => Effect)

end?

number | (() => number | undefined)

fill?

Fill | (() => Fill | undefined)

Fill layer(s). Each item can be:

  • A plain CSS color string → treated as a solid fill
  • A fill prop object (SolidFillProp, LinearGradientFillProp, …)
  • An already-resolved fill object
  • A FillChain from the Fills builder (e.g. Fills.color('red'))
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'.

heading?

number | (() => number)

Rotation of the camera view in degrees (clockwise).

height?

SizeInput | (() => SizeInput)

lookAt?

Vector2 | (() => Vector2)

World-space point that maps to the centre of the camera viewport — what the camera is pointed at. Same name and meaning as Graphics3D.perspective({ lookAt }), so a 2D and a 3D camera are aimed with the same word.

opacity?

number | (() => number)

overlay?

Fill | (() => Fill | undefined)

Overlay layer(s) — the same loose values as fill, but painted over this node's fill and its children (clipped to the node's silhouette) while still sitting under the stroke. Use for textures laid across the whole subtree, e.g. a VHS-grain image or video.

padding?

Insets | (() => Insets)

Inner spacing between this node's edges and its content/children.

pivot?

Anchor | (() => Anchor)

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.

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.

shadow?

Shadow | (() => Shadow | undefined)

Shadow layer(s): a single ShadowProp, an array of them, or an already-resolved shadow. fill inside each shadow accepts the same loose values as the top-level fill prop.

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/heightsize: 'fill', size: () => ..., or node.to({ size: 300 }, 0.5) are all valid.

start?

number | (() => number | undefined)

stroke?

Stroke | (() => Stroke | undefined)

Stroke layer(s): a single StrokeProp, an array of them, or an already-resolved stroke. fill inside each stroke accepts the same loose values as the top-level fill prop.

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)

Magnification factor. Values > 1 zoom in; < 1 zoom out.

Returns

void

Inherited from

ShapeNode.set


setLayoutRect()

protected setLayoutRect(rect): void

Defined in: nodes/base/node.ts:1796

Record this node's allocated bounds without touching children. Used by subclasses that run their own child-layout pass (e.g. Rect's flex/stack) and so skip layoutChildren.

Parameters

rect

BoxBounds

Returns

void

Inherited from

ShapeNode.setLayoutRect


shadowTo()

shadowTo(to, duration, options?): FrameGenerator

Defined in: nodes/geometry/shape-node.ts:170

Parameters

to

Shadow

duration

number

options?

TweenOptions<ShadowResolved[]>

Returns

FrameGenerator

Inherited from

ShapeNode.shadowTo


shapeGraphics()

protected shapeGraphics(): Graphics

Defined in: nodes/layout/camera-node.ts:102

The node's bare silhouette as a Graphics with no paint ops. renderSelf appends shadow + fill; renderOverlay appends the overlay fill; renderStroke appends the stroke. Sharing one builder keeps each shape's geometry defined in a single place.

Returns null for nodes that have no single fillable silhouette (text, boolean groups, grids) — those override the paint hooks themselves or opt out of the generic overlay/stroke passes.

Returns

Graphics

Overrides

ShapeNode.shapeGraphics


strokeTo()

strokeTo(to, duration, options?): FrameGenerator

Defined in: nodes/geometry/shape-node.ts:159

Parameters

to

Stroke

duration

number

options?

TweenOptions<StrokeResolved[]>

Returns

FrameGenerator

Inherited from

ShapeNode.strokeTo


tick()

tick(_globalTime): void

Defined in: nodes/base/node.ts:965

Parameters

_globalTime

number

Returns

void

Inherited from

ShapeNode.tick


to()

to(to, duration, easing?): AnimationBuilder<CameraProps>

Defined in: nodes/base/node.ts:607

Parameters

to

Partial<P>

duration

number

easing?

EasingFunction

Returns

AnimationBuilder<CameraProps>

Inherited from

ShapeNode.to


tryAssets()

protected tryAssets(): AssetCatalog | null

Defined in: nodes/base/node.ts:280

Returns the bound asset catalog, or null if this node hasn't been bound yet.

Returns

AssetCatalog | null

Inherited from

ShapeNode.tryAssets


useContext()

useContext<T>(ctx): T

Defined in: nodes/base/node.ts:301

Read the nearest ancestor provider's value for ctx (or its default).

Type Parameters

T

T

Parameters

ctx

Context<T>

Returns

T

Inherited from

ShapeNode.useContext


wiggle()

wiggle(amplitudes, duration, options?): FrameGenerator

Defined in: nodes/base/node.ts:831

Continuously jitter one or more numeric props around their current values for duration seconds, then settle them back exactly where they started.

The target reads like to — an object of prop → amplitude rather than prop → target — so you name props as typed object keys, never string arguments, and can jitter several at once: wiggle({ x: 8, rotation: 2 }, 0.6). Each value is the peak offset from that prop's base, in the prop's own units. Call-wide shaping (frequency, settle) goes in the trailing WiggleOptions bag, mirroring how TweenOptions bundles its knobs.

Unlike to(), which drives a prop to a target, wiggle adds an organic offset on top of a fixed base — each prop's value at the moment the generator starts. Offsets are drawn from this node's seeded random noise field, so they are correlated over time (nearby frames get nearby offsets) rather than the jagged jumps independent draws would give — the difference that makes it read as hand-held shake / drift rather than static. Because the source is seeded per node, the motion is reproducible across scrub / precomp / HMR out of the box.

The offset rides on each prop's stored numeric value, so raw props (x, rotation, …) and mapped props that resolve to a plain number both wiggle correctly. A prop whose stored value isn't a number — width: 'fill', or a per-corner cornerRadius object — has no scalar to offset, so it's skipped with a dev-time warning rather than producing NaN.

The bases are captured once, so wiggle composes: run it inside parallel alongside a to() on other props, or give sibling nodes distinct seeds (via the NodeProps.seed prop) so a crowd wiggles out of phase. Every prop's offset eases to zero over the final settle fraction so it lands back on its base without a visible snap.

Parameters

amplitudes

Map of prop → peak offset from its base, in the prop's own units. Same key shape as to's target ({ x, y, rotation, … }).

blend?

number

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?

number

bottomLeft?

number

bottomRight?

number

center?

number

centerLeft?

number

centerRight?

number

children?

number

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?

number

When true, content drawn outside this node's outline is clipped away (see Node.clipSelf).

colSpan?

number

How many grid columns this child spans. Default 1.

column?

number

1-based column index for explicit grid placement. Undefined = auto-placed.

cornerRadius?

number

Corner radius in pixels — uniform, per-corner, or per-axis.

cornerStyle?

number

How each corner is shaped once it has a radius: 'rounded' or 'angled'.

effects?

number

end?

number

fill?

number

Fill layer(s). Each item can be:

  • A plain CSS color string → treated as a solid fill
  • A fill prop object (SolidFillProp, LinearGradientFillProp, …)
  • An already-resolved fill object
  • A FillChain from the Fills builder (e.g. Fills.color('red'))
flex?

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'.

heading?

number

Rotation of the camera view in degrees (clockwise).

height?

number

lookAt?

number

World-space point that maps to the centre of the camera viewport — what the camera is pointed at. Same name and meaning as Graphics3D.perspective({ lookAt }), so a 2D and a 3D camera are aimed with the same word.

opacity?

number

overlay?

number

Overlay layer(s) — the same loose values as fill, but painted over this node's fill and its children (clipped to the node's silhouette) while still sitting under the stroke. Use for textures laid across the whole subtree, e.g. a VHS-grain image or video.

padding?

number

Inner spacing between this node's edges and its content/children.

pivot?

number

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.

rotation?

number

row?

number

1-based row index for explicit grid placement. Undefined = auto-placed.

rowSpan?

number

How many grid rows this child spans. Default 1.

scale?

number

seed?

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.

shadow?

number

Shadow layer(s): a single ShadowProp, an array of them, or an already-resolved shadow. fill inside each shadow accepts the same loose values as the top-level fill prop.

size?

number

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/heightsize: 'fill', size: () => ..., or node.to({ size: 300 }, 0.5) are all valid.

start?

number

stroke?

number

Stroke layer(s): a single StrokeProp, an array of them, or an already-resolved stroke. fill inside each stroke accepts the same loose values as the top-level fill prop.

topCenter?

number

topLeft?

number

topRight?

number

width?

number

x?

number

y?

number

zoom?

number

Magnification factor. Values > 1 zoom in; < 1 zoom out.

duration

number

Seconds to wiggle for. Pass Infinity inside a parallel for an endless jitter bounded by its siblings (no settle is applied to an infinite wiggle).

options?

WiggleOptions

Call-wide WiggleOptions: frequency (default 4) and settle. frequency applies to every prop; for a per-prop rate, use a second wiggle in the same parallel.

Returns

FrameGenerator

Examples

// Shake horizontally for a beat, then rest exactly where it began:
yield* node.wiggle({ x: 8 }, 0.6);
// A faster shake with a hard cut (no ease-out) at the end:
yield* node.wiggle({ x: 12, y: 12 }, 1, { frequency: 8, settle: 0 });
// Hand-held drift while it moves across (offset composes with the move):
yield* parallel(
  node.moveX(400, 2),
  node.wiggle({ y: 6, rotation: 2 }, 2, { frequency: 3 }),
);

Inherited from

ShapeNode.wiggle


worldMatrix()

protected worldMatrix(): Matrix2D

Defined in: nodes/base/node.ts:1306

This node's full transform in canvas (y-down) world space — the product of every ancestor's local matrix from the root down to this node. Reactive: walks the live parent chain and reads each node's transform signals.

Returns

Matrix2D

Inherited from

ShapeNode.worldMatrix


zoomTo()

zoomTo(zoom, duration, ease?): FrameGenerator

Defined in: nodes/layout/camera-node.ts:75

Animate the magnification factor (zoom). Values > 1 zoom in; < 1 zoom out.

Parameters

zoom

number

duration

number

ease?

EasingFunction

Returns

FrameGenerator

Example

yield* camera.zoomTo(2, 0.5, ease.outCubic);

flattenChildrenProp()

protected static flattenChildrenProp(props): Node<NodeProps>[]

Defined in: nodes/base/node.ts:462

Flatten a constructor's raw children prop into the Node instances it contains, without mutating or adding them — the same normalisation the constructor applies before addChildren, exposed standalone so applyDefaultSize overrides can inspect children's own resolved width/height before they're attached (JSX children are constructed, defaults and all, before being passed in as props).

Parameters

props

{ children?: unknown; } | undefined

Returns

Node<NodeProps>[]

Inherited from

ShapeNode.flattenChildrenProp


hasFillChild()

protected static hasFillChild(children, axis): boolean

Defined in: nodes/base/node.ts:475

True if any of children requests "fill" on axis — the signal a container's applyDefaultSize override uses to decide whether its own hug default on that axis would strand the child with no space to fill into (see Rect/FlexNode overrides).

Parameters

children

Node<NodeProps>[]

axis

"width" | "height"

Returns

boolean

Inherited from

ShapeNode.hasFillChild