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

Vue

Paint scenes with Vue 3 through @motionactor/renderers/vue and @motionactor/dom/vue.

Scenes, actors and effects are the same under every binding. A Vue app changes two things: its renderers return VNodes, and it mounts through the /vue entries.

Package Vue entry
@motionactor/renderers /vue: SceneRenderer, renderers, composables, compositions, transitions, media
@motionactor/dom /vue: dom (the backend), DomHost, ActorElement, vStyle, effect stages
@motionactor/media /vue: views for Image, Video and Audio
@motionactor/engine /vue: mountVueComposition
@motionactor/hyperframes /vue: mountHyperframesComposition

A program loads one binding: importing /vue makes every RenderNode a VNode.

Renderers

A renderer returns a VNode from h. The registry calls it as a pure function, so it calls no composables; an actor whose view needs state renders a component.

import { class LayoutActor<TEvents extends ActorEventMap = {}>LayoutActor, 
function signal<T>(): RequiredSignal<T> (+1 overload)
module signal
A timeline value on an actor, and an input to every spawn of it. Without an initial value the signal is required: `ctx.spawn` must supply it.
signal
} from "@motionactor/core";
import {
const dom: StagedBackend<DefineComponent<ExtractPropTypes<{
    readonly actors: {
        readonly type: PropType<BackendHostProps["actors"]>;
        readonly required: true;
    };
    readonly state: {
        readonly type: PropType<BackendHostProps["state"]>;
        readonly required: true;
    };
    readonly frame: {
        readonly type: NumberConstructor;
        readonly required: true;
    };
    readonly compiled: {
        readonly type: PropType<BackendHostProps["compiled"]>;
        readonly required: true;
    };
    ... 4 more ...;
    readonly layer: {
        ...;
    };
}>, ... 18 more ..., any>, "dom", VNodeChild>
The Vue DOM backend: `DomHost`, the `Group` primitive, and the `domStyle` stage, as `dom` in Vue binding code: `dom.render(Box, …)`, `createRenderRuntime({ backends: [dom], renderers })`.
dom
, const vStyle: ObjectDirective<HTMLElement | SVGElement, StyleRecord, string, any>
`v-style`: writes a style record through `applyStyle`, so a patch sets only the declarations whose value moved, where Vue's `style` prop writes every key on every patch. The node's only style writer: an element takes `v-style` or `style`, never both. Writes before Vue inserts the node and at the point of each patch Vue would patch `style`; on the server it renders the record.
vStyle
} from "@motionactor/dom/vue";
import { const createRenderRuntime: (input: CreateRenderRuntimeInput<VueBackendHost, VNodeChild>) => VueRenderRuntime
The floor's `createRenderRuntime` for Vue: every backend's host is a Vue component and its stages wrap Vue nodes.
createRenderRuntime
} from "@motionactor/renderers/vue";
import { function h<K extends keyof HTMLElementTagNameMap>(type: K, children?: RawChildren): VNode (+22 overloads)h, function withDirectives<T extends VNode>(vnode: T, directives: DirectiveArguments): T
Adds directives to a VNode.
withDirectives
} from "vue";
export class class BadgeBadge extends class LayoutActor<TEvents extends ActorEventMap = {}>LayoutActor { Badge.label: ActorFieldSignal<string>label = signal<string>(initial: string): ActorFieldSignal<string> (+1 overload)
A timeline value on an actor, and an input to every spawn of it. Without an initial value the signal is required: `ctx.spawn` must supply it.
signal
("New");
Badge.hue: ActorFieldSignal<number>hue = signal<number>(initial: number): ActorFieldSignal<number> (+1 overload)
A timeline value on an actor, and an input to every spawn of it. Without an initial value the signal is required: `ctx.spawn` must supply it.
signal
(190);
} const const badge: BackendRendererDefinition<readonly [typeof Badge], "dom">badge =
const dom: StagedBackend<DefineComponent<ExtractPropTypes<{
    readonly actors: {
        readonly type: PropType<BackendHostProps["actors"]>;
        readonly required: true;
    };
    readonly state: {
        readonly type: PropType<BackendHostProps["state"]>;
        readonly required: true;
    };
    readonly frame: {
        readonly type: NumberConstructor;
        readonly required: true;
    };
    readonly compiled: {
        readonly type: PropType<BackendHostProps["compiled"]>;
        readonly required: true;
    };
    ... 4 more ...;
    readonly layer: {
        ...;
    };
}>, ... 18 more ..., any>, "dom", VNodeChild>
The Vue DOM backend: `DomHost`, the `Group` primitive, and the `domStyle` stage, as `dom` in Vue binding code: `dom.render(Box, …)`, `createRenderRuntime({ backends: [dom], renderers })`.
dom
.render: <typeof Badge>(blueprint: typeof Badge, render: ActorRendererForBlueprints<readonly [typeof Badge], "dom">, options?: ActorRendererRegistrationOptions) => BackendRendererDefinition<readonly [typeof Badge], "dom"> (+1 overload)render(class BadgeBadge, ({
actor: ResolvedActor & Omit<ResolvedActor, "signals" | "channels"> & {
    label: string;
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    hue: number;
} & {
    ...;
}
The actor. Reading it makes the renderer depend on all of it.
actor
}) =>
withDirectives<VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>>(vnode: VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>, directives: DirectiveArguments): VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>
Adds directives to a VNode.
withDirectives
(h<"span">(type: "span", children?: RawChildren): VNode (+22 overloads)h("span",
actor: ResolvedActor & Omit<ResolvedActor, "signals" | "channels"> & {
    label: string;
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    hue: number;
} & {
    ...;
}
The actor. Reading it makes the renderer depend on all of it.
actor
.
signals: Readonly<Record<string, unknown>> & {
    label: string;
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    hue: number;
}
signals
.label: stringlabel), [
[const vStyle: ObjectDirective<HTMLElement | SVGElement, StyleRecord, string, any>
`v-style`: writes a style record through `applyStyle`, so a patch sets only the declarations whose value moved, where Vue's `style` prop writes every key on every patch. The node's only style writer: an element takes `v-style` or `style`, never both. Writes before Vue inserts the node and at the point of each patch Vue would patch `style`; on the server it renders the record.
vStyle
, { padding: numberpadding: 8, background: stringbackground: `hsl(${
actor: ResolvedActor & Omit<ResolvedActor, "signals" | "channels"> & {
    label: string;
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    hue: number;
} & {
    ...;
}
The actor. Reading it makes the renderer depend on all of it.
actor
.
signals: Readonly<Record<string, unknown>> & {
    label: string;
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    hue: number;
}
signals
.hue: numberhue} 80% 45%)` }],
]), ); export const const runtime: VueRenderRuntimeruntime = function createRenderRuntime(input: CreateRenderRuntimeInput<VueBackendHost, VNodeChild>): VueRenderRuntime
The floor's `createRenderRuntime` for Vue: every backend's host is a Vue component and its stages wrap Vue nodes.
createRenderRuntime
({
backends: readonly AnyBackend<VueBackendHost, VNodeChild>[]backends: [
const dom: StagedBackend<DefineComponent<ExtractPropTypes<{
    readonly actors: {
        readonly type: PropType<BackendHostProps["actors"]>;
        readonly required: true;
    };
    readonly state: {
        readonly type: PropType<BackendHostProps["state"]>;
        readonly required: true;
    };
    readonly frame: {
        readonly type: NumberConstructor;
        readonly required: true;
    };
    readonly compiled: {
        readonly type: PropType<BackendHostProps["compiled"]>;
        readonly required: true;
    };
    ... 4 more ...;
    readonly layer: {
        ...;
    };
}>, ... 18 more ..., any>, "dom", VNodeChild>
The Vue DOM backend: `DomHost`, the `Group` primitive, and the `domStyle` stage, as `dom` in Vue binding code: `dom.render(Box, …)`, `createRenderRuntime({ backends: [dom], renderers })`.
dom
],
renderers?: readonly RendererRegistryEntry[] | undefined
Family and project renderers, for any backend. Each routes to the backend it names (`three.render(…)`); one naming a backend missing from `backends` throws.
renderers
: [const badge: BackendRendererDefinition<readonly [typeof Badge], "dom">badge],
});

