Skip to content
MotionActor
Esc
↑↓navigate↵open⌘Jpreview
On this page

LayoutActor

The default base class for renderable actors — canonical layout, transform, appearance and item groups, plus measured geometry.

LayoutActor extends Actor with the groups every renderable thing needs. Declaring one gives you all of them.

class Badge extends LayoutActor {
  label = signal("Ready");
}

Canonical groups

badge.layout.x(); // LayoutValue: number | pct(n) | "50%"
badge.layout.y();
badge.layout.width();
badge.layout.height();

badge.transform.scale();
badge.transform.rotation();

badge.appearance.opacity();

badge.flexItem.alignSelf();
badge.gridItem.gridColumn();
badge.gridItem.gridRow();

Change the defaults by overriding layout with layoutGroup:

class Image extends LayoutActor {
  layout = layoutGroup({ width: 320, height: 180 });
}

Animating

yield* badge.layout.x.tween(100, 0.4);
yield* badge.layout.y.tween(200, 0.4);

yield* this.runtime.all(
  badge.layout.x.tween(100, 0.4),
  badge.layout.y.tween(200, 0.4),
);

Authored input vs resolved output

This distinction causes more confusion than any other part of the class.

Authored Resolved
Written by you the runtime
Accepts numbers, pct(n), "50%" —
Always numeric no yes
Read where anywhere resolution time
// Authored input — write here
actor.layout.x.set("50%");

// Resolved output — read only, always numeric
actor.localLayout(); // position relative to the parent
actor.worldLayout(); // position in world space
actor.bounds(); // currently aliases localLayout()

Percentages resolve against the containing block: the scene viewport for root actors, the nearest positioned ancestor’s local box for nested ones. Renderers size their element from resolved localLayout.

measuredBox

LayoutActor includes a built-in measuredBox host binding: the renderer publishes the actor’s actual rendered box, and the actor reads it back.

this.measuredBox(); // ResolvedLayoutBox | null

It is a recorded channel, so seeking backwards replays the measurement that was actually taken at that frame — and it is demand-gated, so nothing is measured unless something reads it.

Was this page helpful?