A style that moves with the frame goes through v-style rather than style. Vue’s style patch writes every key of an object on each render; v-style writes only the declarations whose value changed, so on a frame where only hue moves the badge above sets background alone. Numbers take px as in React, and the server renders the record as a style attribute. An element takes one of v-style and style, never both. In an SFC that imports vStyle in <script setup>:

<span v-style="{ padding: 8, background: `hsl(${hue} 80% 45%)` }">{{ label }}</span>

A component behind a renderer may use useHold, useMotionactorFrame and the other composables; each reader returns a ref. A host that places its children in the browser’s flow returns renderChild(child, { flow }) for each one. The DOM backend measures a flow child while something reads its measuredBox.

Painting a scene

SceneRenderer resolves the frame and paints its layers. A composition’s render returns it as a VNode:

import { function createScene<TSceneExports, const I extends SceneInputs = Readonly<Record<never, SceneInput>>, const L extends SceneLayers = Readonly<Record<never, SceneLayer<BackendRef<string>>>>>(script: SceneScript<I, L, TSceneExports>, options?: SceneDefinitionOptions<I, L>): SceneDefinition<I, L, TSceneExports>
Declare a scene. Nothing compiles until a host builds it: `scene.build({ viewport, fps, inputs })` runs the script as `(ctx, inputs, viewport, layers)` and returns the compiled scene. `ctx.spawn` places a root actor in the default layer; `layers.<key>.spawn` places it in a declared one. `ctx.stage` stages another scene on this scene's clock, and a staged scene may stage again.
createScene
} from "@motionactor/core";
import { const defineComposition: DefineComposition<VueBackendHost, VNodeChild, VNodeChild>
A composition of a `createScene` definition (`scene`), painted by `render`, or by default by `SceneRenderer` over `background`.
defineComposition
,
const SceneRenderer: DefineComponent<ExtractPropTypes<{
    compiled: {
        type: PropType<CompiledScene<unknown>>;
        required: true;
    };
    frame: {
        type: NumberConstructor;
        required: true;
    };
    width: {
        type: NumberConstructor;
        required: true;
    };
    height: {
        type: NumberConstructor;
        required: true;
    };
    runtime: {
        type: PropType<VueRenderRuntime>;
        default: undefined;
    };
}>, () => VNode<RendererNode, RendererElement, {
    ...;
}>, ... 17 more ..., any>
Frame-passive renderer for a CompiledScene: resolves the frame and paints its layers on a stage of `width` by `height`. The default slot is page markup, rendered in the scope of the scene's DOM layer (`SceneLayers`), where `<actor.h1 :of="compiled.scene.card.title">` binds a node of it to an actor; `<InLayer :layer="compiled.layers.<key>">` places its own markup in another DOM layer.
SceneRenderer
,
} from "@motionactor/renderers/vue"; import { function h<K extends keyof HTMLElementTagNameMap>(type: K, children?: RawChildren): VNode (+22 overloads)h } from "vue"; import { class BadgeBadge, const runtime: VueRenderRuntimeruntime } from "./badge-renderers"; const
const scene: SceneDefinition<Readonly<Record<never, SceneInput>>, Readonly<Record<never, SceneLayer<BackendRef<string>>>>, {
    badge: Badge;
}>
scene
=
createScene<{
    badge: Badge;
}, Readonly<Record<never, SceneInput>>, Readonly<Record<never, SceneLayer<BackendRef<string>>>>>(script: SceneScript<Readonly<Record<never, SceneInput>>, Readonly<Record<never, SceneLayer<BackendRef<string>>>>, {
    badge: Badge;
}>, options?: SceneDefinitionOptions<Readonly<Record<never, SceneInput>>, Readonly<Record<never, SceneLayer<BackendRef<string>>>>> | undefined): SceneDefinition<...>
Declare a scene. Nothing compiles until a host builds it: `scene.build({ viewport, fps, inputs })` runs the script as `(ctx, inputs, viewport, layers)` and returns the compiled scene. `ctx.spawn` places a root actor in the default layer; `layers.<key>.spawn` places it in a declared one. `ctx.stage` stages another scene on this scene's clock, and a staged scene may stage again.
createScene
(function* (ctx: SceneContextctx) {
const const badge: Badgebadge = ctx: SceneContextctx.
CompileContext.spawn<Badge>(definition: ActorClass<Badge>, overrides?: {
    label?: SignalInputValue<string> | undefined;
    id?: undefined;
    localLayout?: undefined;
    worldLayout?: undefined;
    compositing?: {
        clip?: SignalInputValue<number | null> | undefined;
        isolate?: SignalInputValue<boolean> | undefined;
        blend?: SignalInputValue<"overlay" | "difference" | "hue" | "source-over" | "multiply" | "screen" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "saturation" | "color" | "luminosity" | "plus-lighter"> | undefined;
    } | undefined;
    ... 19 more ...;
    bounds?: undefined;
} | undefined, options?: {
    ...;
} | undefined): Badge (+1 overload)
spawn
(class BadgeBadge, { label?: SignalInputValue<string> | undefinedlabel: "Live" });
yield* const badge: Badgebadge.Badge.hue: ActorFieldSignal<number>hue.LiveSignal<number>.tween(target: number, options: number | SignalTweenOptions<number>): Generator<Frame, void, unknown>
Tween to target over authored seconds — must yield*
tween
(320, 1);
return { badge: Badgebadge }; }); export const
const badgeCard: CompositionDefinition<HostInputArgs<Readonly<Record<never, SceneInput>>>, {
    badge: Badge;
}, VueBackendHost, VNodeChild, VNodeChild>
badgeCard
=
defineComposition<SceneDefinition<Readonly<Record<never, SceneInput>>, Readonly<Record<never, SceneLayer<BackendRef<string>>>>, {
    badge: Badge;
}>>(definition: SceneCompositionInput<SceneDefinition<Readonly<Record<never, SceneInput>>, Readonly<Record<never, SceneLayer<BackendRef<string>>>>, {
    badge: Badge;
}>, VueBackendHost, VNodeChild, VNodeChild>): CompositionDefinition<...> (+1 overload)
`scene`'s inputs are the props.
defineComposition
({
id: stringid: "BadgeCard", width: numberwidth: 1280, height: numberheight: 720, fps: numberfps: 30, defaultProps?: HostInputArgs<Readonly<Record<never, SceneInput>>> | undefineddefaultProps: {}, runtime: RenderRuntime<VueBackendHost, VNodeChild>runtime,
scene: SceneDefinition<Readonly<Record<never, SceneInput>>, Readonly<Record<never, SceneLayer<BackendRef<string>>>>, {
    badge: Badge;
}>
scene
,
render?(args: CompositionRenderArgs<HostInputArgs<Readonly<Record<never, SceneInput>>>, {
    badge: Badge;
}>): VNodeChild
render
: ({
compiled: CompiledScene<{
    badge: Badge;
}, Readonly<Record<string, CompiledLayer<BackendRef<string>>>>>
compiled
, frame: numberframe, width: numberwidth, height: numberheight }) =>
h<Partial<{
    runtime: VueRenderRuntime;
}> & Omit<{
    readonly compiled: CompiledScene<unknown, Readonly<Record<string, CompiledLayer<BackendRef<string>>>>>;
    readonly frame: number;
    readonly width: number;
    readonly height: number;
    readonly runtime?: VueRenderRuntime | undefined;
} & VNodeProps & AllowedComponentProps & ComponentCustomProps, "runtime">>(type: Constructor<Partial<{
    runtime: VueRenderRuntime;
}> & Omit<...>>, props?: (VNodeProps & ... 3 more ... & Omit<...>) | undefined, children?: RawChildren | RawSlots): VNode (+22 overloads)
h
(
const SceneRenderer: DefineComponent<ExtractPropTypes<{
    compiled: {
        type: PropType<CompiledScene<unknown>>;
        required: true;
    };
    frame: {
        type: NumberConstructor;
        required: true;
    };
    width: {
        type: NumberConstructor;
        required: true;
    };
    height: {
        type: NumberConstructor;
        required: true;
    };
    runtime: {
        type: PropType<VueRenderRuntime>;
        default: undefined;
    };
}>, () => VNode<RendererNode, RendererElement, {
    ...;
}>, ... 17 more ..., any>
Frame-passive renderer for a CompiledScene: resolves the frame and paints its layers on a stage of `width` by `height`. The default slot is page markup, rendered in the scope of the scene's DOM layer (`SceneLayers`), where `<actor.h1 :of="compiled.scene.card.title">` binds a node of it to an actor; `<InLayer :layer="compiled.layers.<key>">` places its own markup in another DOM layer.
SceneRenderer
, { compiled: CompiledScene<unknown, Readonly<Record<string, CompiledLayer<BackendRef<string>>>>>compiled, frame: numberframe, width: numberwidth, height: numberheight }),
});

Outside a composition, provideRenderRuntime, provideFrameSource and provideFrameGate set the runtime, an ExternalFrameSource and a PromiseFrameGate for everything below them.

Transitions

Transition takes the actor and a default slot. Each Shared is tagged by name, so it morphs between the actor’s views. With the Standings actor from Transitions:

import { 
const dom: StagedBackend<DefineComponent<ExtractPropTypes<{
    readonly actors: {
        readonly type: PropType<BackendHostProps["actors"]>;
        readonly required: true;
    };
    readonly state: {
        readonly type: PropType<BackendHostProps["state"]>;
        readonly required: true;
    };
    readonly frame: {
        readonly type: NumberConstructor;
        readonly required: true;
    };
    readonly compiled: {
        readonly type: PropType<BackendHostProps["compiled"]>;
        readonly required: true;
    };
    ... 4 more ...;
    readonly layer: {
        ...;
    };
}>, ... 18 more ..., any>, "dom", VNodeChild>
The Vue DOM backend: `DomHost`, the `Group` primitive, and the `domStyle` stage, as `dom` in Vue binding code: `dom.render(Box, …)`, `createRenderRuntime({ backends: [dom], renderers })`.
dom
} from "@motionactor/dom/vue";
import {
const Shared: DefineComponent<ExtractPropTypes<{
    name: {
        type: PropType<SharedName>;
        required: true;
    };
    style: {
        type: PropType<StyleRecord>;
        default: undefined;
    };
    reflow: {
        type: BooleanConstructor;
        default: boolean;
    };
    stacking: {
        type: PropType<SharedStacking>;
        default: string;
    };
}>, () => VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>, {}, {}, {}, ... 14 more ..., any>
Tags a shared element by a declared name — the one way a view marks something `Transition` should morph; the kind (box or text) rides the declaration. Chrome belongs on the tagged element itself: that is what is measured and morphed. The default slot is the content. With `reflow`, it is content that lays itself out at any box — a container's hosted child — and receives `{ box }`: the morphing box inside a ghost, the measured box in a layer, `null` on the measuring commit. Without it the content is fixed and a ghost scales a copy.
Shared
,
const Transition: DefineComponent<ExtractPropTypes<{
    actor: {
        type: PropType<TransitioningActor>;
        required: true;
    };
}>, () => VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, ToResolvedProps<ExtractPropTypes<{
    actor: {
        type: PropType<TransitioningActor>;
        required: true;
    };
}>, {}>, ... 8 more ..., any>
The binding for `LayoutActor.transition(apply, options)`. The default slot renders one layer from the actor resolved for it: the snapshot one frame before the mutation for the from-layer, the current actor for the to-layer. Requires the compiled scene (`provideCompiledScene`, as `SceneRenderer` provides it); without one it shows the current tree. One measuring commit per transition, latched by transition and channel run: the layers render untransformed, every tagged element publishes its natural box, the scene re-resolves and the next render paints the morph. The latch is a plain variable so flipping it never re-renders on its own.
Transition
} from "@motionactor/renderers/vue";
import { function h<K extends keyof HTMLElementTagNameMap>(type: K, children?: RawChildren): VNode (+22 overloads)h } from "vue"; import { class StandingsStandings } from "./standings"; const { const row: (name: string) => SharedName<"box">row } = class StandingsStandings.
Standings.shared: SharedNames<{
    readonly row: (name: string) => string;
}>
shared
;
export const const standingsView: BackendRendererDefinition<readonly [typeof Standings], "dom">standingsView =
const dom: StagedBackend<DefineComponent<ExtractPropTypes<{
    readonly actors: {
        readonly type: PropType<BackendHostProps["actors"]>;
        readonly required: true;
    };
    readonly state: {
        readonly type: PropType<BackendHostProps["state"]>;
        readonly required: true;
    };
    readonly frame: {
        readonly type: NumberConstructor;
        readonly required: true;
    };
    readonly compiled: {
        readonly type: PropType<BackendHostProps["compiled"]>;
        readonly required: true;
    };
    ... 4 more ...;
    readonly layer: {
        ...;
    };
}>, ... 18 more ..., any>, "dom", VNodeChild>
The Vue DOM backend: `DomHost`, the `Group` primitive, and the `domStyle` stage, as `dom` in Vue binding code: `dom.render(Box, …)`, `createRenderRuntime({ backends: [dom], renderers })`.
dom
.render: <typeof Standings>(blueprint: typeof Standings, render: ActorRendererForBlueprints<readonly [typeof Standings], "dom">, options?: ActorRendererRegistrationOptions) => BackendRendererDefinition<readonly [typeof Standings], "dom"> (+1 overload)render(
class StandingsStandings, ({
actor: ResolvedActor & Omit<ResolvedActor, "signals" | "channels"> & {
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    teams: Team[];
} & {
    ...;
}
The actor. Reading it makes the renderer depend on all of it.
actor
}) =>
h<Partial<{}> & Omit<{
    readonly actor: TransitioningActor;
} & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>>(type: Constructor<Partial<{}> & Omit<{
    readonly actor: TransitioningActor;
} & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>>, props?: (VNodeProps & {
    __v_isVNode?: never;
    [Symbol.iterator]?: never;
} & Record<...> & Partial<...> & Omit<...>) | undefined, children?: RawChildren | RawSlots): VNode (+22 overloads)
h
(
const Transition: DefineComponent<ExtractPropTypes<{
    actor: {
        type: PropType<TransitioningActor>;
        required: true;
    };
}>, () => VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, ToResolvedProps<ExtractPropTypes<{
    actor: {
        type: PropType<TransitioningActor>;
        required: true;
    };
}>, {}>, ... 8 more ..., any>
The binding for `LayoutActor.transition(apply, options)`. The default slot renders one layer from the actor resolved for it: the snapshot one frame before the mutation for the from-layer, the current actor for the to-layer. Requires the compiled scene (`provideCompiledScene`, as `SceneRenderer` provides it); without one it shows the current tree. One measuring commit per transition, latched by transition and channel run: the layers render untransformed, every tagged element publishes its natural box, the scene re-resolves and the next render paints the morph. The latch is a plain variable so flipping it never re-renders on its own.
Transition
, { actor: TransitioningActoractor }, {
default: (table: ResolvedActor & Omit<ResolvedActor, "signals" | "channels"> & {
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    teams: Team[];
} & {
    ...;
}) => VNode<...>
default
: (
table: ResolvedActor & Omit<ResolvedActor, "signals" | "channels"> & {
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    teams: Team[];
} & {
    ...;
}
table
: typeof
actor: ResolvedActor & Omit<ResolvedActor, "signals" | "channels"> & {
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    teams: Team[];
} & {
    ...;
}
The actor. Reading it makes the renderer depend on all of it.
actor
) =>
h<"ol">(type: "ol", children?: RawChildren): VNode (+22 overloads)h("ol",
table: ResolvedActor & Omit<ResolvedActor, "signals" | "channels"> & {
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    teams: Team[];
} & {
    ...;
}
table
.
signals: Readonly<Record<string, unknown>> & {
    shape: {
        radius: number;
    };
    compositing: {
        blend: "difference" | "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten" | "color-dodge" | "color-burn" | "hard-light" | "soft-light" | "exclusion" | "hue" | "saturation" | "color" | "luminosity" | "plus-lighter";
        isolate: boolean;
        clip: number | null;
    };
    measuredBox: Rect | undefined;
    layout: {
        width: number | `${number}%` | Readonly<{
            kind: "layout.percent";
            value: number;
        }>;
        height: number | ... 1 more ... | Readonly<...>;
        x: LayoutValue;
        y: LayoutValue;
    };
    ... 5 more ...;
    teams: Team[];
}
signals
.teams: Team[]teams.
Array<Team>.map<VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>>(callbackfn: (value: Team, index: number, array: Team[]) => VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>, thisArg?: any): VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map
((team: Teamteam) =>
h<Partial<{
    style: StyleRecord;
    reflow: boolean;
    stacking: SharedStacking;
}> & Omit<{
    readonly name: SharedName<ViewTransitionElementKind>;
    readonly reflow: boolean;
    readonly stacking: SharedStacking;
    readonly style?: StyleRecord | undefined;
} & VNodeProps & AllowedComponentProps & ComponentCustomProps, DefaultKeys<{
    name: {
        type: PropType<SharedName>;
        required: true;
    };
    style: {
        ...;
    };
    reflow: {
        ...;
    };
    stacking: {
        ...;
    };
}>>>(type: Constructor<...>, props?: (VNodeProps & ... 3 more ... & Omit<...>) | undefined, children?: RawChildren | RawSlots): VNode (+22 overloads)
h
(
const Shared: DefineComponent<ExtractPropTypes<{
    name: {
        type: PropType<SharedName>;
        required: true;
    };
    style: {
        type: PropType<StyleRecord>;
        default: undefined;
    };
    reflow: {
        type: BooleanConstructor;
        default: boolean;
    };
    stacking: {
        type: PropType<SharedStacking>;
        default: string;
    };
}>, () => VNode<RendererNode, RendererElement, {
    [key: string]: any;
}>, {}, {}, {}, ... 14 more ..., any>
Tags a shared element by a declared name — the one way a view marks something `Transition` should morph; the kind (box or text) rides the declaration. Chrome belongs on the tagged element itself: that is what is measured and morphed. The default slot is the content. With `reflow`, it is content that lays itself out at any box — a container's hosted child — and receives `{ box }`: the morphing box inside a ghost, the measured box in a layer, `null` on the measuring commit. Without it the content is fixed and a ghost scales a copy.
Shared
,
{ key?: PropertyKey | undefinedkey: team: Teamteam.name: stringname, name: SharedName<ViewTransitionElementKind>
A name built by the actor's `defineShared` declaration; never a string.
name
: const row: (name: string) => SharedName<"box">row(team: Teamteam.name: stringname) },
() => `${team: Teamteam.name: stringname} ${team: Teamteam.points: numberpoints}`, ))), }), );

Effects

domStyle effects, overlays included, paint unchanged. Canvas effects such as glShader need the browser’s HTML-in-canvas; call provideHtmlCanvas(nativeHtmlCanvas) once near the root. Where the browser lacks it, the content paints unchanged under an overlay naming the missing browser APIs.

Hosts

mountVueComposition from @motionactor/engine/vue mounts a composition as the native preview, with the controller Hosts describes. @motionactor/hyperframes/vue mounts it for HyperFrames. Headless capture reads the binding from the composition:

import { function openHeadlessSession(options: HeadlessSessionOptions): Promise<HeadlessSession>
Open a composition in headless Chromium. The page is the one Studio previews (`buildCompositionPreview`), served from loopback; frames come out through CDP screenshots (`@motionactor/engine/capture/cdp`). An abort or a failure while opening releases everything it had started, the browser included.
openHeadlessSession
} from "@motionactor/engine/node";
const const session: HeadlessSessionsession = await function openHeadlessSession(options: HeadlessSessionOptions): Promise<HeadlessSession>
Open a composition in headless Chromium. The page is the one Studio previews (`buildCompositionPreview`), served from loopback; frames come out through CDP screenshots (`@motionactor/engine/capture/cdp`). An abort or a failure while opening releases everything it had started, the browser included.
openHeadlessSession
({
HeadlessSessionOptions.entry: CompositionEntry
The composition, as `bundleComposition`/`buildCompositionPreview` take it.
entry
: {
CompositionEntry.entry: stringentry: "./src/badge-card.ts", CompositionEntry.export: stringexport: "badgeCard", }, }); const const jpeg: Uint8Array<ArrayBufferLike>jpeg = await const session: HeadlessSessionsession.HeadlessSession.still(frame: number, options?: HeadlessStillOptions): Promise<Uint8Array>
A JPEG of `frame`. Captures only that frame.
still
(30);
await const session: HeadlessSessionsession.HeadlessSession.close(): Promise<void>
Waits for the running operation, then releases the browser, server and build. Idempotent.
close
();

Was this page helpful?