All guides

API reference

Every public export, generated from the TypeScript source when the site builds.

Film and stage

Aspecttype

type Aspect = "16:9" | "9:16" | "1:1" | "4:3" | "21:9"

Captioninterface

  • t0: number
  • t1: number
  • text: string

Chapterinterface

  • title: string
  • time: number

Clipinterface

  • t0: number
  • t1: number
  • labels: string[]

CompiledFilmclass

A film ready to sample. frame(t) is pure: seek to any time, in any order.

new CompiledFilm(stage
  • width: number
  • height: number
  • fps: number
  • duration: number
  • title: string
  • description: string
  • look: Look
  • bloom: number
  • background: string | null
  • posterTime: number | undefinedThe author's chosen poster time, when set.
  • bleed: boolean
  • chapters: readonly Chapter[]
  • clips: readonly Clip[]
  • captions: readonly Caption[]
  • stage: Stage
  • frameCount: number
  • preloadImages(): Promise<void>Preload static and keyed images, including those not visible in the first frame.
  • frame(time: number): FrameThe draw list at a time in seconds. May throw Suspend if a drawing needs a new asset.
  • svg(time: number, options?: { transparent?: boolean | undefined; scale?: number | undefined; }): stringStandalone SVG for a time.

compileFilmfunction

Run the build function, waiting for fonts and math when it asks for them, and return a seekable film.

function compileFilm(definition: FilmDefinition, overrides?: CompileOverrides): Promise<CompiledFilm>

CompileOverridesinterface

  • imageNetwork?: "allow" | "deny" | undefined
  • look?: Look | "midnight" | "paper" | "blueprint" | "chalk" | "neon" | undefined
  • fps?: number | undefined
  • bloom?: number | undefined
  • background?: string | null | undefined

filmfunction

Define a film: a function that authors a timeline on a stage.

function film(build: (stage: Stage) => void | Promise<void>): FilmDefinition
function film(options: FilmOptions, build: (stage: Stage) => void | Promise<void>): FilmDefinition

FilmDefinitioninterface

  • kind: "vizmatic.film"
  • options: FilmOptions
  • build: (stage: Stage) => void | Promise<void>
  • compile: (overrides?: CompileOverrides | undefined) => Promise<CompiledFilm>Compile with the engine that authored this film. The clock is module state, so a tool with its own bundled engine must call this and not its own compileFilm.

FilmOptionsinterface

  • imageNetwork?: "allow" | "deny" | undefinedLegacy URL images are allowed by default. Prepared image assets never use the network.
  • bleed?: boolean | undefinedLines and shapes run past the frame edges on purpose, as a warped grid does. Text is still checked.
  • title?: string | undefined
  • description?: string | undefined
  • aspect?: Aspect | undefinedLogical stage size. 16:9 is 1920x1080. Everything is authored in these units.
  • width?: number | undefined
  • height?: number | undefined
  • fps?: number | undefined
  • look?: Look | "midnight" | "paper" | "blueprint" | "chalk" | "neon" | undefined
  • font?: FontFamily | undefinedThe font of every text of the film that names none: a text() with no font, and each label of an object that got no font. A text or an object that names a font keeps it, and so do the code and the values that an object sets in mono. Without it, such a text is sans.
  • background?: string | null | undefined
  • bloom?: number | undefinedLight that spills from bright marks. Defaults to the look's value.
  • poster?: number | undefinedTime in seconds of the frame to use as a poster. Defaults to the richest frame.

isFilmfunction

function isFilm(value: unknown): value is FilmDefinition

isSuspendfunction

True for a Suspend thrown by any copy of the engine.

function isSuspend(error: unknown): error is Suspend

PlayOptionsinterface

  • duration?: number | undefined
  • ease?: Ease | undefined
  • label?: string | undefinedName shown in timelines.

Stageclass

The timeline a film is authored on. All coordinates are centered: (0, 0) is mid-frame and y points down.

new Stage(options
  • root: Node
  • camera: NodeMove, zoom, and rotate the view with to(s.camera, ...). sx is the zoom.
  • width: number
  • height: number
  • fps: number
  • look: Look
  • font: FontFamily | nullThe font that the film names for its texts, or null when it names none. A text with no font is then sans.
  • chapters: Chapter[]
  • clips: Clip[]
  • captions: Caption[]
  • updaters: Updater[]
  • lights: Light[]The lights that spotlight added. settleLights turns them into the dim of each node, in time order.
  • arrivals: WeakMap<Node, number>Three records for the lights, of facts that the timeline does not hold. Only a film with a light reads them, so they change nothing in a film with none. arrivals is the time at which a verb brought a node to the stage: a node that arrives at the very time of a light enters with it, and at time 0 the timeline cannot tell it from a node of s.add. marks is the node that a mark of a verb belongs to, such as the line of circumscribe and its target: the mark is as bright as that node. morphs is each morph with its nodes: a light must not dim a node while it changes its shape.
  • marks: Map<Node, Node>
  • morphs: MorphRecord[]
  • backdrop: RgbaThe color that a dim node goes toward: the background of the film, or of its look when the film has none.
  • time: number
  • right: numberHalf of the frame in each direction.
  • left: number
  • top: number
  • bottom: number
  • add<T extends Node>(first: T, ...rest: Node[]): TPut nodes on stage now. Returns the first, so setup reads as one line.
  • mountAt(node: Node, time: number): voidPut a node on stage so it first shows at time, which may differ from the cursor.
  • remove(...nodes: Node[]): void
  • play(...items: (Anim | PlayOptions)[]): StageRun animations together and advance the timeline past them.
  • wait(seconds?: number): StageHold on the current picture.
  • at(time: number, build: () => void): StageAuthor something at another time, then return to where you were.
  • chapter(title: string): StageMark a chapter for the player, presentation steps, and the timeline.
  • caption(text: string, duration?: number): StageShow a caption for a span of time. Captions also export as a VTT sidecar.
  • value(initial?: number): ValueA number that animates, for driving dynamic drawings.
  • update<T extends Node>(node: T, fn: (node: T, time: number) => void, window?: { from?: number | undefined; to?: number | undefined; }): TRe-run a function each frame while the node shows. It can set any property on the node.
  • duration: number

Suspendclass

Thrown while an asset loads. The compiler waits and runs the build function again.

new Suspend(promise
  • isVizmaticSuspend: trueLets a second copy of the engine recognize this without instanceof.
  • message: stringWhat a tool prints when this leaves the compiler: a text at the top of a film file throws it when the file loads, and a second copy of the engine throws one that this copy does not know.
  • promise: Promise<unknown>
  • toString(): string

Animations

alongfunction

Follow a path, or the shape of a node, from start to end.

function along(node: Node, track: Node | Path, options?: AnimOptions & { orient?: boolean | undefined; }): Anim

Animinterface

A piece of motion. schedule writes timeline keys for a window of time.

  • label: string
  • duration: number
  • ease?: Ease | undefined
  • schedule(ctx: AnimContext): void

AnimContextinterface

  • t0: number
  • t1: number
  • ease: Ease
  • stage: Stage

AnimOptionsinterface

  • duration?: number | undefined
  • ease?: Ease | undefined
  • lag?: number | undefinedFraction of one item's time between the starts of consecutive items.

appearfunction

Show at this moment, with no transition.

function appear(target: Target): Anim

applyMatrixfunction

Multiply a node's geometry by a 2x2 matrix around a stage point.

function applyMatrix(target: Target, matrix: readonly [readonly [number, number], readonly [number, number]], options?: AnimOptions & { origin?: Vec | undefined; yUp?: boolean | undefined; }): Anim

callfunction

Run a plain function at a moment on the timeline.

function call(fn: () => void): Anim

circumscribefunction

Trace a line around a node for emphasis, then let it run off.

function circumscribe(target: Node, options?: AnimOptions & { color?: ColorInput | undefined; pad?: number | undefined; radius?: number | undefined; width?: number | undefined; }): Anim

delayfunction

function delay(anim: Anim, seconds: number): Anim

drawfunction

Trace strokes in order. Filled shapes outline first, then fill.

function draw(target: Target, options?: AnimOptions): Anim

erasefunction

The reverse of draw.

function erase(target: Target, options?: AnimOptions): Anim

fadefunction

function fade(node: Node, opacity: number, options?: AnimOptions): Anim

fadeInfunction

function fadeIn(target: Target, options?: FadeOptions): Anim

FadeOptionsinterface

  • shift?: Vec | undefinedStart offset for fades in, or travel for fades out.
  • scale?: number | undefinedStart scale for fades in, or end scale for fades out.
  • duration?: number | undefined
  • ease?: Ease | undefined
  • lag?: number | undefinedFraction of one item's time between the starts of consecutive items.

fadeOutfunction

function fadeOut(target: Target, options?: FadeOptions): Anim

flashfunction

Radial burst at a point, for a moment of arrival.

function flash(point: Node | Vec, options?: AnimOptions & { color?: ColorInput | undefined; radius?: number | undefined; rays?: number | undefined; }): Anim

growfunction

Scale up from nothing. Pass a stage point to grow from it, such as an arrow's tail.

function grow(target: Target, options?: AnimOptions & { from?: Vec | undefined; }): Anim

indicatefunction

Swell and tint for a moment, then return.

function indicate(target: Target, options?: AnimOptions & { color?: ColorInput | undefined; scale?: number | undefined; }): Anim

laggedfunction

Start each piece after a fraction of the previous one has played.

function lagged(anims: readonly Anim[], options?: { lag?: number | undefined; duration?: number | undefined; }): Anim

morphfunction

Turn from into to, whatever their shapes. Afterwards to is on stage and from is hidden, so later code always refers to the node it can see.

function morph(from: Target, to: Target, options?: AnimOptions & { lag?: number | undefined; }): Anim

morphMatchingfunction

Morph equations and labels by meaning. Glyphs that exist on both sides travel to their new places. The rest fade out or in where they stand.

function morphMatching(from: Node, to: Node, options?: AnimOptions & { key?: ((leaf: Node) => unknown) | undefined; fadeShift?: Vec | undefined; }): Anim

moveTofunction

function moveTo(node: Node, target: Node | Vec, options?: AnimOptions): Anim

parfunction

Run together. Each piece keeps its own length unless the whole is rescaled.

function par(...anims: readonly Anim[]): Anim

pulsefunction

A short lit segment that travels along a line: a packet on an edge, a signal on a wire. The source line stays in place underneath.

function pulse(line: Node, options?: AnimOptions & { color?: ColorInput | undefined; length?: number | undefined; width?: number | undefined; glow?: number | undefined; }): Anim

recolorfunction

function recolor(node: Node, color: ColorInput, options?: AnimOptions): Anim

retimefunction

Change an animation's length or easing without changing what it does.

function retime(anim: Anim, options: AnimOptions): Anim

ripplefunction

Expanding ring that fades out, for a pulse from a point.

function ripple(point: Node | Vec, options?: AnimOptions & { color?: ColorInput | undefined; radius?: number | undefined; width?: number | undefined; }): Anim

rotatefunction

function rotate(node: Node, radians: number, options?: AnimOptions & { about?: Vec | undefined; }): Anim

scaleByfunction

function scaleBy(node: Node, factor: number | Vec, options?: AnimOptions & { about?: Vec | undefined; }): Anim

seqfunction

Run one after another.

function seq(...anims: readonly Anim[]): Anim

shakefunction

Shake gently to draw the eye.

function shake(node: Node, options?: AnimOptions & { angle?: number | undefined; cycles?: number | undefined; }): Anim

shiftfunction

function shift(node: Node, dx: number, dy: number, options?: AnimOptions): Anim

Targettype

type Target = Node | readonly Node[]

tofunction

Animate any change. Make the change on the node inside the callback, and the engine interpolates from the old state to the new one, including geometry. s.play(to(dot, (d) => d.moveTo(axes.p(2, 4)).color('yellow').scale(1.5)))

function to<T extends Node>(node: T, change: (node: T) => unknown, options?: AnimOptions & { restore?: boolean | undefined; }): Anim

Valueclass

A number on the timeline. Read .value inside dynamic and update to drive anything.

new Value(initial
  • track: Track<number>
  • value: number
  • set(value: number): ValueSet at the current point on the timeline.
  • to(value: number, options?: AnimOptions): Anim

vanishfunction

Hide at this moment, with no transition.

function vanish(target: Target): Anim

warpfunction

Deform every shape under a node through a function of stage position. This is how a grid bends under a matrix or a complex map.

function warp(target: Target, f: (x: number, y: number) => Vec, options?: AnimOptions & { subdivisions?: number | undefined; }): Anim

writefunction

Handwrite text and equations: each glyph is outlined, then filled.

function write(target: Target, options?: AnimOptions): Anim

Nodes

BlendModetype

type BlendMode = "normal" | "screen" | "multiply" | "overlay"

dynamicfunction

A node that rebuilds its contents on every frame from timeline values.

function dynamic(build: (time: number) => Node | readonly Node[] | null): Node

Edgetype

type Edge = "left" | "right" | "top" | "bottom"

groupfunction

A group. Children keep their own transforms inside it.

function group(...children: Node[]): Node

Nodeclass

Every visible thing on stage. A node with a path draws. A node with children groups. Both can carry a transform, and every property can change over time. Setter methods chain and apply at the current point on the timeline, so the same calls set up a node before it appears and change it afterwards.

new Node(path?
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Node
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Node
  • drop(child: Node): Node
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): NodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): NodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Node
  • moveTo(target: Node | Vec): NodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): NodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): NodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): NodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): NodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): NodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): NodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): NodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Node
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Node
  • color(color: ColorInput): NodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Node
  • glow(radius: number, color?: ColorInput | undefined): NodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Node
  • zIndex(value: number): Node
  • pin(): NodePin to the screen so the camera does not move this node.
  • hide(): Node
  • show(): Node
  • named(label: string): Node
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

NodePropsinterface

  • x: number
  • y: number
  • rotation: number
  • sx: number
  • sy: number
  • px: number
  • py: number
  • opacity: number
  • dim: numberThe part of its color that a node keeps while a light is on something else: at 1 the node has its own look, and at 0 its paints are the background color of the film. spotlight owns it, so a film that fades a node and a light that dims it do not write the same value. It does not change the alpha, so a dim node still hides what is behind it. It does not add up along a branch: a node draws with the least dim of itself and its ancestors.
  • visible: boolean
  • z: number
  • path: Path | null
  • fill: Paint | null
  • fillOpacity: number
  • stroke: Paint | null
  • strokeOpacity: number
  • strokeWidth: number
  • cap: "round" | "butt" | "square"
  • join: "round" | "miter" | "bevel"
  • dash: readonly number[] | null
  • dashOffset: number
  • trimFrom: number
  • trimTo: number
  • trimEach: boolean
  • glow: number
  • glowColor: Rgba | null
  • blend: BlendMode
  • fixed: booleanIgnore the camera. Use it for titles, captions, and other screen-space marks.
  • image: StageImage | null

PropNametype

type PropName = keyof NodeProps

Sidetype

type Side = Vec | Edge | "up" | "down"

StageImageinterface

  • src: stringEmbedded raster, local filename or legacy URL, resolved before the film is rendered.
  • width: number
  • height: number
  • crop?: Readonly<ImageCrop> | undefined
  • asset?: ImageAsset | undefined

Shapes

arcfunction

function arc(radius: number, from: number, to: number, style?: ShapeStyle): Node

arrowfunction

A shaft and a clean tip as one group. The shaft ends at the tip's base, so a thick line never pokes through the point.

function arrow(from: Vec, to: Vec, style?: ArrowStyle): Node

ArrowStyleinterface

  • tip?: number | undefinedTip length in pixels.
  • tipRatio?: number | undefinedTip width relative to its length.
  • bend?: number | undefinedCurve the shaft: positive bends left of the direction of travel.
  • pad?: number | undefinedSpace left at each end, so arrows stop short of what they point at.
  • both?: boolean | undefined
  • fill?: ColorInput | null | undefined
  • stroke?: ColorInput | null | undefined
  • width?: number | undefined
  • opacity?: number | undefined
  • glow?: number | undefined
  • dash?: readonly number[] | undefined
  • z?: number | undefined

bracefunction

Curly brace beside a span of two points, pointing out to one side.

function brace(from: Vec, to: Vec, style?: ShapeStyle & { depth?: number | undefined; }): Node

circlefunction

function circle(radius: number, style?: ShapeStyle): Node

curvefunction

A smooth curve through points. Non-finite points leave gaps.

function curve(points: readonly Vec[], style?: ShapeStyle & { closed?: boolean | undefined; }): Node

dotfunction

A filled point.

function dot(radius?: number, color?: ColorInput, style?: ShapeStyle): Node

ellipsefunction

function ellipse(rx: number, ry: number, style?: ShapeStyle): Node

imagefunction

A raster picture, such as a logo or a photo, centered on its origin. src is a URL or a data URL. A data URL keeps a film in one file and renders the same in every tool. It fades, moves, and scales like any node. Give width, height, or both.

function image(src: string | ImageAsset, options?: ImageOptions): Node

ImageOptionsinterface

  • width?: number | undefinedWidth on the stage. With only one of width and height, the other keeps the picture's proportions.
  • height?: number | undefined
  • opacity?: number | undefined
  • fit?: "contain" | "cover" | undefined
  • crop?: ImageCrop | undefinedA region in intrinsic image pixels, before fitting the destination box.

linefunction

function line(a: Vec, b: Vec, style?: ShapeStyle): Node

parametricfunction

function parametric(f: (t: number) => Vec, from: number, to: number, style?: ShapeStyle & { samples?: number | undefined; }): Node

polygonfunction

function polygon(points: readonly Vec[], style?: ShapeStyle): Node

polylinefunction

function polyline(points: readonly Vec[], style?: ShapeStyle & { closed?: boolean | undefined; }): Node

rectfunction

function rect(width: number, height: number, style?: ShapeStyle & { radius?: number | undefined; }): Node

regularPolygonfunction

function regularPolygon(sides: number, radius: number, style?: ShapeStyle): Node

shapefunction

Wrap any path as a stroked shape in the default ink.

function shape(path: Path, style?: ShapeStyle): Node

ShapeStyleinterface

  • fill?: ColorInput | null | undefined
  • stroke?: ColorInput | null | undefined
  • width?: number | undefined
  • opacity?: number | undefined
  • glow?: number | undefined
  • dash?: readonly number[] | undefined
  • z?: number | undefined

svgPathfunction

function svgPath(d: string, style?: ShapeStyle): Node

Images

ImageAssetinterface

Encoded bytes and intrinsic dimensions, validated before a film uses them.

  • id?: string | undefined
  • src: string
  • mediaType: "image/png" | "image/jpeg" | "image/gif"
  • width: number
  • height: number
  • sha256: string

ImageAssetErrorclass

new ImageAssetError(message

ImageAssetOptionsinterface

  • id?: string | undefined
  • mediaType?: string | undefined
  • sha256?: string | undefined
  • baseDir?: string | undefinedResolve a local filename relative to this directory in Node.
  • width?: number | undefinedExpected intrinsic dimensions, such as those declared in an asset manifest.
  • height?: number | undefined

ImageCropinterface

  • x: number
  • y: number
  • width: number
  • height: number

ImageFitOptionsinterface

  • width?: number | undefined
  • height?: number | undefined
  • fit?: "contain" | "cover" | undefined
  • crop?: ImageCrop | undefinedA region in intrinsic image pixels, before fitting the destination box.

resolveImageAssetfunction

Load once before authoring. No network request or file read occurs while painting.

function resolveImageAsset(source: string | Uint8Array<ArrayBufferLike>, options?: ImageAssetOptions): Promise<ImageAsset>

Objects

angleMarkfunction

An angle at a vertex, between the rays toward two points.

function angleMark(vertex: Vec, from: Vec, to: Vec, options?: AngleOptions): Node

AngleOptionsinterface

  • radius?: number | undefined
  • color?: ColorInput | undefined
  • width?: number | undefined
  • label?: string | undefined
  • labelSize?: number | undefined
  • fillOpacity?: number | undefinedSoft wedge under the arc.
  • reflex?: boolean | undefinedTake the long way around.

applyComplexfunction

Deform a complex plane through f(re, im). Labels stay readable by fading separately, so this moves only the grid.

function applyComplex(plane: NumberPlane, f: (re: number, im: number) => Vec, options?: AnimOptions & { subdivisions?: number | undefined; }): Anim

AreaOptionsinterface

  • from?: Reactive | undefined
  • to?: Reactive | undefined
  • fill?: ColorInput | undefined
  • opacity?: number | undefined
  • samples?: number | undefined

areaUnderfunction

Shaded region between a curve and the x axis. Pass functions for bounds that move.

function areaUnder(axes: Axes, f: (x: number) => number, options?: AreaOptions): Node

arrayCellsfunction

function arrayCells(values: readonly (string | number)[], options?: ArrayCellsOptions): ArrayCells

ArrayCellsclass

A row of boxes. swap(i, j) lifts two items over each other, and .cell(i) follows them.

new ArrayCells(values
  • slots: Node[]
  • indexLabels: Node[]
  • items: Node[]The item at each index, updated as swaps are authored.
  • cell(index: number): NodeThe item currently at an index.
  • slotAt(index: number): VecLocal stage position of a slot.
  • swap(i: number, j: number, options?: AnimOptions & { lift?: number | undefined; }): AnimExchange two items along opposite arcs.
  • mark(index: number, color: ColorInput, options?: AnimOptions): AnimRecolor an item.
  • enter(options?: AnimOptions): AnimCells appear from left to right.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): ArrayCells
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): ArrayCells
  • drop(child: Node): ArrayCells
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): ArrayCellsA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): ArrayCellsSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): ArrayCells
  • moveTo(target: Node | Vec): ArrayCellsMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): ArrayCellsMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): ArrayCellsScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): ArrayCellsRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): ArrayCellsScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): ArrayCellsPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): ArrayCellsLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): ArrayCellsLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): ArrayCells
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): ArrayCells
  • color(color: ColorInput): ArrayCellsRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): ArrayCells
  • glow(radius: number, color?: ColorInput | undefined): ArrayCellsSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): ArrayCells
  • zIndex(value: number): ArrayCells
  • pin(): ArrayCellsPin to the screen so the camera does not move this node.
  • hide(): ArrayCells
  • show(): ArrayCells
  • named(label: string): ArrayCells
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

ArrayCellsOptionsinterface

  • cell?: number | undefined
  • gap?: number | undefined
  • size?: number | undefined
  • color?: ColorInput | undefined
  • indices?: boolean | undefined
  • indexSize?: number | undefined
  • font?: FontFamily | undefinedThe font of the values. Defaults to mono. The indexes are in mono.

attentionMatrixfunction

Attention weights as a heatmap, with source tokens across the top and targets down the side. It is a Heatmap, so .cell(i, j) and .row(i) work.

function attentionMatrix(rows: readonly string[], columns: readonly string[], weights: readonly (readonly number[])[], options?: AttentionMatrixOptions): Heatmap

AttentionMatrixOptionsinterface

  • cell?: number | undefined
  • colors?: readonly ColorInput[] | undefined
  • values?: boolean | undefined
  • labelSize?: number | undefined
  • gap?: number | undefined
  • font?: FontFamily | undefinedThe font of the token labels. Defaults to the font of the film.

axesfunction

function axes(options?: AxesOptions): Axes

Axesclass

Coordinate axes. .p(x, y) converts math coordinates to stage points in this group's local space, and .plot(f) draws a function on them.

new Axes(options?
  • xRange: readonly [number, number]
  • yRange: readonly [number, number]
  • plotWidth: number
  • plotHeight: number
  • lines: NodeLines and ticks, for drawing in on their own.
  • grid: Node
  • numbers: Node
  • p(x: number, y: number): [number, number]Math coordinates to this group's local stage coordinates.
  • world(x: number, y: number): [number, number]Math coordinates to stage coordinates, following this group's transform.
  • plotPath(f: (x: number) => number, options?: { from?: number | undefined; to?: number | undefined; samples?: number | undefined; }): PathGeometry of a function over a range, clipped to the visible y range.
  • plot(f: (x: number) => number, style?: ShapeStyle & { from?: number | undefined; to?: number | undefined; samples?: number | undefined; }): NodeDraw a function on the axes. The curve becomes a child, so it moves with them.
  • dotAt(x: number, y: number, color?: ColorInput, radius?: number): NodeA point on the axes.
  • guides(x: number, y: number, style?: ShapeStyle): NodeDashed guides from a point down to both axes.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Axes
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Axes
  • drop(child: Node): Axes
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): AxesA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): AxesSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Axes
  • moveTo(target: Node | Vec): AxesMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): AxesMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): AxesScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): AxesRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): AxesScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): AxesPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): AxesLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): AxesLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Axes
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Axes
  • color(color: ColorInput): AxesRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Axes
  • glow(radius: number, color?: ColorInput | undefined): AxesSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Axes
  • zIndex(value: number): Axes
  • pin(): AxesPin to the screen so the camera does not move this node.
  • hide(): Axes
  • show(): Axes
  • named(label: string): Axes
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

AxesOptionsinterface

  • x?: readonly [number, number] | undefinedMath range on the x axis.
  • y?: readonly [number, number] | undefined
  • width?: number | undefinedOn-screen size in stage pixels.
  • height?: number | undefined
  • xStep?: number | undefined
  • yStep?: number | undefined
  • color?: ColorInput | undefined
  • labels?: boolean | undefinedNumber labels on ticks.
  • labelSize?: number | undefined
  • grid?: boolean | undefinedFaint background grid.
  • xLabel?: string | undefined
  • yLabel?: string | undefined
  • tips?: boolean | undefined

barChartfunction

function barChart(data: readonly BarDatum[], options?: BarChartOptions): BarChart

BarChartclass

Bars with direct labels and a single hairline baseline. enter() grows them from zero and update(values) animates to new data, with readouts that count.

new BarChart(data
  • bars: Node[]
  • labels: Node[]
  • readouts: Node[]
  • baseline: Node
  • values: Value[]
  • bar(i: number): Node
  • labelsOf(part: Node): readonly Node[]The name and the readout of a bar belong to it, so a light on the bar keeps them bright.
  • enter(options?: AnimOptions): AnimBaseline and labels appear, then bars rise one after another while readouts count up.
  • update(values: readonly number[], options?: AnimOptions): AnimAnimate to new values. The scale follows unless it was fixed at creation.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): BarChart
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): BarChart
  • drop(child: Node): BarChart
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): BarChartA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): BarChartSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): BarChart
  • moveTo(target: Node | Vec): BarChartMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): BarChartMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): BarChartScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): BarChartRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): BarChartScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): BarChartPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): BarChartLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): BarChartLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): BarChart
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): BarChart
  • color(color: ColorInput): BarChartRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): BarChart
  • glow(radius: number, color?: ColorInput | undefined): BarChartSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): BarChart
  • zIndex(value: number): BarChart
  • pin(): BarChartPin to the screen so the camera does not move this node.
  • hide(): BarChart
  • show(): BarChart
  • named(label: string): BarChart

BarChartOptionsinterface

  • gap?: number | undefinedFraction of each band left empty between bars.
  • max?: number | undefinedFixes the top of the scale. Defaults to the largest value.
  • min?: number | undefined
  • showValues?: boolean | undefined
  • format?: ((value: number) => string) | undefined
  • horizontal?: boolean | undefined
  • radius?: number | undefined
  • width?: number | undefined
  • height?: number | undefined
  • labelSize?: number | undefinedText size for direct labels and ticks.
  • color?: ColorInput | undefined
  • font?: FontFamily | undefinedThe font of the labels and the ticks. Defaults to the font of the film. A value that the chart prints is in mono.

BarDatuminterface

  • label: string
  • value: number
  • color?: ColorInput | undefined

bitFieldfunction

A word split into named fields: bitField([{ bits: 10, label: 'directory' }, { bits: 10, label: 'table', color: 'orange' }, { bits: 12, label: 'offset' }], { width: 1400 }).

function bitField(parts: readonly BitFieldPart[], options?: BitFieldOptions): BitField

BitFieldclass

A word split into named fields: a row of boxes, one per field, with the bit numbers over them. It shows a virtual address as its table indexes, the flags of a register, or the layout of a structure by byte offset. The first field is at the left. With wrap, the fields fill rows from the top. .at() places the middle of a full row, and of all rows from the top to the bottom. A field shows its label inside its box. A field with a value shows the value inside and the label under the box, and setValue() changes the value in place. field('PTE') is the node of one field, to light it, and p('PTE') is a point on its box.

new BitField(parts
  • fields: Node[]One node per field, which holds its box, its texts and its numbers. The first field is at the left.
  • boxes: Node[]
  • labels: (Node | null)[]The name of each field, or null for a field that has none.
  • values: (Node | null)[]The content that each field shows now, or null for a field that has none. setValue() replaces the node.
  • numbers: Node[]The numbers over the boxes, row by row, from the left to the right. Each one is also a part of its field.
  • total: numberThe sum of the bits of all fields.
  • field(which: string | number): NodeThe node of a field, by its index or by its label. Index 0 is the first field, at the left of the first row.
  • p(which: string | number, edge?: "left" | "right" | "top" | "bottom"): [number, number]The middle of an edge of the box of a field, in the coordinates of the object: the point where a line from the field starts. Defaults to the bottom edge. The left and the right edge are for the field at an end of a row. The point does not follow the object: read it again after the object moves.
  • range(which: string | number): [number, number]The high and the low bit of a field. With numbers: 'offsets', its first and its last offset. Without numbers, the bits count as with numbers: 'bits'.
  • enter(options?: AnimOptions): AnimThe fields arrive one after another, each with its texts and its numbers: from the left, and row by row.
  • setValue(which: string | number, value: string, options?: AnimOptions): AnimThe value of a field changes in place, such as a flag that goes from '0' to '1'. The text in the box fades out, then the new text fades in, so no moment shows two texts. It works on a field that was built with a value, because the layout does not change. The new text follows the rule of the first one: it shrinks to fit, and a text that cannot fit is an error. values then holds the new text.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): BitField
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): BitField
  • drop(child: Node): BitField
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): BitFieldA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): BitFieldSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): BitField
  • moveTo(target: Node | Vec): BitFieldMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): BitFieldMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): BitFieldScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): BitFieldRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): BitFieldScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): BitFieldPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): BitFieldLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): BitFieldLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): BitField
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): BitField
  • color(color: ColorInput): BitFieldRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): BitField
  • glow(radius: number, color?: ColorInput | undefined): BitFieldSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): BitField
  • zIndex(value: number): BitField
  • pin(): BitFieldPin to the screen so the camera does not move this node.
  • hide(): BitField
  • show(): BitField
  • named(label: string): BitField
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

BitFieldOptionsinterface

  • width?: number | undefinedThe width of one row: of all fields together, or of wrap bits. Defaults to 1200.
  • height?: number | undefinedThe height of the boxes. Defaults to 2.6 of size.
  • scale?: "proportional" | "even" | undefined'proportional' gives each field a width for its bits. 'even' gives every field of a row the same width. Defaults to proportional.
  • minWidth?: number | undefinedThe least width of a field, so that a field of one bit can hold a name. The wider fields share the rest. Defaults to 0.
  • wrap?: number | undefinedHow many bits (or bytes) one row holds. The fields then fill rows from the top, for the layout of a structure. A field that would cross the end of a row is an error. Without it, all fields are in one row.
  • rowGap?: number | undefinedThe room between two rows. Defaults to the room that the numbers and the labels under the boxes need, and a little more.
  • numbers?: false | "bits" | "offsets" | undefinedWhat to write over the boxes. 'bits' numbers the bits from the right, with the highest bit at the left, such as 63, 48, 47, 39. 'offsets' counts up from 0 at the left, for the bytes of a structure. False writes nothing. Defaults to 'bits'.
  • size?: number | undefinedText size of the labels and values. The numbers are smaller. Defaults to 26.
  • color?: ColorInput | undefinedThe color of a field that has none of its own. Defaults to blue.
  • font?: FontFamily | undefinedThe font of the labels. The values and the numbers are in mono.

BitFieldPartinterface

  • bits: numberHow many bits (or bytes) the field has. A whole number, 1 or more.
  • label?: string | undefinedThe name of the field, on one line.
  • value?: string | undefinedThe content of the field, such as '0x1fe' or '1', on one line. Drawn in mono inside the box. The label then goes under the box. An empty text is a value too: an empty box that setValue() can fill.
  • color?: ColorInput | undefinedDefaults to the color of the object.
  • unused?: boolean | undefinedA field that carries nothing, such as reserved bits: a faint box with a hatch.

boundaryfunction

An open line between two sides that counts what crosses it: boundary({ label: 'system call line', above: 'user space', below: 'kernel', tally: ['system call', 'system calls'] }). .at(x, y) places its middle.

function boundary(options?: BoundaryOptions): Boundary

Boundaryclass

An open line between two sides, such as user space and the kernel, that counts what crosses it. cross() sends a mark through the line: the line lights there, a tick stays, and the tally goes up. addCrossings() runs the tally up with no mark, for a number that is too large to draw, and fills the line with ticks. clear() starts the next round of a comparison. .at() places the middle of the line. The names are at the left end and the tally is at the right end, and x() gives the places between them. What changes with time is kept in lists that a change replaces and never edits, and in the nodes. So a copy of the line, made alone or with the group or the zone that holds it, has its own tally and its own ticks.

new Boundary(options?
  • line: Node
  • labelNode: Node | nullThe name of the line, or null when it has none.
  • sides: readonly [Node | null, Node | null]The names of the side over the line and of the side under it. Each is null when it is not given.
  • tallyNode: Node | nullThe number and the word of the tally, as one node, or null when the line shows no tally.
  • noteNode: Node | nullThe note under the right end of the line that says what one tick stands for, such as "each tick: about 40". It is null while one tick is one crossing.
  • ticks: readonly Node[]The ticks that are on the line after the changes that are scheduled so far, in the order that they arrive.
  • x(part: number): numberA place along the line for cross(), in the coordinates of the line: 0 is the first place after the names and 1 is the last place before the tally, with room for the widest tally of the line.
  • count: numberThe tally after the changes that are scheduled so far.
  • enter(options?: AnimOptions): AnimThe line draws from the left, then the names, the tally and the ticks arrive.
  • cross(x: number, options?: BoundaryCrossOptions): BoundaryCrossingA mark travels through the line at x, a place in the coordinates of the line: use line.x(part). Where the mark passes, the line lights for a moment and a tick stays. The tally goes up when the mark is on the line the first time.
  • addCrossings(count: number, options?: AnimOptions): AnimThe tally runs up by count with no mark, for a number that is too large to draw, such as line.addCrossings(10000). The number on screen runs through whole values and ends exact. The line fills with ticks from the left while the number runs: one tick for each crossing, or for each tickScale crossings. When the line is full, a note under it says what one tick stands for.
  • clear(options?: AnimOptions): AnimThe ticks and the note fade and the tally goes back to 0, for the next round of a comparison.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Boundary
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Boundary
  • drop(child: Node): Boundary
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): BoundaryA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): BoundarySet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Boundary
  • moveTo(target: Node | Vec): BoundaryMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): BoundaryMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): BoundaryScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): BoundaryRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): BoundaryScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): BoundaryPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): BoundaryLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): BoundaryLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Boundary
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Boundary
  • color(color: ColorInput): BoundaryRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Boundary
  • glow(radius: number, color?: ColorInput | undefined): BoundarySoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Boundary
  • zIndex(value: number): Boundary
  • pin(): BoundaryPin to the screen so the camera does not move this node.
  • hide(): Boundary
  • show(): Boundary
  • named(label: string): Boundary
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

BoundaryCrossinginterface

A crossing that s.play() can run. It also gives its two parts, for a film that reads their places.

  • mark: NodeThe mark that travels.
  • labelNode: Node | nullThe text of the crossing, or null when it has none.
  • label: string
  • duration: number
  • ease?: Ease | undefined
  • schedule(ctx: AnimContext): void

BoundaryCrossOptionsinterface

  • direction?: "up" | "down" | "round" | undefined'down' goes from over the line to under it, 'up' the reverse, and 'round' goes down and comes back. Defaults to down.
  • reach?: number | undefinedHow far from the line the mark starts and ends. Defaults to 2.7 of the text size of the line, as a whole number: 70 at size 26.
  • color?: ColorInput | undefinedThe color of the mark and of its tick. Without it, the mark is ink and the tick has the color of the line.
  • label?: string | undefinedA short text beside the place where the mark starts. It fades with the mark.
  • counts?: number | undefinedHow much the tally goes up. A whole number, 0 or more. Defaults to 1.
  • duration?: number | undefined
  • ease?: Ease | undefined
  • lag?: number | undefinedFraction of one item's time between the starts of consecutive items.

BoundaryOptionsinterface

  • width?: number | undefinedThe length of the line. Defaults to 1600.
  • label?: string | undefinedThe name of the line, over its left end, such as 'system call line'.
  • above?: string | undefinedThe name of the side over the line, at the left end, such as 'user space'.
  • below?: string | undefinedThe name of the side under the line, at the left end, such as 'kernel'.
  • color?: ColorInput | undefinedThe color of the line, its label and its ticks. Defaults to yellow.
  • weight?: number | undefinedThe width of the stroke. Defaults to 3. A wall that is harder to cross can take 6.
  • dash?: boolean | undefinedA dashed line, for a boundary that is a rule and not a wall.
  • tally?: string | boolean | readonly [one: string, many: string] | undefinedShow a tally of the crossings. true shows the number alone. A string is the word after the number. A pair is the word for one and the word for more, such as ['system call', 'system calls'].
  • tallySide?: "over" | "end" | undefinedWhere the tally is. 'end' puts it over the right end of the line, next to the line, and x() keeps crossings clear of it. 'over' puts it on a row of its own, over the place where a mark starts, so that crossings have the line up to its right end. Defaults to 'end'.
  • tallyDigits?: number | undefinedThe digits that the tally has room for. A count with more digits is an error. Defaults to 6.
  • tallySize?: number | undefinedText size of the tally. Defaults to size.
  • tallyColor?: ColorInput | undefinedThe color of the number of the tally. Its word stays dim. Defaults to ink.
  • tickScale?: number | undefinedHow many crossings one tick stands for. Give the lines that a film compares one value, so that their ticks compare as their counts do. Without it, one tick is one crossing until the line is full.
  • size?: number | undefinedText size. Defaults to 26.
  • font?: FontFamily | undefined

braceLabelfunction

A brace along one side of a node or nodes, with a label at its point.

function braceLabel(target: Node | readonly Node[], label: string, options?: BraceLabelOptions): Node

BraceLabelOptionsinterface

  • side?: "left" | "right" | "top" | "bottom" | undefined
  • gap?: number | undefined
  • size?: number | undefined
  • color?: ColorInput | undefined
  • plain?: boolean | undefinedSet for plain text labels. Labels are math by default.
  • font?: FontFamily | undefinedThe font of a plain label. Defaults to the font of the film.
  • depth?: number | undefined

calloutfunction

function callout(target: Node | Vec, body: string, options?: CalloutOptions): Callout

Calloutclass

A note with a leader line back to what it describes. The leader stops at the text block's edge, so it never runs through the words.

new Callout(target
  • leader: Node
  • marker: Node
  • body: Node
  • titleNode: Node | null
  • enter(options?: AnimOptions): AnimThe marker lands, the leader runs out, and the text settles at the end of it.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Callout
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Callout
  • drop(child: Node): Callout
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): CalloutA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): CalloutSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Callout
  • moveTo(target: Node | Vec): CalloutMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): CalloutMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): CalloutScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): CalloutRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): CalloutScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): CalloutPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): CalloutLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): CalloutLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Callout
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Callout
  • color(color: ColorInput): CalloutRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Callout
  • glow(radius: number, color?: ColorInput | undefined): CalloutSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Callout
  • zIndex(value: number): Callout
  • pin(): CalloutPin to the screen so the camera does not move this node.
  • hide(): Callout
  • show(): Callout
  • named(label: string): Callout
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

CalloutOptionsinterface

  • title?: string | undefined
  • side?: Edge | undefinedWhich way the text sits from its target.
  • distance?: number | undefinedDistance from the target to the text, in stage pixels.
  • offset?: number | undefinedSlide the text along the other axis.
  • width?: number | undefinedWrap width for the body.
  • size?: number | undefined
  • color?: ColorInput | undefined
  • bodyColor?: ColorInput | undefined
  • plate?: boolean | undefinedPlate behind the text, for placing a note over busy marks.
  • font?: FontFamily | undefinedThe font of the title and the body. Defaults to the font of the film.

captionLinesfunction

Split spoken text into caption lines: by sentence, then by length.

function captionLines(text: string, length?: number): string[]

cardfunction

A box with a title, a picture, and a caption, such as card({ title: 'Logs', figure: pictogram('logs'), caption: 'one line per event' }).

function card(options?: CardOptions): Card

Cardclass

A box with a title at the top, a picture in the middle, and a caption at the bottom. The title and the caption sit at fixed distances from the border, and the picture is centered in the space between them. Cards with one width, one height, and one captionLines share one layout whatever they hold.

new Card(options?
  • frame: Node
  • title: Node | null
  • figure: Node | null
  • caption: Node | null
  • figureBox: BoundsThe space that the picture may use, in the coordinates of the card, where (0, 0) is its middle.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Card
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Card
  • drop(child: Node): Card
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): CardA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): CardSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Card
  • moveTo(target: Node | Vec): CardMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): CardMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): CardScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): CardRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): CardScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): CardPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): CardLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): CardLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Card
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Card
  • color(color: ColorInput): CardRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Card
  • glow(radius: number, color?: ColorInput | undefined): CardSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Card
  • zIndex(value: number): Card
  • pin(): CardPin to the screen so the camera does not move this node.
  • hide(): Card
  • show(): Card
  • named(label: string): Card
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

CardOptionsinterface

  • width?: number | undefinedOuter width, in pixels. Defaults to 420.
  • height?: number | undefinedOuter height, in pixels. Without it, the card is as tall as its content. Give one height to the cards of a row.
  • title?: string | undefinedThe name at the top. A name that is too wide is set smaller, down to 0.6 of titleSize.
  • figure?: Node | undefinedThe picture in the middle. It must not be on the stage or in a group yet. A picture that is too large is scaled down to fit.
  • caption?: string | undefinedThe text at the bottom. It wraps to the width of the card.
  • captionLines?: number | undefinedThe number of caption lines to keep room for. Set it to the longest caption of a row, so that a card with a short caption has the same layout as the others. Defaults to the lines of this caption.
  • color?: ColorInput | undefinedThe color of the border and the title. Defaults to ink.
  • captionColor?: ColorInput | undefinedThe color of the caption. Defaults to ink.
  • titleSize?: number | undefinedFont size of the title. Defaults to 40.
  • captionSize?: number | undefinedFont size of the caption. Defaults to 0.72 of titleSize.
  • padding?: number | undefinedSpace between the border and the content. Defaults to 0.7 of titleSize.
  • fill?: ColorInput | null | undefinedThe fill of the card. Pass null for none. Defaults to the surface color.
  • radius?: number | undefined
  • borderWidth?: number | undefinedWidth of the border. Defaults to 3.
  • font?: FontFamily | undefined

ChartOptionsinterface

  • width?: number | undefined
  • height?: number | undefined
  • labelSize?: number | undefinedText size for direct labels and ticks.
  • color?: ColorInput | undefined
  • font?: FontFamily | undefinedThe font of the labels and the ticks. Defaults to the font of the film. A value that the chart prints is in mono.

checkFilmfunction

Inspect a film for layout defects: marks off the canvas, text against an edge of the frame, text on text, strokes through text, and characters that no font can draw. It looks where the film comes to rest, because objects may cross each other while moving. With motion, it also looks at every frame. Runs anywhere, with no rendering.

function checkFilm(film: FilmDefinition | CompiledFilm, options?: FilmCheckOptions): Promise<FilmCheckReport>

CODE_LANGUAGESconst

The languages that tokenize and codeBlock color. An unknown name falls back to TypeScript.

const CODE_LANGUAGES: readonly string[]

codeBlockfunction

function codeBlock(source: string, options?: CodeBlockOptions): CodeBlock

CodeBlockclass

Syntax-colored code as real glyphs. It can be written on, focused line by line, and morphed token by token into a new version with morphCode.

new CodeBlock(source
  • lines: Node[]
  • tokens: CodeToken[]
  • chars: Node[]
  • panelNode: Node | null
  • body: Node
  • source: string
  • line(index: number): NodeOne line of code, as a node. Lines count from 0.
  • find(fragment: string, line?: number | undefined): Node[]Glyphs of the code that matches. A fragment that is one token, such as lo, matches every such token. Any other fragment, such as lo + hi, matches as text inside a line, and spaces do not count. Pass a line, counted from 0, to search that line only.
  • focus(lines: number | readonly number[], options?: AnimOptions & { dim?: number | undefined; color?: ColorInput | undefined; }): AnimDim everything except these lines, and lay a soft bar behind them.
  • unfocus(options?: AnimOptions): AnimRestore all lines and remove the focus bar.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): CodeBlock
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): CodeBlock
  • drop(child: Node): CodeBlock
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): CodeBlockA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): CodeBlockSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): CodeBlock
  • moveTo(target: Node | Vec): CodeBlockMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): CodeBlockMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): CodeBlockScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): CodeBlockRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): CodeBlockScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): CodeBlockPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): CodeBlockLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): CodeBlockLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): CodeBlock
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): CodeBlock
  • color(color: ColorInput): CodeBlockRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): CodeBlock
  • glow(radius: number, color?: ColorInput | undefined): CodeBlockSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): CodeBlock
  • zIndex(value: number): CodeBlock
  • pin(): CodeBlockPin to the screen so the camera does not move this node.
  • hide(): CodeBlock
  • show(): CodeBlock
  • named(label: string): CodeBlock
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

CodeBlockOptionsinterface

  • language?: string | undefinedOne of CODE_LANGUAGES, or an alias such as py, tla+, or smt2. Defaults to TypeScript.
  • size?: number | undefined
  • leading?: number | undefinedLine height as a multiple of size.
  • lineNumbers?: boolean | undefined
  • panel?: boolean | undefinedDraw a quiet panel behind the code.
  • padding?: number | undefined
  • minWidth?: number | undefinedMinimum panel width, so versions of a snippet can share one frame.
  • colors?: Partial<Record<"string" | "number" | "function" | "keyword" | "comment" | "type" | "punctuation" | "plain", ColorInput>> | undefined

CodeTokeninterface

  • text: string
  • kind: TokenKind
  • line: number
  • glyphs: Node[]

complexconst

Small complex arithmetic on [re, im] pairs.

const complex: { mul: (a: Vec, b: Vec) => Vec; div: (a: Vec, b: Vec) => Vec; exp: (a: Vec) => Vec; log: (a: Vec) => Vec; pow: (a: Vec, n: number) => Vec; sin: (a: Vec) => Vec; cos: (a: Vec) => Vec; inv: (a: Vec) => Vec; }

complexPlanefunction

function complexPlane(options?: ComplexPlaneOptions): ComplexPlane

ComplexPlaneclass

new ComplexPlane(options?
  • numbers: Node
  • z(re: number, im: number): [number, number]Complex number to local stage coordinates.
  • unit: number
  • major: Node
  • minor: Node
  • axes: Node
  • p(x: number, y: number): [number, number]Math coordinates to stage coordinates. y points up on the plane.
  • vector(x: number, y: number, style?: ShapeStyle): NodeA vector drawn from the origin, as an arrow.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): ComplexPlane
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): ComplexPlane
  • drop(child: Node): ComplexPlane
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): ComplexPlaneA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): ComplexPlaneSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): ComplexPlane
  • moveTo(target: Node | Vec): ComplexPlaneMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): ComplexPlaneMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): ComplexPlaneScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): ComplexPlaneRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): ComplexPlaneScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): ComplexPlanePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): ComplexPlaneLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): ComplexPlaneLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): ComplexPlane
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): ComplexPlane
  • color(color: ColorInput): ComplexPlaneRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): ComplexPlane
  • glow(radius: number, color?: ColorInput | undefined): ComplexPlaneSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): ComplexPlane
  • zIndex(value: number): ComplexPlane
  • pin(): ComplexPlanePin to the screen so the camera does not move this node.
  • hide(): ComplexPlane
  • show(): ComplexPlane
  • named(label: string): ComplexPlane
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

ComplexPlaneOptionsinterface

  • labelRange?: number | undefinedLabel real and imaginary integers out to this distance from the origin.
  • labelSize?: number | undefined
  • unit?: number | undefinedStage pixels per math unit.
  • x?: readonly [number, number] | undefinedExtent in math units. Defaults to overscan past the frame edges, for warps that pull in.
  • y?: readonly [number, number] | undefined
  • color?: ColorInput | undefined
  • minor?: number | undefinedMinor grid lines per unit.
  • axisColor?: ColorInput | undefined
  • width?: number | undefined

connectorfunction

function connector(from: ConnectorEnd, to: ConnectorEnd, options?: ConnectorOptions): Connector

Connectorclass

A line between two nodes that is routed fresh on every frame. Move a node and the line follows. draw(connector) traces it, and .pulse() sends a signal.

new Connector(from
  • routeNow(): PathGeometry from end to end at this moment, in stage coordinates.
  • pulse(options?: AnimOptions & { color?: ColorInput | undefined; length?: number | undefined; width?: number | undefined; glow?: number | undefined; }): AnimSend a signal along the line. Pulses can overlap, and they follow a moving route.
  • pointNow(fraction?: number): [number, number]Point at a fraction along the current route, for placing notes beside the line.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Connector
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Connector
  • drop(child: Node): Connector
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): ConnectorA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): ConnectorSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Connector
  • moveTo(target: Node | Vec): ConnectorMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): ConnectorMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): ConnectorScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): ConnectorRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): ConnectorScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): ConnectorPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): ConnectorLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): ConnectorLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Connector
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Connector
  • color(color: ColorInput): ConnectorRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Connector
  • glow(radius: number, color?: ColorInput | undefined): ConnectorSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Connector
  • zIndex(value: number): Connector
  • pin(): ConnectorPin to the screen so the camera does not move this node.
  • hide(): Connector
  • show(): Connector
  • named(label: string): Connector
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

ConnectorEndtype

type ConnectorEnd = Node | Vec

ConnectorOptionsinterface

  • from?: Edge | undefinedSide to leave from and arrive at. Chosen automatically when omitted.
  • to?: Edge | undefined
  • route?: "curve" | "ortho" | "straight" | undefined
  • color?: ColorInput | undefined
  • width?: number | undefined
  • dash?: readonly number[] | undefined
  • tip?: boolean | undefinedDraw an arrowhead at the end.
  • tipSize?: number | undefined
  • label?: string | undefinedLabel on the line, on a plate so the line never crosses its text.
  • font?: FontFamily | undefinedThe font of the label. Defaults to the font that the film names, and to mono in a film that names none.
  • labelSize?: number | undefined
  • labelColor?: ColorInput | undefined
  • labelBackground?: ColorInput | undefined
  • labelAt?: number | undefinedWhere the label sits along the line.
  • gap?: number | undefinedSpace between the line and the box it touches.
  • fromOffset?: number | undefinedSlide each end along its side, from -1 to 1. Use it to separate parallel lines.
  • toOffset?: number | undefined
  • curvature?: number | undefined
  • radius?: number | undefined
  • flow?: number | undefinedDashes travel along the line at this many pixels per second.

counterfunction

function counter(initial?: number, options?: CounterOptions): Counter

Counterclass

A number readout. Animate it with countUp.

new Counter(initial?
  • value: Value
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Counter
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Counter
  • drop(child: Node): Counter
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): CounterA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): CounterSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Counter
  • moveTo(target: Node | Vec): CounterMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): CounterMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): CounterScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): CounterRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): CounterScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): CounterPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): CounterLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): CounterLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Counter
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Counter
  • color(color: ColorInput): CounterRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Counter
  • glow(radius: number, color?: ColorInput | undefined): CounterSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Counter
  • zIndex(value: number): Counter
  • pin(): CounterPin to the screen so the camera does not move this node.
  • hide(): Counter
  • show(): Counter
  • named(label: string): Counter
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

CounterOptionsinterface

  • digits?: number | undefined
  • size?: number | undefined
  • color?: ColorInput | undefined
  • font?: FontFamily | undefinedDefaults to mono, in every film: a number that changes keeps its width in mono.
  • weight?: 400 | 600 | 700 | undefined
  • prefix?: string | undefined
  • suffix?: string | undefined
  • grouped?: boolean | undefinedThousands separators.

countUpfunction

Count a Counter or Value to a target.

function countUp(target: Value | Counter, to: number, options?: AnimOptions): Anim

crossThroughfunction

One mark through several lines, from the first to the last: crossThrough([calls, wall], calls.x(0.5), { direction: 'round' }). Each line lights, keeps a tick, and counts.

function crossThrough(lines: readonly Boundary[], x: number, options?: BoundaryCrossOptions): BoundaryCrossing

dashedGuidesfunction

Dashed drop lines from a point on the axes. Pass functions to follow a moving point.

function dashedGuides(axes: Axes, x: Reactive, y: Reactive, style?: ShapeStyle): Node

DateEventinterface

  • at: DateInputWhen the event was. With scale 'order', it can also be a version, such as '5.1'.
  • label?: string | number | undefinedThe name of the event, on one line. A number is written as its text. An event with no label is a mark only, with no stem.
  • note?: string | number | undefinedA second line under the label, in dim. A number is written as its text.
  • color?: ColorInput | undefinedThe color of the mark, the stem and the label. Defaults to ink.
  • side?: "over" | "under" | undefinedWhere the label goes. Without it, the labels go over the line and under it by turns, in date order.
  • mark?: DateMark | undefinedThe mark on the line: a dot, a star for an event of another kind, or a ring for an event with no sure date. Defaults to a dot.

DateEventNodeclass

One event of a DateLine object. It is hidden until the cursor reaches it.

new DateEventNode(mark
  • covers: Node[]The ticks of the line that are in the clear room of the mark. A tick leaves while the event shows, by any way that the film shows it.
  • mark: NodeThe mark of the event: a dot, a star, or a ring.
  • stem: Node | nullThe line to the label, or null for an event with no label.
  • text: TextNode | nullThe label of the event, or null when the event has none.
  • note: TextNode | nullThe line under the label, or null when the event has none.
  • halo: NodeThe ring around the mark of the event that light() lit. It has no opacity when the event is not lit.
  • set<K extends PropName>(prop: K, value: NodeProps[K]): DateEventNode
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): DateEventNode
  • drop(child: Node): DateEventNode
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): DateEventNodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): DateEventNodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): DateEventNode
  • moveTo(target: Node | Vec): DateEventNodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): DateEventNodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): DateEventNodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): DateEventNodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): DateEventNodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): DateEventNodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): DateEventNodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): DateEventNodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): DateEventNode
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): DateEventNode
  • color(color: ColorInput): DateEventNodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): DateEventNode
  • glow(radius: number, color?: ColorInput | undefined): DateEventNodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): DateEventNode
  • zIndex(value: number): DateEventNode
  • pin(): DateEventNodePin to the screen so the camera does not move this node.
  • hide(): DateEventNode
  • show(): DateEventNode
  • named(label: string): DateEventNode
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

DateInputtype

A date: 'YYYY', 'YYYY-MM' or 'YYYY-MM-DD', or a number of years such as 2020 or 2023.25.

type DateInput = string | number

dateLinefunction

A line of time with events at their dates: dateLine([{ at: '2025-06-10', label: 'the newsletter' }, { at: '2026-03-24', label: 'the report', note: 'names the system' }], { width: 1600, from: 2020, to: 2027 }).

function dateLine(events: readonly DateEvent[], options?: DateLineOptions): DateLine

DateLineclass

A line of time with events at their dates: a mark on the line for each event, and a stem to its label. The object places the labels over the line and under it, at more than one height, so that no two of them meet. An event with no label is a mark only. A mark that would touch another one goes to a row over the line. advance(date) moves a cursor to a date and stops there, and each event appears when the cursor passes it. .at() places the middle of the line. The bounds of the object hold every label from the start: read extent.

new DateLine(events
  • events: DateEventNode[]One node per event, in the order given.
  • axis: NodeThe line, its ticks and the texts under them, and the words "not to scale" of an 'order' line.
  • cursor: NodeA small pointer under the line, at the date that the film has reached. It moves in a room of its own, under the marks and over the texts under the line, so it touches nothing. The first advance shows it.
  • domain: readonly [number, number]The two ends of the line as numbers of years. With scale 'order', the ends are counted in events: -0.5 and the number of dates less 0.5.
  • unit: DateUnit | nullWhat a tick of the line is. Null with scale 'order', where a tick is an event.
  • extent: { readonly left: number; readonly right: number; readonly top: number; readonly bottom: number; }The room of the line with all its events, in the coordinates of the object: how far the labels and the rows of marks go over the line and under it, and how far a text passes each end. The bounds of the object are this room from the start, also while the events are hidden.
  • date: numberThe place of the cursor after the changes that are scheduled so far, as a number of years. It starts at the first end of the line. With scale 'order', it is counted in events: 0 is the first date.
  • lit: number | nullThe index of the event that has the accent color, after the changes that are scheduled so far. Null when no event is lit.
  • x(date: DateInput): numberThe x of a date, in the coordinates of the object. The middle of the line is at 0. With scale 'order', the line has a place for the dates of its events only.
  • p(index: number): [number, number]The place of the mark of an event, in the coordinates of the object, by its index in the list.
  • enter(options?: AnimOptions): AnimThe line draws from its first end, and its ticks and their texts arrive as it passes them. No event shows yet.
  • advance(to: DateInput, options?: AnimOptions): AnimThe cursor moves from its date to to, and stops. Each event that it passes appears: its mark, then its stem, then its label. All of it is over when the animation ends: when the last event needs time after the cursor reaches it, the cursor stops early.
  • showAll(options?: AnimOptions): AnimThe same as advance to the last end of the line. It takes 3 seconds when the film gives no duration.
  • light(index: number | null, options?: AnimOptions): AnimOne event takes the look of the lit event: the accent color on its mark, its stem and its label, and a ring around its mark. The event that had this look takes its own color back. light(null) leaves no event lit. An event that the cursor has not reached stays hidden, and it is lit when it appears.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): DateLine
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): DateLine
  • drop(child: Node): DateLine
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): DateLineA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): DateLineSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): DateLine
  • moveTo(target: Node | Vec): DateLineMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): DateLineMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): DateLineScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): DateLineRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): DateLineScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): DateLinePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): DateLineLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): DateLineLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): DateLine
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): DateLine
  • color(color: ColorInput): DateLineRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): DateLine
  • glow(radius: number, color?: ColorInput | undefined): DateLineSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): DateLine
  • zIndex(value: number): DateLine
  • pin(): DateLinePin to the screen so the camera does not move this node.
  • hide(): DateLine
  • show(): DateLine
  • named(label: string): DateLine
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

DateLineOptionsinterface

  • width?: number | undefinedThe length of the line. Every label is inside it. A text under a tick at an end passes it by half of its width. Defaults to 1600.
  • from?: DateInput | undefinedThe dates at the two ends of the line, for scale 'time', such as from: '2025-06'. They default to the whole years, months or days around the events, by the unit of the ticks.
  • to?: DateInput | undefined
  • scale?: "time" | "order" | undefined'time' puts each event at its date. 'order' puts the events at equal steps in date order, for events that are crowded in time: each one has its date under the line as the film wrote it, and the line says "not to scale" at its end. Defaults to time.
  • unit?: DateUnit | undefinedWhat a tick is, for scale 'time': the start of a year, of a month, or of a day. Without it, the span of the line decides: days up to 45 days, months under 2 years, and years from 2 years.
  • size?: number | undefinedText size of the labels. The notes and the texts under the line are a little smaller. Defaults to 26.
  • levels?: number | undefinedHow many heights the labels may take at each side of the line. The object uses as few as the labels need. Defaults to 3.
  • rows?: number | undefinedThe most rows of marks: the line, and the rows over it. A mark that would touch an earlier mark goes one row up, and the object has as many rows as the marks need, up to this number. Defaults to 10.
  • cursor?: boolean | undefinedDraw the cursor. With false, no cursor is ever drawn, and the events still appear at their dates. On by default.
  • accent?: ColorInput | undefinedThe color of the event that light() lights. Defaults to orange.
  • font?: FontFamily | undefined

DateMarktype

The mark of an event on the line.

type DateMark = "dot" | "ring" | "star"

DateUnittype

What a tick of the line is: the start of a year, of a month, or of a day.

type DateUnit = "year" | "month" | "day"

decimalfunction

A number readout that follows a function of the timeline, drawn fresh each frame.

function decimal(read: () => number, options?: DecimalOptions): Node

DecimalOptionsinterface

  • digits?: number | undefined
  • size?: number | undefined
  • color?: ColorInput | undefined
  • font?: FontFamily | undefinedDefaults to mono, in every film: a number that changes keeps its width in mono.
  • prefix?: string | undefined
  • suffix?: string | undefined

donutfunction

function donut(data: readonly PieDatum[], options?: PieOptions): PieChart

dotChartfunction

Dots on a shared axis, one row per item, with a line for each interval: dotChart([{ label: 'blocks', value: 0.89, low: 0.87, high: 0.91 }]).

function dotChart(data: readonly DotDatum[], options?: DotChartOptions): DotChart

DotChartclass

One row per item: its label, a dot at its value on a shared axis, and a line for its interval. It shows many scores with their uncertainty in less room than bars, and its axis does not have to start at zero. The rows keep the order of the data, so sort the data to rank it. enter() brings the rows in one by one. scale: 'log' gives each power of ten the same room, for values that differ by many powers of ten.

new DotChart(data
  • rows: Node[]One node per item, which holds its label, its interval and its dot.
  • labels: Node[]
  • dots: Node[]
  • intervals: (Node | null)[]The interval of each item, or null for an item that has none.
  • axis: NodeThe axis line, the grid, the ticks and their numbers, and the axis label.
  • domain: readonly [number, number]The two ends of the axis, as values.
  • labelsOf(part: Node): readonly Node[]The label, the dot and the interval of one row belong together, so a light on one of them keeps the row bright.
  • p(value: number, row: number): [number, number]The place of a value in a row, in the coordinates of the chart. Row 0 is the first item. On a log axis, the value must be more than 0.
  • enter(options?: AnimOptions): AnimThe axis fades in, then the rows arrive one after another, from the first to the last.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): DotChart
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): DotChart
  • drop(child: Node): DotChart
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): DotChartA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): DotChartSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): DotChart
  • moveTo(target: Node | Vec): DotChartMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): DotChartMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): DotChartScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): DotChartRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): DotChartScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): DotChartPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): DotChartLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): DotChartLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): DotChart
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): DotChart
  • color(color: ColorInput): DotChartRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): DotChart
  • glow(radius: number, color?: ColorInput | undefined): DotChartSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): DotChart
  • zIndex(value: number): DotChart
  • pin(): DotChartPin to the screen so the camera does not move this node.
  • hide(): DotChart
  • show(): DotChart
  • named(label: string): DotChart

DotChartOptionsinterface

  • width?: number | undefinedThe length of the axis. The labels are outside it, at the left. Defaults to 900.
  • height?: number | undefinedThe height of all rows together. Defaults to 1.65 of labelSize for each row.
  • labelSize?: number | undefinedText size of the labels and the ticks. Defaults to 20.
  • color?: ColorInput | undefinedThe color of the axis. Defaults to faint.
  • dotColor?: ColorInput | undefinedThe color of a dot that has none of its own. Defaults to blue.
  • domain?: readonly [number, number] | undefinedThe values at the two ends of the axis. Defaults to a round range that holds every value and interval. On a log axis, the default is the powers of ten around them.
  • ticks?: number | readonly number[] | undefinedAbout how many ticks to draw, or the values to mark. Defaults to about 5. On a log axis, the default is the powers of ten in the domain, and every second or third one when there are more than 8.
  • format?: ((value: number) => string) | undefinedHow to write a tick. On a log axis, the default is a short form: 1, 10, 100, 1k, 1M, and 0.01.
  • scale?: "linear" | "log" | undefined'log' gives each power of ten the same room, for values that differ by more than about a hundred times. Every value, interval end, domain end and tick must then be more than 0. Say on screen that the axis is logarithmic, for example in xLabel. Defaults to linear.
  • xLabel?: string | undefinedA line under the axis that says what the value is and which way is better.
  • grid?: boolean | undefinedDraw a faint vertical line at each tick. On by default.
  • font?: FontFamily | undefined

DotDatuminterface

  • label: string
  • value: number
  • low?: number | undefinedThe two ends of an interval around the value, such as a 95% confidence interval. Give both or none.
  • high?: number | undefined
  • color?: ColorInput | undefinedDefaults to the dotColor of the chart.
  • hollow?: boolean | undefinedDraw a ring in place of a filled dot, to tell a second group apart.

epicyclesfunction

function epicycles(terms: readonly FourierTerm[], options: EpicyclesOptions): Epicycles

Epicyclesclass

Circles on circles: the tip of the chain draws the original shape.

new Epicycles(terms
  • terms: readonly FourierTerm[]
  • outline(): PathThe reconstructed outline as a path, for morphing the drawing into something else.
  • point(u: number): [number, number]
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Epicycles
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Epicycles
  • drop(child: Node): Epicycles
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): EpicyclesA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): EpicyclesSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Epicycles
  • moveTo(target: Node | Vec): EpicyclesMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): EpicyclesMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): EpicyclesScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): EpicyclesRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): EpicyclesScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): EpicyclesPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): EpicyclesLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): EpicyclesLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Epicycles
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Epicycles
  • color(color: ColorInput): EpicyclesRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Epicycles
  • glow(radius: number, color?: ColorInput | undefined): EpicyclesSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Epicycles
  • zIndex(value: number): Epicycles
  • pin(): EpicyclesPin to the screen so the camera does not move this node.
  • hide(): Epicycles
  • show(): Epicycles
  • named(label: string): Epicycles
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

EpicyclesOptionsinterface

  • u: () => numberProgress as a function of the timeline. 1 means one full trip.
  • circles?: number | undefinedMost circles to draw. The sum still uses every term.
  • circleColor?: ColorInput | undefined
  • armColor?: ColorInput | undefined
  • traceColor?: ColorInput | undefined
  • traceWidth?: number | undefined
  • glow?: number | undefined
  • tail?: number | undefinedShare of a trip to keep lit. Use 1 for the whole drawing.
  • samples?: number | undefined

eventLogfunction

A list of records that grows, with states: eventLog([{ id: 1, name: 'WorkflowExecutionStarted' }, { ids: [2, 3, 4], name: 'workflow task' }], { title: 'event history', visible: 12 }), then log.append({ id: 5, name: 'ActivityTaskScheduled', detail: 'chargeCard', state: 'new' }).

function eventLog(rows?: readonly LogRow[], options?: EventLogOptions): EventLog

EventLogclass

A list of records with an identity, such as the event history of a workflow, the steps of an agent, or the life of a sandbox. A row has an id, a name, one short detail, and a state that sets its color and its mark. append() adds rows at the bottom, mark() changes the state of rows, fold() puts rows that follow each other into one line, focus() moves one outline to a row, and scrollTo() moves the window to a row. The window shows visible lines. When the list has more, the oldest rows leave at the top, and the first line says how many are above. The list changes its rows one change at a time: two changes of the rows whose times overlap are an error. .at() places the middle of the panel. The panel has its full height from the start.

new EventLog(rows?
  • frame: NodeThe panel: its fill and its border.
  • rules: Node[]The line under the title and the line over the footer.
  • title: Node | null
  • footer: Node | nullThe line under the list that follows the count, or null.
  • earlier: NodeThe first line of a window with rows above it: the number of those records.
  • later: NodeThe last line of a window with rows under it: the number of those records.
  • outline: NodeWhat focus() moves: the outline around a row, or the band behind it.
  • pitch: numberThe distance from one row to the next. A code block beside the list can take it: leading: log.pitch / size.
  • rows: LogRowNode[]The nodes of the lines in the window, from the top, after the changes that are scheduled so far. A fold is one node.
  • count: numberThe number of records that show, after the changes that are scheduled so far. A fold counts each record that it holds. A row that waits for show() does not count.
  • ids: Id[]The ids of the records, in order, after the changes that are scheduled so far.
  • row(id: Id): LogRowNodeThe node of the line that shows a record, after the changes that are scheduled so far. For a record in a fold, that is the line of the fold. A row that is out of the window is an error: scrollTo() brings it in.
  • p(id: Id, side?: "left" | "right"): [number, number]The point where a connector to a row ends: on the left or the right border of the panel, at the middle height of the row, in the coordinates of the list. It is the place after the changes that are scheduled so far, and it does not follow the row. For a fold, any of its ids gives the point. Defaults to the left.
  • find(test: (row: LogRow) => boolean): Id[]The ids of the rows that a function picks, in the order of the list, after the changes that are scheduled so far: one id for a row, and each id of a fold. So mark(find(test), state) changes the same records as mark(test, state). The function gets a row as the list shows it: with its id, its ids, its state and its family. A fold is one row there. A row that waits for show() has shown: false.
  • clone(): EventLogA copy with its own rows and its own bookkeeping, so a change of the copy does not change the list.
  • enter(options?: AnimOptions): AnimThe panel, the title and the footer arrive, and then the rows of the window.
  • append(rows: LogRow | readonly LogRow[], options?: AnimOptions): AnimRows arrive at the bottom, one after another. In a full window, the oldest rows leave at the top as the new ones arrive, and all rows move as one. The first line then says how many records are above. lag: 0 brings the rows of one call together, as a group. A window that scrollTo() moved goes back to the end first. An id that the list has is an error.
  • show(): EventLog show(which: Id | readonly Id[] | ((row: LogRow) => boolean), options?: AnimOptions | undefined): AnimRows that had their place and did not show arrive there, one after another, as the rows of append arrive. which is an id, a list of ids, or a function of a row, as mark takes. No row moves, and the window does not move: a row that is out of it changes the count of its side. The footer and the two counts count the rows that show. A row that shows already does not change. With no argument, the list itself shows, as any node does.
  • mark(which: Id | readonly Id[] | ((row: LogRow) => boolean), state: string, options?: AnimOptions): AnimRows change state: the color of the name cross-fades, and so does the mark at the left. which is an id, a list of ids, or a function of a row, which the list calls when the change is scheduled. So a second change in one sequence sees the states that the first one left. An id names one record. In a closed fold, the record takes the state, and the fold shows the look of the record that was marked last. After unfold(), each record has its own state. The function gets a row as find() gives it. A fold is one row there, and a fold that it picks takes the state with all its records. A row that already has the state does not change. lag makes the rows change one after another, in the order of the list.
  • fold(ids: readonly Id[], label?: string | LogRowFields | undefined, options?: AnimOptions): AnimRows that follow each other become one line: a fold, with its first id, its last id, and a name, such as "2 to 4 workflow task". The label is the name, or the fields of the row of the fold: a name, a detail, a time, a state, a family. Without a state, the fold has the state of its first row. With no label, a fold that unfold() opened closes again as it was. The fold counts as one line of the window, and as its records in count. The ids can be in any order. Rows that do not follow each other, and a row that is in a fold, are errors.
  • unfold(firstId: Id, options?: AnimOptions): AnimA fold opens into its rows. firstId is the first id of the fold. fold() with the same ids closes it again.
  • scrollTo(id: Id, options?: AnimOptions): AnimThe window moves to a row that is out of it, and the row shows: at the top of the window for a row that was above, and at its end for a row that was under. The first line says how many records are above the window, and the last line says how many are under it. A row that is in the window moves nothing, so such a call can play with any change. append() brings the window back to the end.
  • focus(id: Id | null, options?: AnimOptions): AnimThe outline goes to a row, and stays there until the next focus. focus(null) takes it away. The outline is with its row at every frame: it moves with a row that scrolls, arrives with a row that arrives, and leaves with a row that leaves the window. On its way to another row it fades out at the first and comes in at the second, so it does not cross the text of the rows between the two. Each call takes the place of the outline and how much of it shows back from its time on, whatever the film did to the node outline before. A leading that is too small for the outline is an error here.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): EventLog
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): EventLog
  • drop(child: Node): EventLog
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): EventLogSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): EventLog
  • moveTo(target: Node | Vec): EventLogMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): EventLogMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): EventLogScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): EventLogRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): EventLogScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): EventLogPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): EventLogLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): EventLogLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): EventLog
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): EventLog
  • color(color: ColorInput): EventLogRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): EventLog
  • glow(radius: number, color?: ColorInput | undefined): EventLogSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): EventLog
  • zIndex(value: number): EventLog
  • pin(): EventLogPin to the screen so the camera does not move this node.
  • hide(): EventLog
  • named(label: string): EventLog
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

EventLogOptionsinterface

  • width?: number | undefinedThe width of the list. Defaults to 640.
  • visible?: number | undefinedHow many lines show at once. More rows scroll: the oldest leave at the top, and the first line then says how many are above. Defaults to 10.
  • size?: number | undefinedText size. Defaults to 24.
  • leading?: number | undefinedThe height of a row, as a part of size. Defaults to the height that the outline of the focus needs, about 1.9. A list with focusLook: 'band', or with no focus, can take less, such as 1.5.
  • states?: Record<string, LogState> | undefinedThe states and their looks. Defaults to LOG_STATES.
  • title?: string | undefinedA title over the list, such as 'event history'.
  • footer?: ((count: number) => string) | undefinedA line under the list that follows the count of the rows that show, such as (count) => ${count} events.
  • titleSize?: number | undefinedThe text size of the title, the footer and the counts of the rows out of the window. Defaults to 0.85 of size.
  • nameWidth?: number | undefinedThe room of the names. A longer name is cut with an ellipsis. Defaults to the longest name of the first rows, and to 60% of the width at most. The details have the room that is left. The name of a row with no detail may go on to the end of the details.
  • idWidth?: number | undefinedThe room of the ids. A longer id is an error. Defaults to the longest id of the first rows, and to two digits at least.
  • timeWidth?: number | undefinedThe room of the times. A longer time is an error. Defaults to the longest time of the first rows. Set it for a list that gets its first time later.
  • ellipsis?: boolean | undefinedWith false, a name or a detail that does not fit is an error, and not a text with an ellipsis. Defaults to true.
  • focusLook?: "outline" | "band" | undefinedWhat focus() draws: an outline around the row, or a band behind it. Defaults to outline.
  • font?: FontFamily | undefinedThe font of the title, the footer and the details. Defaults to the font of the film. The ids, the names and the times are in mono.
  • detailFont?: FontFamily | undefinedThe font of the details, for a detail that is data, such as the output of a run. Defaults to font.

FieldFntype

type FieldFn = (x: number, y: number, t: number) => Vec

FilmCheckOptionsinterface

  • times?: readonly number[] | undefinedInspect exactly these times, in seconds, in place of the automatic sampling.
  • samples?: number | undefinedAdd this many evenly spaced samples to the moments at rest.
  • motion?: boolean | undefinedAlso inspect every frame. A problem that appears only while something moves is a warning, because the check cannot tell a collision from one picture that replaces another. A stretch of 0.2 seconds or more with nothing visible is reported as film.blank. Text that leaves before a viewer can read it is reported as film.text_brief.
  • readingSpeed?: number | undefinedFor a motion scan, the characters that a viewer reads in one second. Text that leaves before a reader at this speed gets to its end is reported as film.text_brief. Defaults to 20, the fastest speed that subtitle guides allow for an adult viewer. 0 turns the rule off.
  • stepped?: boolean | undefinedThe film plays one chapter at a time, as a deck does: the player waits for the viewer on the first frame of each chapter after the start. Text that is up at such a stop has all the time that the viewer gives it, so film.text_brief does not report it.
  • contentTop?: number | undefinedFor a motion scan, the canvas y where the content starts. Marks above it, such as a heading that stays up, do not count as content when the scan looks for blank frames.
  • textMargin?: number | undefinedThe least distance between text and an edge of the frame, in canvas pixels. Text that is nearer is reported as film.text_edge. Defaults to 2% of the shorter side of the frame. 0 turns the rule off.
  • imageNetwork?: "allow" | "deny" | undefined
  • look?: Look | "midnight" | "paper" | "blueprint" | "chalk" | "neon" | undefined
  • fps?: number | undefined
  • bloom?: number | undefined
  • background?: string | null | undefined

FilmCheckReportinterface

  • ok: boolean
  • width: number
  • height: number
  • duration: number
  • sampled: number[]The moments at rest that were inspected, in seconds.
  • frames?: number | undefinedThe number of frames that a motion scan inspected.
  • diagnostics: FilmDiagnostic[]
  • summary: { errors: number; warnings: number; }

FilmDiagnosticinterface

  • code: FilmDiagnosticCode
  • severity: "error" | "warning"
  • message: string
  • time: numberFirst sampled time with this problem, in seconds.
  • until: numberLast sampled time with this problem, in seconds.
  • box: BoundsWhere to look, in canvas pixels with the origin at the top left.
  • stage: { x: number; y: number; }The center of the box in authoring coordinates, with (0, 0) at mid-frame.
  • text?: string | undefinedThe text involved, when there is any.
  • other?: string | undefinedThe second text involved in an overlap.
  • motion?: { spans: number; seconds: number; } | undefinedSet when a motion scan finds the problem only while something moves. time and until then bound the longest stretch. spans counts the separate stretches, and seconds is their total length. For film.text_brief, time and until bound the first stretch, or a whole row of texts that follow each other. spans counts the stretches or the texts, and seconds is the time that they were readable.

FilmDiagnosticCodetype

type FilmDiagnosticCode = "film.off_canvas" | "film.text_edge" | "film.text_overlap" | "film.text_crossed" | "film.text_brief" | "film.missing_glyph" | "film.blank" | "film.image_asset"

fourierfunction

Discrete Fourier transform of a closed outline, largest terms first. Sample the points evenly along the outline, for example with samplePath.

function fourier(points: readonly Vec[], options?: { terms?: number | undefined; }): FourierTerm[]

fourierPointfunction

Value of a Fourier series at u, where u from 0 to 1 is one trip around the shape.

function fourierPoint(terms: readonly FourierTerm[], u: number): [number, number]

FourierTerminterface

  • freq: numberWhole turns per trip around the shape.
  • amp: number
  • phase: number

fromComponentfunction

Render any Vizmatic TSX component and return it as animatable vector nodes, so every existing diagram and chart can be written on, faded, and morphed. It runs in Node only, because it needs the layout engine: const flow = await fromComponent(<Flow c={c} stages={stages} />, { width: 900, height: 300 }) s.play(write(flow))

function fromComponent(element: ReactNode, options: FromComponentOptions): Promise<SvgNode>

FromComponentOptionsinterface

  • width: numberLayout size of the component, in pixels.
  • height: number
  • theme?: ThemeMode | undefined
  • canvas?: RenderBackground | undefinedCanvas behind the component. Transparent by default, so it sits on the film.
  • scale?: number | undefinedScale on stage. Layout stays at width and height, so dense text stays small.
  • center?: boolean | undefinedCenter the picture on the node's origin. On by default.
  • background?: boolean | undefinedKeep a full-canvas background rectangle. Films have their own, so it is dropped by default.
  • splitGlyphs?: boolean | undefinedSplit filled multi-glyph outlines into one node per glyph, so text writes letter by letter.
  • font?: FontFamily | undefinedThe font of the text elements. Defaults to the font that the film names. Text that the SVG sets in a monospace family is code, and it is then mono. With no font from this option or from the film, every text is sans, as it was before films had a font: the importer does not read which family the SVG names.

fromSvgfunction

Turn SVG markup into stage nodes. Each shape becomes a leaf whose origin is its center, so it can be drawn, faded, scaled, and morphed like anything else. Filters and masks are skipped, because shapes draw without them.

function fromSvg(source: string, options?: FromSvgOptions): SvgNode

FromSvgOptionsinterface

  • width?: number | undefinedFit into this box, keeping proportions. Defaults to the SVG's own size.
  • height?: number | undefined
  • center?: boolean | undefinedCenter the picture on the node's origin. On by default.
  • background?: boolean | undefinedKeep a full-canvas background rectangle. Films have their own, so it is dropped by default.
  • splitGlyphs?: boolean | undefinedSplit filled multi-glyph outlines into one node per glyph, so text writes letter by letter.
  • font?: FontFamily | undefinedThe font of the text elements. Defaults to the font that the film names. Text that the SVG sets in a monospace family is code, and it is then mono. With no font from this option or from the film, every text is sans, as it was before films had a font: the importer does not read which family the SVG names.

graphfunction

function graph(nodes: readonly GraphNodeSpec[], edges: readonly GraphEdgeSpec[], options?: GraphOptions): Graph

Graphclass

Nodes and edges with a stable layout. node(id) and edge(from, to) return ordinary nodes, so every verb works on them, and visit and pulseEdge tell an algorithm's story.

new Graph(nodes
  • nodes: Map<string, GraphNode>
  • edges: GraphEdge[]
  • edgeLayer: Node
  • nodeLayer: Node
  • node(id: string): GraphNode
  • edge(from: string, to: string): GraphEdge
  • enter(options?: AnimOptions): AnimNodes pop in by order, and each edge draws as its source is shown.
  • pulseEdge(from: string, to: string, options?: AnimOptions & { color?: ColorInput | undefined; length?: number | undefined; }): AnimA lit signal travels along an edge.
  • visit(id: string, options?: AnimOptions & { color?: ColorInput | undefined; }): AnimMark a node as reached: its color changes and it swells for a moment.
  • moveNode(id: string, to: Vec, options?: AnimOptions): AnimMove a node. Its edges follow, re-routed as straight lines.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Graph
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Graph
  • drop(child: Node): Graph
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): GraphA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): GraphSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Graph
  • moveTo(target: Node | Vec): GraphMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): GraphMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): GraphScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): GraphRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): GraphScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): GraphPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): GraphLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): GraphLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Graph
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Graph
  • color(color: ColorInput): GraphRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Graph
  • glow(radius: number, color?: ColorInput | undefined): GraphSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Graph
  • zIndex(value: number): Graph
  • pin(): GraphPin to the screen so the camera does not move this node.
  • hide(): Graph
  • show(): Graph
  • named(label: string): Graph
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

GraphEdgeclass

new GraphEdge(path?
  • shaft: Node
  • tip: Node | null
  • caption: Node | null
  • from: string
  • to: string
  • tipSize: number
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): GraphEdge
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): GraphEdge
  • drop(child: Node): GraphEdge
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): GraphEdgeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): GraphEdgeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): GraphEdge
  • moveTo(target: Node | Vec): GraphEdgeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): GraphEdgeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): GraphEdgeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): GraphEdgeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): GraphEdgeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): GraphEdgePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): GraphEdgeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): GraphEdgeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): GraphEdge
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): GraphEdge
  • color(color: ColorInput): GraphEdgeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): GraphEdge
  • glow(radius: number, color?: ColorInput | undefined): GraphEdgeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): GraphEdge
  • zIndex(value: number): GraphEdge
  • pin(): GraphEdgePin to the screen so the camera does not move this node.
  • hide(): GraphEdge
  • show(): GraphEdge
  • named(label: string): GraphEdge
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

GraphEdgeSpecinterface

  • from: string
  • to: string
  • label?: string | undefined
  • color?: ColorInput | undefined
  • width?: number | undefined
  • dash?: readonly number[] | undefined
  • directed?: boolean | undefined

GraphNodeclass

new GraphNode(path?
  • shape: Node
  • caption: Node | null
  • halfWidth: number
  • halfHeight: number
  • round: boolean
  • edgePoint(fx: number, fy: number, tx: number, ty: number, pad?: number): VecPoint on this node's outline facing a stage point, in graph space.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): GraphNode
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): GraphNode
  • drop(child: Node): GraphNode
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): GraphNodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): GraphNodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): GraphNode
  • moveTo(target: Node | Vec): GraphNodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): GraphNodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): GraphNodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): GraphNodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): GraphNodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): GraphNodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): GraphNodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): GraphNodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): GraphNode
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): GraphNode
  • color(color: ColorInput): GraphNodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): GraphNode
  • glow(radius: number, color?: ColorInput | undefined): GraphNodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): GraphNode
  • zIndex(value: number): GraphNode
  • pin(): GraphNodePin to the screen so the camera does not move this node.
  • hide(): GraphNode
  • show(): GraphNode
  • named(label: string): GraphNode
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

GraphNodeSpecinterface

  • id: string
  • label?: string | undefined
  • color?: ColorInput | undefined
  • radius?: number | undefinedCircle radius.
  • width?: number | undefinedBox size. A node with a width draws as a rounded box.
  • height?: number | undefined
  • at?: Vec | undefinedManual position, used by layout: 'manual'.
  • math?: boolean | undefinedTypeset the label as math.

GraphOptionsinterface

  • layout?: "dagre" | "force" | "circle" | "manual" | undefined
  • direction?: "LR" | "RL" | "TB" | "BT" | undefined
  • width?: number | undefinedBounding size for force and circle layouts.
  • height?: number | undefined
  • nodeGap?: number | undefined
  • rankGap?: number | undefined
  • radius?: number | undefined
  • labelSize?: number | undefined
  • edgeLabelSize?: number | undefined
  • directed?: boolean | undefined
  • nodeColor?: ColorInput | undefined
  • edgeColor?: ColorInput | undefined
  • seed?: number | undefined
  • fillOpacity?: number | undefinedFill nodes softly with their color instead of leaving them hollow.
  • font?: FontFamily | undefinedThe font of the node labels. Defaults to the font of the film.
  • edgeFont?: FontFamily | undefinedThe font of the edge labels. Defaults to the font that the film names, and to mono in a film that names none.

GridLegendOptionsinterface

  • size?: number | undefinedText size of the names. The sample cells are a little smaller. Defaults to 26.
  • gap?: number | undefinedRoom between a name and the next sample cell. Defaults to 1.3 of size.
  • font?: FontFamily | undefined

GridStateinterface

  • color: ColorInput
  • fill?: number | undefinedOpacity of the fill, 0 to 1. 0 draws the outline only. Defaults to 0.7.
  • dash?: boolean | undefinedA dashed outline, for a thing that is not there.

heatmapfunction

function heatmap(values: readonly (readonly number[])[], options?: HeatmapOptions): Heatmap

Heatmapclass

new Heatmap(values
  • cells: Node[][]
  • rowLabels: Node[]
  • columnLabels: Node[]
  • numbers: Node[][]
  • rowCount: number
  • colCount: number
  • colorFor(value: number): Rgba
  • cell(row: number, column: number): Node
  • row(index: number): Node[]
  • col(index: number): Node[]
  • enter(options?: AnimOptions): AnimCells fade in along the diagonal.
  • update(values: readonly (readonly number[])[], options?: AnimOptions): AnimRecolor every cell to new values.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Heatmap
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Heatmap
  • drop(child: Node): Heatmap
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): HeatmapA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): HeatmapSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Heatmap
  • moveTo(target: Node | Vec): HeatmapMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): HeatmapMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): HeatmapScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): HeatmapRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): HeatmapScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): HeatmapPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): HeatmapLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): HeatmapLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Heatmap
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Heatmap
  • color(color: ColorInput): HeatmapRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Heatmap
  • glow(radius: number, color?: ColorInput | undefined): HeatmapSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Heatmap
  • zIndex(value: number): Heatmap
  • pin(): HeatmapPin to the screen so the camera does not move this node.
  • hide(): Heatmap
  • show(): Heatmap
  • named(label: string): Heatmap
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

HeatmapOptionsinterface

  • cell?: number | undefinedCell edge in stage pixels.
  • cellWidth?: number | undefined
  • cellHeight?: number | undefined
  • gap?: number | undefined
  • colors?: readonly ColorInput[] | undefined
  • domain?: readonly [number, number] | undefinedValue range for the color ramp.
  • values?: boolean | undefinedPrint values in cells.
  • format?: ((value: number) => string) | undefined
  • valueSize?: number | undefined
  • rowLabels?: readonly string[] | undefined
  • columnLabels?: readonly string[] | undefined
  • labelSize?: number | undefined
  • columnLabelAngle?: number | undefinedTilt column labels so long names fit, in radians.
  • radius?: number | undefined
  • font?: FontFamily | undefinedThe font of the row and the column labels. Defaults to the font of the film. The values in the cells are in mono.

HighlightOptionsinterface

  • color?: ColorInput | undefined
  • opacity?: number | undefined
  • pad?: number | undefinedExtra room around the target.
  • radius?: number | undefined
  • from?: "left" | "right" | undefinedKeep the mark afterwards. By default it stays until you fade it.
  • duration?: number | undefined
  • ease?: Ease | undefined
  • lag?: number | undefinedFraction of one item's time between the starts of consecutive items.

highlightSweepfunction

A marker stroke sweeps across a target and stays behind it. .mark is the node, so it can be faded out later.

function highlightSweep(target: Node | readonly Node[], options?: HighlightOptions): Anim & { mark: Node; }

histogramfunction

function histogram(samples: readonly number[], options?: HistogramOptions): Histogram

Histogramclass

A distribution that can fill up over time. fillUp() drops the samples in, in order, so bars rise exactly as the data accumulates.

new Histogram(samples
  • shown: Value
  • bins: number
  • range: readonly [number, number]
  • chartWidth: number
  • chartHeight: number
  • axis: Node
  • total: number
  • peak: number
  • p(value: number, count: number): [number, number]Local stage point for a value and a count.
  • fillUp(options?: AnimOptions & { count?: number | undefined; }): AnimSamples arrive in order, from none to count (all of them by default).
  • curve(f: (x: number) => number, options?: { color?: ColorInput | undefined; width?: number | undefined; samples?: number | undefined; }): NodeOverlay a curve, such as the fitted density, on the same axes. f returns a count.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Histogram
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Histogram
  • drop(child: Node): Histogram
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): HistogramA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): HistogramSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Histogram
  • moveTo(target: Node | Vec): HistogramMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): HistogramMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): HistogramScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): HistogramRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): HistogramScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): HistogramPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): HistogramLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): HistogramLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Histogram
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Histogram
  • color(color: ColorInput): HistogramRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Histogram
  • glow(radius: number, color?: ColorInput | undefined): HistogramSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Histogram
  • zIndex(value: number): Histogram
  • pin(): HistogramPin to the screen so the camera does not move this node.
  • hide(): Histogram
  • show(): Histogram
  • named(label: string): Histogram
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

HistogramOptionsinterface

  • bins?: number | undefined
  • range?: readonly [number, number] | undefined
  • max?: number | undefinedFixes the top of the scale, for a stable axis while samples arrive.
  • gap?: number | undefined
  • ticks?: number | undefinedNumber of x tick labels.
  • colors?: readonly ColorInput[] | undefined
  • width?: number | undefined
  • height?: number | undefined
  • labelSize?: number | undefinedText size for direct labels and ticks.
  • color?: ColorInput | undefined
  • font?: FontFamily | undefinedThe font of the labels and the ticks. Defaults to the font of the film. A value that the chart prints is in mono.

infoBoxfunction

function infoBox(options: InfoBoxOptions): InfoBox

InfoBoxclass

A compact node for system stories: a title, a status, and rows of labeled metrics at reading size. It packs information like an engineering figure, not a slide. For a talk, raise size and the whole box scales with it.

new InfoBox(options
  • frame: Node
  • accentBar: Node | null
  • titleNode: Node
  • subtitleNode: Node | null
  • badgeNode: Node | null
  • rowLabels: Node[]
  • rowValues: (Node | null)[]
  • meters: Node[]
  • tagNodes: Node[]
  • boxWidth: number
  • boxHeight: number
  • port(side: Edge, at?: number): [number, number]Stage point on one side of the box. at moves along the side, from -1 to 1.
  • enter(options?: AnimOptions): AnimThe frame draws, then the contents settle in, top to bottom.
  • setValue(row: number, value: string, options?: AnimOptions & { tone?: ColorInput | undefined; }): AnimChange a row's value in place. Matching digits slide, and the others cross-fade.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): InfoBox
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): InfoBox
  • drop(child: Node): InfoBox
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): InfoBoxA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): InfoBoxSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): InfoBox
  • moveTo(target: Node | Vec): InfoBoxMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): InfoBoxMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): InfoBoxScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): InfoBoxRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): InfoBoxScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): InfoBoxPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): InfoBoxLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): InfoBoxLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): InfoBox
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): InfoBox
  • color(color: ColorInput): InfoBoxRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): InfoBox
  • glow(radius: number, color?: ColorInput | undefined): InfoBoxSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): InfoBox
  • zIndex(value: number): InfoBox
  • pin(): InfoBoxPin to the screen so the camera does not move this node.
  • hide(): InfoBox
  • show(): InfoBox
  • named(label: string): InfoBox
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

InfoBoxOptionsinterface

  • title: string
  • subtitle?: string | undefined
  • badge?: string | undefinedShort status tag at the top right, such as "p99" or "degraded".
  • badgeTone?: ColorInput | undefined
  • rows?: readonly InfoRow[] | undefined
  • tags?: readonly string[] | undefinedSmall chips along the bottom.
  • width?: number | undefinedWidth in stage pixels. Grows to fit the content when omitted.
  • size?: number | undefinedBase text size. Everything scales from it. Raise it for a presentation.
  • accent?: ColorInput | undefinedColor of the left edge.
  • fill?: ColorInput | undefined
  • border?: ColorInput | undefined
  • radius?: number | undefined
  • font?: FontFamily | undefinedThe font of the title and the row labels. Defaults to the font of the film. The subtitle, the badge, the values and the tags are in mono.

InfoRowinterface

  • label: string
  • value?: string | undefined
  • tone?: ColorInput | undefinedColor for the value.
  • meter?: number | undefinedThin meter under the row, from 0 to 1.
  • spark?: readonly number[] | undefinedSmall trend drawn at the end of the row.

labeledDotfunction

function labeledDot(label: string, options?: LabeledDotOptions): LabeledDot

LabeledDotclass

A point with a label. The node's origin stays on the point.

new LabeledDot(label
  • mark: Node
  • caption: Node
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): LabeledDot
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): LabeledDot
  • drop(child: Node): LabeledDot
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): LabeledDotA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): LabeledDotSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): LabeledDot
  • moveTo(target: Node | Vec): LabeledDotMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): LabeledDotMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): LabeledDotScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): LabeledDotRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): LabeledDotScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): LabeledDotPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): LabeledDotLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): LabeledDotLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): LabeledDot
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): LabeledDot
  • color(color: ColorInput): LabeledDotRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): LabeledDot
  • glow(radius: number, color?: ColorInput | undefined): LabeledDotSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): LabeledDot
  • zIndex(value: number): LabeledDot
  • pin(): LabeledDotPin to the screen so the camera does not move this node.
  • hide(): LabeledDot
  • show(): LabeledDot
  • named(label: string): LabeledDot
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

LabeledDotOptionsinterface

  • color?: ColorInput | undefined
  • radius?: number | undefined
  • side?: Side | undefined
  • gap?: number | undefined
  • size?: number | undefined
  • plain?: boolean | undefined
  • font?: FontFamily | undefinedThe font of a plain label. Defaults to the font of the film.
  • labelColor?: ColorInput | undefined

Laneinterface

  • name: string
  • color?: ColorInput | undefinedThe color of the spans and the marks of the lane. Defaults to blue.

LaneBoundaryinterface

A line along the time area between two lanes, such as the line between user space and the kernel.

  • between: readonly [LaneRef, LaneRef]The two lanes that the boundary is between. They are neighbors.
  • label?: string | undefinedText after the right end of the line, outside the time area.
  • color?: ColorInput | undefinedDefaults to yellow.
  • count?: boolean | undefinedShow the number of handoffs that crossed the boundary so far, after the label, and a tick on the line for each one.

LaneEventtype

type LaneEvent = { lane: LaneRef; start: number; end: number; label?: string | undefined; labelSide?: LaneLabelSide | undefined; color?: ColorInput | undefined; open?: boolean | undefined; idle?: boolean | undefined; } | { from: LaneRef; to: LaneRef; at: number; label?: string | undefined; labelSide?: LaneLabelSide | undefined; color?: ColorInput | undefined; dashed?: boolean | undefined; } | { lane: LaneRef; at: number; label?: string | undefined; labelSide?: LaneLabelSide | undefined; color?: ColorInput | undefined; }

LaneEventNodeclass

One event of a Lanes object. It is hidden until the cursor reaches it.

new LaneEventNode(kind: "mark" | "span" | "handoff", shape
  • kind: "mark" | "span" | "handoff"
  • shape: NodeThe bar of a span, the arrow of a handoff, or the dot of a mark.
  • text: Node | nullThe label of the event, or null when it has none.
  • tip: Node | nullThe arrow head of an open span that reaches the last end of the domain.
  • edge: Node | nullThe dashed outline of an idle span.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): LaneEventNode
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): LaneEventNode
  • drop(child: Node): LaneEventNode
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): LaneEventNodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): LaneEventNodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): LaneEventNode
  • moveTo(target: Node | Vec): LaneEventNodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): LaneEventNodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): LaneEventNodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): LaneEventNodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): LaneEventNodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): LaneEventNodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): LaneEventNodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): LaneEventNodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): LaneEventNode
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): LaneEventNode
  • color(color: ColorInput): LaneEventNodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): LaneEventNode
  • glow(radius: number, color?: ColorInput | undefined): LaneEventNodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): LaneEventNode
  • zIndex(value: number): LaneEventNode
  • pin(): LaneEventNodePin to the screen so the camera does not move this node.
  • hide(): LaneEventNode
  • show(): LaneEventNode
  • named(label: string): LaneEventNode
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

LaneLabelSidetype

Where the label of an event goes, when the film must choose. For a span: over the bar, under it, or beside it at its left or its right end. For a handoff: at the left or the right of its arrow, and over or under the boundary that the arrow crosses first. For a mark: over the dot, under it, or beside it.

type LaneLabelSide = "left" | "right" | "over" | "under"

LaneReftype

The name of a lane, or its index.

type LaneRef = string | number

lanesfunction

Lanes over time, one per actor, with spans, handoffs and marks: lanes(['guest', 'KVM'], [{ lane: 'guest', start: 0, end: 30, label: 'runs' }, { from: 'guest', to: 'KVM', at: 30, label: 'VM exit' }, { lane: 'KVM', start: 30, end: 42 }]).

function lanes(names: readonly (string | Lane)[], events: readonly LaneEvent[], options?: LanesOptions): Lanes

Lanesclass

Who runs when: one lane per actor, a bar for each span of work, an arrow for each handoff between two lanes, and a dot for each instant. Time runs from left to right. advance(to) moves a cursor to a time and stops there, and what the cursor passes appears, so a narration can step through the sequence. With ticks, the object also draws a time axis, for a chart of durations. With boundaries, it draws a line between two lanes and counts the handoffs that cross it. .at() places the middle of the time area. The names of the lanes are outside it, at the left.

new Lanes(lanes
  • names: Node[]The name of each lane, at the left of the time area.
  • rails: Node[]A faint line along each lane.
  • events: LaneEventNode[]One node per event, in the order given.
  • spans: LaneEventNode[]The events by kind, in the order given.
  • handoffs: LaneEventNode[]
  • marks: LaneEventNode[]
  • boundaries: Node[]One node per boundary: its line, its label, and its counter.
  • counters: (Node | null)[]The number at the right end of each boundary that counts its crossings, or null for a boundary that does not.
  • axis: Node | nullThe axis line, the ticks and their numbers, and the axis label. Null without ticks.
  • cursor: NodeA thin vertical line over all lanes, at the time of the object. The first advance shows it.
  • domain: readonly [number, number]The times at the two ends of the time area.
  • labelsOf(part: Node): readonly Node[]The label of an event belongs to its bar, its arrow, or its dot, so a light on that shape keeps the label bright.
  • time: numberThe time of the cursor after the changes that are scheduled so far. It starts at the first end of the domain.
  • x(time: number): numberThe x of a time, in the coordinates of the object. The middle of the domain is at 0.
  • y(lane: LaneRef): numberThe y of the middle of a lane, in the coordinates of the object. The first lane and the last one are at the same distance from 0.
  • crossings(boundary: string | number): numberHow many handoffs crossed a boundary up to the time of the cursor, after the changes that are scheduled so far. Name the boundary by its index or by its label.
  • enter(options?: AnimOptions): AnimThe names, the lines of the lanes, the boundaries and the axis arrive, lane by lane. No event shows yet.
  • advance(to: number, options?: AnimOptions): AnimThe cursor moves from its time to to, and stops. What it passes appears. A span grows with the cursor. A handoff draws its arrow and a mark shows its dot when the cursor reaches them. A label arrives when its event is complete, and a label inside a bar arrives when the bar starts to grow. All of it is over when the animation ends: when the last event needs time after the cursor reaches it, the cursor stops early.
  • showAll(options?: AnimOptions): AnimThe same as advance to the last end of the domain. It takes 4 seconds when the film gives no duration.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Lanes
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Lanes
  • drop(child: Node): Lanes
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): LanesA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): LanesSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Lanes
  • moveTo(target: Node | Vec): LanesMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): LanesMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): LanesScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): LanesRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): LanesScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): LanesPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): LanesLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): LanesLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Lanes
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Lanes
  • color(color: ColorInput): LanesRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Lanes
  • glow(radius: number, color?: ColorInput | undefined): LanesSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Lanes
  • zIndex(value: number): Lanes
  • pin(): LanesPin to the screen so the camera does not move this node.
  • hide(): Lanes
  • show(): Lanes
  • named(label: string): Lanes

LanesOptionsinterface

  • width?: number | undefinedThe width of the time area. The lane names are outside it, at the left. Defaults to 1400.
  • barHeight?: number | undefinedThe height of the bar of a span. Defaults to 44.
  • pitch?: number | undefinedFrom the middle of one lane to the middle of the next. Defaults to a value with room for the label of a handoff between two bars. Two lanes with a boundary between them are further apart, by 1.25 of the text size.
  • domain?: readonly [number, number] | undefinedThe times at the two ends. Defaults to the range of the events.
  • ticks?: number | readonly number[] | undefinedTicks under the lanes: a count, or the values. Without it, no axis is drawn, for a sequence that is not to scale.
  • format?: ((time: number) => string) | undefinedHow to write a tick.
  • axisLabel?: string | undefinedA line under the axis that names the unit. Without ticks, the axis is a line with this label and no ticks.
  • boundaries?: readonly LaneBoundary[] | undefinedLines between lanes that are neighbors. A handoff crosses each boundary that is between its two lanes.
  • cursor?: boolean | undefinedDraw the cursor. With false, no cursor is ever drawn, and the events still appear at their times. On by default.
  • backing?: ColorInput | null | undefinedThe color of the patches behind the labels, the bars and the arrows of dashes. They hide the cursor and the lines of the lanes there. Defaults to the background of the look. On a panel of another color, give that color. Pass null for no patches, on a background with no single color.
  • size?: number | undefinedText size. Defaults to 26.
  • font?: FontFamily | undefined

legendfunction

A small key. Prefer direct labels. Use this when a figure holds too many marks to label.

function legend(items: readonly LegendItem[], options?: LegendOptions): Node

LegendIteminterface

  • label: string
  • color?: ColorInput | undefined
  • kind?: "dash" | "line" | "swatch" | "dot" | "ring" | undefined

LegendOptionsinterface

  • direction?: "row" | "column" | undefined
  • size?: number | undefined
  • gap?: number | undefined
  • font?: FontFamily | undefinedThe font of the labels. Defaults to the font of the film.

lineChartfunction

function lineChart(series: readonly LineSeries[], options?: LineChartOptions): LineChart

LineChartclass

new LineChart(series
  • lines: Node[]
  • areas: Node[]
  • names: Node[]
  • axis: Node
  • p(x: number, y: number): [number, number]
  • series(name: string): Node
  • enter(options?: AnimOptions): AnimAxes fade in, lines draw left to right, and their labels arrive as each line lands.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): LineChart
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): LineChart
  • drop(child: Node): LineChart
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): LineChartA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): LineChartSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): LineChart
  • moveTo(target: Node | Vec): LineChartMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): LineChartMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): LineChartScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): LineChartRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): LineChartScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): LineChartPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): LineChartLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): LineChartLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): LineChart
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): LineChart
  • color(color: ColorInput): LineChartRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): LineChart
  • glow(radius: number, color?: ColorInput | undefined): LineChartSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): LineChart
  • zIndex(value: number): LineChart
  • pin(): LineChartPin to the screen so the camera does not move this node.
  • hide(): LineChart
  • show(): LineChart
  • named(label: string): LineChart
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

LineChartOptionsinterface

  • x?: readonly [number, number] | undefined
  • y?: readonly [number, number] | undefined
  • xLabel?: string | undefined
  • yLabel?: string | undefined
  • xFormat?: ((x: number) => string) | undefined
  • yFormat?: ((y: number) => string) | undefined
  • xTicks?: number | undefined
  • yTicks?: number | undefined
  • width?: number | undefined
  • height?: number | undefined
  • labelSize?: number | undefinedText size for direct labels and ticks.
  • color?: ColorInput | undefined
  • font?: FontFamily | undefinedThe font of the labels and the ticks. Defaults to the font of the film. A value that the chart prints is in mono.

LineSeriesinterface

  • name?: string | undefined
  • values?: readonly number[] | undefinedY values at x = 0, 1, 2, ...
  • points?: readonly Vec[] | undefined
  • color?: ColorInput | undefined
  • width?: number | undefined
  • dash?: readonly number[] | undefined
  • area?: number | undefinedSoft fill under the line.
  • smooth?: boolean | undefined

LoadedFontinterface

  • unitsPerEm: number
  • ascent: number
  • descent: number
  • lineGap: number
  • glyphFor(code: number): number
  • advance(glyph: number): number
  • kern(left: number, right: number): number
  • outline(glyph: number): GlyphOutline | null

LOG_STATESconst

States for a history that is written and then replayed. Each has its own mark, so color is not the only sign.

const LOG_STATES: { stored: { color: string; mark: "dot"; }; new: { color: string; mark: "dot"; }; answered: { color: string; mark: "check"; }; waiting: { color: string; mark: "ring"; }; failed: { color: string; mark: "cross"; }; }

LogRowtype

One row of the list. A row has an id: an event number, a step number. Or it has ids, and stands for several records that follow each other, such as the three events of one task. Such a row is a fold. It shows its first and its last id, as "2 to 4", and unfold() opens it into its rows. An id is in the list once.

type LogRow = LogRowFields & ({ id: Id; ids?: readonly Id[] | undefined; } | { id?: Id | undefined; ids: readonly Id[]; rows?: readonly LogRow[] | undefined; })

LogRowFieldsinterface

What a row shows and carries, apart from its identity.

  • name: stringThe name of the record, in mono: ActivityTaskCompleted.
  • detail?: string | number | undefinedOne short detail, dim: "ch_1001", attempt 4. A number is taken as its text.
  • time?: string | number | undefinedA time at the right end of the row, dim and in mono: +6.01 s. The list has this column when one of its first rows has a time.
  • state?: string | undefinedDefaults to the first state of states. A row of a fold defaults to the state of the fold.
  • family?: string | undefinedA word that the list does not draw. A film reads it in find() and mark(), to pick the rows of one kind.
  • shown?: boolean | undefinedWith false, the row has its place in the list from the start and does not show. show() brings it in. Defaults to true.

LogRowNodeclass

One line of an EventLog: a row, or a fold.

new LogRowNode(mark
  • content: NodeThe holder of the parts. show() brings it in, for a row that had its place and did not show.
  • mark: NodeThe mark at the left, in the color and the shape of the state. A fold in a state with a dot has three small dots.
  • idText: NodeThe id. For a fold, its first id.
  • range: Node | nullFor a fold, the word "to" and its last id. Null for a row.
  • name: NodeThe name, in the color of the state.
  • detail: Node | nullThe detail, or null for a row that has none.
  • time: Node | nullThe time, or null for a row that has none.
  • parts: Node[]The parts that the line has, from the left: the mark, the id, the range of a fold, the name, the detail, the time.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): LogRowNode
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): LogRowNode
  • drop(child: Node): LogRowNode
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): LogRowNodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): LogRowNodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): LogRowNode
  • moveTo(target: Node | Vec): LogRowNodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): LogRowNodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): LogRowNodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): LogRowNodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): LogRowNodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): LogRowNodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): LogRowNodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): LogRowNodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): LogRowNode
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): LogRowNode
  • color(color: ColorInput): LogRowNodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): LogRowNode
  • glow(radius: number, color?: ColorInput | undefined): LogRowNodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): LogRowNode
  • zIndex(value: number): LogRowNode
  • pin(): LogRowNodePin to the screen so the camera does not move this node.
  • hide(): LogRowNode
  • show(): LogRowNode
  • named(label: string): LogRowNode
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

LogStateinterface

  • color: ColorInput
  • dim?: boolean | undefinedDraw the row dim, for a record that is old or not reached.
  • mark?: "dot" | "ring" | "check" | "cross" | undefinedThe shape of the mark at the left of the row, so that a viewer can tell two states with no color. Defaults to dot.

matrixfunction

function matrix(rows: readonly (readonly (string | number)[])[], options?: MatrixOptions): MatrixNode

MatrixNodeclass

A typeset matrix with real TeX brackets. Each entry is its own node.

new MatrixNode(rows
  • cells: TexNode[][]
  • entries: Node
  • brackets: Node
  • rowCount: number
  • colCount: number
  • cell(row: number, column: number): TexNode
  • row(index: number): TexNode[]
  • col(index: number): TexNode[]
  • setCell(row: number, column: number, value: string | number, options?: AnimOptions): AnimReplace one entry, morphing matching glyphs. Later calls to .cell return the new one.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): MatrixNode
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): MatrixNode
  • drop(child: Node): MatrixNode
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): MatrixNodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): MatrixNodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): MatrixNode
  • moveTo(target: Node | Vec): MatrixNodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): MatrixNodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): MatrixNodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): MatrixNodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): MatrixNodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): MatrixNodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): MatrixNodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): MatrixNodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): MatrixNode
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): MatrixNode
  • color(color: ColorInput): MatrixNodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): MatrixNode
  • glow(radius: number, color?: ColorInput | undefined): MatrixNodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): MatrixNode
  • zIndex(value: number): MatrixNode
  • pin(): MatrixNodePin to the screen so the camera does not move this node.
  • hide(): MatrixNode
  • show(): MatrixNode
  • named(label: string): MatrixNode
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

MatrixOptionsinterface

  • size?: number | undefined
  • color?: ColorInput | undefined
  • gapX?: number | undefinedSpace between columns and rows, as multiples of size.
  • gapY?: number | undefined
  • bracket?: "[" | "(" | "|" | undefined
  • bracketColor?: ColorInput | undefined

morphCodefunction

Morph one version of code into another. Tokens are matched in order, so unchanged code slides to its new place and only real edits fade.

function morphCode(from: CodeBlock, to: CodeBlock, options?: AnimOptions): Anim

narrationfunction

Lay a measured narration on the stage. Each scene gets a clock with phrase cues. Captions and chapters are added to the film, so the MP4 carries them.

function narration(stage: Stage, timing: NarrationTiming, options?: NarrationOptions): Narration

Narrationclass

The timeline of a whole narration.

new Narration(stage
  • scenes: readonly SceneClock[]
  • duration: numberThe end of the last scene, in seconds. Hold the film at least this long, or the voice is cut.
  • lead: number
  • gap: number
  • scene(id: string): SceneClockThe clock of one scene.
  • placements(): { scene: string; beat: number; start: number; end: number; }[]Where every beat's recording starts, in order, for the script that mixes the sound.

NarrationBeatinterface

One take of the voice: a sentence or a short paragraph.

  • say: stringThe text that the voice speaks. Captions use it.
  • duration: numberMeasured length of the recording, in seconds.
  • hold?: number | undefinedSilence after the beat, in seconds, for the viewer to think.
  • words?: readonly NarrationWord[] | undefinedWord times, from the speech engine or from a transcription. Cues need them.

NarrationOptionsinterface

  • lead?: number | undefinedSeconds before the first word, for a logo or an opening picture. Defaults to 0.6.
  • gap?: number | undefinedSeconds of silence between scenes, for the picture to change. Defaults to 0.4.
  • captions?: boolean | undefinedWrite a caption for each spoken line. On by default.
  • captionLength?: number | undefinedLongest caption line, in characters. Defaults to 74.
  • chapters?: boolean | undefinedStart a chapter at each scene that has a title. On by default.

NarrationSceneinterface

  • id: string
  • title?: string | undefinedChapter title. A scene without one does not start a chapter.
  • beats: readonly NarrationBeat[]

NarrationTiminginterface

  • scenes: readonly NarrationScene[]
  • lead?: number | undefinedSeconds before the first word. NarrationOptions.lead overrides it.
  • gap?: number | undefinedSeconds of silence between scenes. NarrationOptions.gap overrides it.

NarrationWordinterface

One spoken word, timed in seconds from the start of its beat.

  • text: string
  • start: number
  • end: number

neuralNetfunction

function neuralNet(layers: readonly number[], options?: NeuralNetOptions): NeuralNet

NeuralNetclass

Layers of neurons joined by hairline weights. forward() runs a signal through it.

new NeuralNet(layers
  • neurons: Node[][]
  • links: Node[][][]Edges between layer i and layer i + 1, by [from][to].
  • edgeLayer: Node
  • neuronLayer: Node
  • captions: Node[]
  • layer(index: number): Node[]
  • enter(options?: AnimOptions): AnimNeurons appear layer by layer, then the weights draw between them.
  • activate(layer: number, values: readonly number[], options?: AnimOptions & { color?: ColorInput | undefined; }): AnimSet how strongly each neuron in a layer fires, from 0 to 1.
  • forward(options?: AnimOptions & { activations?: readonly (readonly number[])[] | undefined; color?: ColorInput | undefined; pulses?: number | undefined; }): AnimRun a signal from the first layer to the last. Pass activations per layer, or let a seeded generator pick plausible ones. The strongest paths light up.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): NeuralNet
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): NeuralNet
  • drop(child: Node): NeuralNet
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): NeuralNetA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): NeuralNetSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): NeuralNet
  • moveTo(target: Node | Vec): NeuralNetMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): NeuralNetMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): NeuralNetScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): NeuralNetRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): NeuralNetScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): NeuralNetPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): NeuralNetLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): NeuralNetLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): NeuralNet
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): NeuralNet
  • color(color: ColorInput): NeuralNetRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): NeuralNet
  • glow(radius: number, color?: ColorInput | undefined): NeuralNetSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): NeuralNet
  • zIndex(value: number): NeuralNet
  • pin(): NeuralNetPin to the screen so the camera does not move this node.
  • hide(): NeuralNet
  • show(): NeuralNet
  • named(label: string): NeuralNet
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

NeuralNetOptionsinterface

  • width?: number | undefined
  • height?: number | undefined
  • radius?: number | undefined
  • collapse?: number | undefinedShow at most this many neurons per layer, with an ellipsis for the rest.
  • colors?: readonly ColorInput[] | undefined
  • edgeColor?: ColorInput | undefined
  • edgeOpacity?: number | undefined
  • layerLabels?: readonly string[] | undefined
  • labelSize?: number | undefined
  • seed?: number | undefinedSeed for the default activations.
  • font?: FontFamily | undefinedThe font of the layer labels. Defaults to the font of the film.

numberLinefunction

function numberLine(options?: NumberLineOptions): NumberLine

NumberLineclass

new NumberLine(options?
  • range: readonly [number, number]
  • length: number
  • line: Node
  • ticks: Node
  • numbers: Node
  • p(value: number): [number, number]Value to local stage coordinates.
  • world(value: number): [number, number]
  • marker(value: Reactive, options?: { color?: ColorInput | undefined; label?: string | undefined; radius?: number | undefined; labelSize?: number | undefined; }): NodeA point on the line. Pass a function to follow a Value over time.
  • interval(from: number, to: number, options?: { color?: ColorInput | undefined; width?: number | undefined; offset?: number | undefined; openLeft?: boolean | undefined; openRight?: boolean | undefined; }): NodeA highlighted span, with open or closed endpoints.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): NumberLine
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): NumberLine
  • drop(child: Node): NumberLine
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): NumberLineA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): NumberLineSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): NumberLine
  • moveTo(target: Node | Vec): NumberLineMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): NumberLineMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): NumberLineScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): NumberLineRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): NumberLineScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): NumberLinePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): NumberLineLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): NumberLineLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): NumberLine
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): NumberLine
  • color(color: ColorInput): NumberLineRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): NumberLine
  • glow(radius: number, color?: ColorInput | undefined): NumberLineSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): NumberLine
  • zIndex(value: number): NumberLine
  • pin(): NumberLinePin to the screen so the camera does not move this node.
  • hide(): NumberLine
  • show(): NumberLine
  • named(label: string): NumberLine
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

NumberLineOptionsinterface

  • range?: readonly [number, number] | undefined
  • length?: number | undefinedOn-screen length in stage pixels.
  • step?: number | undefined
  • labels?: boolean | undefined
  • labelSize?: number | undefined
  • color?: ColorInput | undefined
  • tips?: boolean | undefined
  • width?: number | undefined

NumberPlaneclass

The classic infinite grid. Each line is a dense path, so it bends smoothly under applyMatrix and under warp with a nonlinear function.

new NumberPlane(options?
  • unit: number
  • major: Node
  • minor: Node
  • axes: Node
  • p(x: number, y: number): [number, number]Math coordinates to stage coordinates. y points up on the plane.
  • vector(x: number, y: number, style?: ShapeStyle): NodeA vector drawn from the origin, as an arrow.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): NumberPlane
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): NumberPlane
  • drop(child: Node): NumberPlane
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): NumberPlaneA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): NumberPlaneSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): NumberPlane
  • moveTo(target: Node | Vec): NumberPlaneMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): NumberPlaneMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): NumberPlaneScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): NumberPlaneRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): NumberPlaneScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): NumberPlanePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): NumberPlaneLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): NumberPlaneLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): NumberPlane
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): NumberPlane
  • color(color: ColorInput): NumberPlaneRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): NumberPlane
  • glow(radius: number, color?: ColorInput | undefined): NumberPlaneSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): NumberPlane
  • zIndex(value: number): NumberPlane
  • pin(): NumberPlanePin to the screen so the camera does not move this node.
  • hide(): NumberPlane
  • show(): NumberPlane
  • named(label: string): NumberPlane
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

PAGE_STATESconst

States for pages of memory.

const PAGE_STATES: { absent: { color: string; fill: number; dash: true; }; zero: { color: string; fill: number; }; present: { color: string; fill: number; }; dirty: { color: string; fill: number; }; shared: { color: string; fill: number; }; copied: { color: string; fill: number; }; file: { color: string; fill: number; }; swapped: { color: string; fill: number; }; }

pictogramfunction

A small picture of a concept, such as pictogram('graph', { size: 120, color: 'dim', accent: 'teal' }).

function pictogram(name: "warning" | "ring" | "series" | "chart" | "forecast" | "threshold" | "anomaly" | "logs" | "traces" | "bars" | "table" | "matrix" | "event" | "alert" | "graph" | "dag" | "tree" | "layers" | "pipeline" | "branch" | "service" | "database" | "queue" | "cloud" | "chip" | "vm" | "process" | "kernel" | "memory" | "disk" | "nic" | "network" | "snapshot" | "clone" | "jail" | "wall" | "key" | "stopwatch" | "bolt" | "proxy" | "certificate" | "sleep" | "shard" | "core" | "timer" | "firmware" | "irqchip" | "bus" | "drive" | "floppy" | "serial" | "keyboard" | "server" | "laptop" | "thread" | "interrupt" | "syscall" | "page" | "pagetable" | "pin" | "worker" | "workflow" | "activity" | "signal" | "query" | "update" | "issue" | "pullRequest" | "repository" | "checklist" | "approval" | "model" | "tokens" | "vector" | "agent" | "spark" | "dashboard" | "terminal" | "container" | "experiment" | "target" | "loop" | "eye" | "message" | "shield" | "browser" | "desktop" | "recording" | "creditCard" | "warehouse" | "truck" | "microphone" | "forum" | "paywall" | "document" | "code" | "gear" | "clock" | "user" | "search" | "filter" | "lock" | "deploy" | "check" | "cross" | "question", options?: PictogramOptions): Pictogram

Pictogramclass

A small picture of a concept. .at(x, y) places the middle of its grid, so pictures of one size line up.

new Pictogram(name: "warning" | "ring" | "series" | "chart" | "forecast" | "threshold" | "anomaly" | "logs" | "traces" | "bars" | "table" | "matrix" | "event" | "alert" | "graph" | "dag" | "tree" | "layers" | "pipeline" | "branch" | "service" | "database" | "queue" | "cloud" | "chip" | "vm" | "process" | "kernel" | "memory" | "disk" | "nic" | "network" | "snapshot" | "clone" | "jail" | "wall" | "key" | "stopwatch" | "bolt" | "proxy" | "certificate" | "sleep" | "shard" | "core" | "timer" | "firmware" | "irqchip" | "bus" | "drive" | "floppy" | "serial" | "keyboard" | "server" | "laptop" | "thread" | "interrupt" | "syscall" | "page" | "pagetable" | "pin" | "worker" | "workflow" | "activity" | "signal" | "query" | "update" | "issue" | "pullRequest" | "repository" | "checklist" | "approval" | "model" | "tokens" | "vector" | "agent" | "spark" | "dashboard" | "terminal" | "container" | "experiment" | "target" | "loop" | "eye" | "message" | "shield" | "browser" | "desktop" | "recording" | "creditCard" | "warehouse" | "truck" | "microphone" | "forum" | "paywall" | "document" | "code" | "gear" | "clock" | "user" | "search" | "filter" | "lock" | "deploy" | "check" | "cross" | "question", options?
  • size: numberThe side of the square that holds the picture, in pixels.
  • name: "warning" | "ring" | "series" | "chart" | "forecast" | "threshold" | "anomaly" | "logs" | "traces" | "bars" | "table" | "matrix" | "event" | "alert" | "graph" | "dag" | "tree" | "layers" | "pipeline" | "branch" | "service" | "database" | "queue" | "cloud" | "chip" | "vm" | "process" | "kernel" | "memory" | "disk" | "nic" | "network" | "snapshot" | "clone" | "jail" | "wall" | "key" | "stopwatch" | "bolt" | "proxy" | "certificate" | "sleep" | "shard" | "core" | "timer" | "firmware" | "irqchip" | "bus" | "drive" | "floppy" | "serial" | "keyboard" | "server" | "laptop" | "thread" | "interrupt" | "syscall" | "page" | "pagetable" | "pin" | "worker" | "workflow" | "activity" | "signal" | "query" | "update" | "issue" | "pullRequest" | "repository" | "checklist" | "approval" | "model" | "tokens" | "vector" | "agent" | "spark" | "dashboard" | "terminal" | "container" | "experiment" | "target" | "loop" | "eye" | "message" | "shield" | "browser" | "desktop" | "recording" | "creditCard" | "warehouse" | "truck" | "microphone" | "forum" | "paywall" | "document" | "code" | "gear" | "clock" | "user" | "search" | "filter" | "lock" | "deploy" | "check" | "cross" | "question"
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Pictogram
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Pictogram
  • drop(child: Node): Pictogram
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): PictogramA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): PictogramSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Pictogram
  • moveTo(target: Node | Vec): PictogramMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): PictogramMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): PictogramScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): PictogramRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): PictogramScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): PictogramPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): PictogramLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): PictogramLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Pictogram
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Pictogram
  • color(color: ColorInput): PictogramRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Pictogram
  • glow(radius: number, color?: ColorInput | undefined): PictogramSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Pictogram
  • zIndex(value: number): Pictogram
  • pin(): PictogramPin to the screen so the camera does not move this node.
  • hide(): Pictogram
  • show(): Pictogram
  • named(label: string): Pictogram
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

PictogramNametype

type PictogramName = "warning" | "ring" | "series" | "chart" | "forecast" | "threshold" | "anomaly" | "logs" | "traces" | "bars" | "table" | "matrix" | "event" | "alert" | "graph" | "dag" | "tree" | "layers" | "pipeline" | "branch" | "service" | "database" | "queue" | "cloud" | "chip" | "vm" | "process" | "kernel" | "memory" | "disk" | "nic" | "network" | "snapshot" | "clone" | "jail" | "wall" | "key" | "stopwatch" | "bolt" | "proxy" | "certificate" | "sleep" | "shard" | "core" | "timer" | "firmware" | "irqchip" | "bus" | "drive" | "floppy" | "serial" | "keyboard" | "server" | "laptop" | "thread" | "interrupt" | "syscall" | "page" | "pagetable" | "pin" | "worker" | "workflow" | "activity" | "signal" | "query" | "update" | "issue" | "pullRequest" | "repository" | "checklist" | "approval" | "model" | "tokens" | "vector" | "agent" | "spark" | "dashboard" | "terminal" | "container" | "experiment" | "target" | "loop" | "eye" | "message" | "shield" | "browser" | "desktop" | "recording" | "creditCard" | "warehouse" | "truck" | "microphone" | "forum" | "paywall" | "document" | "code" | "gear" | "clock" | "user" | "search" | "filter" | "lock" | "deploy" | "check" | "cross" | "question"

PictogramOptionsinterface

  • size?: number | undefinedThe side of the square that holds the picture, in pixels. Defaults to 96.
  • color?: ColorInput | undefinedThe color of the lines. Defaults to ink.
  • accent?: ColorInput | undefinedThe color of the part that carries the meaning, such as the forecast in forecast. A picture with one part, such as series or check, is all in this color. Defaults to color.
  • weight?: number | undefinedStroke width, in units of the 24-unit grid. Defaults to 1.6.

PICTOGRAMSconst

Every pictogram name, in the order of the catalog.

const PICTOGRAMS: readonly ("warning" | "ring" | "series" | "chart" | "forecast" | "threshold" | "anomaly" | "logs" | "traces" | "bars" | "table" | "matrix" | "event" | "alert" | "graph" | "dag" | "tree" | "layers" | "pipeline" | "branch" | "service" | "database" | "queue" | "cloud" | "chip" | "vm" | "process" | "kernel" | "memory" | "disk" | "nic" | "network" | "snapshot" | "clone" | "jail" | "wall" | "key" | "stopwatch" | "bolt" | "proxy" | "certificate" | "sleep" | "shard" | "core" | "timer" | "firmware" | "irqchip" | "bus" | "drive" | "floppy" | "serial" | "keyboard" | "server" | "laptop" | "thread" | "interrupt" | "syscall" | "page" | "pagetable" | "pin" | "worker" | "workflow" | "activity" | "signal" | "query" | "update" | "issue" | "pullRequest" | "repository" | "checklist" | "approval" | "model" | "tokens" | "vector" | "agent" | "spark" | "dashboard" | "terminal" | "container" | "experiment" | "target" | "loop" | "eye" | "message" | "shield" | "browser" | "desktop" | "recording" | "creditCard" | "warehouse" | "truck" | "microphone" | "forum" | "paywall" | "document" | "code" | "gear" | "clock" | "user" | "search" | "filter" | "lock" | "deploy" | "check" | "cross" | "question")[]

piefunction

function pie(data: readonly PieDatum[], options?: PieOptions): PieChart

PieChartclass

Share of a whole, labeled directly. enter() sweeps around, and update() re-divides it.

new PieChart(data
  • wedges: Node[]
  • labels: Node[]
  • leaders: Node[]
  • centerText: Node | null
  • enter(options?: AnimOptions): AnimWedges sweep open around the circle, then the labels arrive.
  • update(values: readonly number[], options?: AnimOptions): AnimRe-divide the circle. Geometry animates, and labels follow their wedges.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): PieChart
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): PieChart
  • drop(child: Node): PieChart
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): PieChartA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): PieChartSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): PieChart
  • moveTo(target: Node | Vec): PieChartMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): PieChartMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): PieChartScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): PieChartRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): PieChartScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): PieChartPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): PieChartLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): PieChartLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): PieChart
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): PieChart
  • color(color: ColorInput): PieChartRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): PieChart
  • glow(radius: number, color?: ColorInput | undefined): PieChartSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): PieChart
  • zIndex(value: number): PieChart
  • pin(): PieChartPin to the screen so the camera does not move this node.
  • hide(): PieChart
  • show(): PieChart
  • named(label: string): PieChart
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

PieDatuminterface

  • label: string
  • value: number
  • color?: ColorInput | undefined

PieOptionsinterface

  • radius?: number | undefined
  • hole?: number | undefinedInner radius as a fraction of the outer radius. 0 makes a pie.
  • gap?: number | undefinedAngular gap between wedges, in radians.
  • labelSize?: number | undefined
  • percent?: boolean | undefinedShow each share as a percentage beside its label.
  • labels?: boolean | undefined
  • centerLabel?: string | undefined
  • centerSize?: number | undefined
  • font?: FontFamily | undefinedThe font of the labels. Defaults to the font of the film. The center label is in the display serif.

PlacedBeatinterface

Where one beat falls on the film's timeline, in seconds.

  • start: numberThe first moment of the recording.
  • end: numberThe last moment of the recording.
  • until: numberThe end of the silence after it.
  • text: string
  • words: readonly NarrationWord[]

planefunction

function plane(options?: PlaneOptions): NumberPlane

PlaneOptionsinterface

  • unit?: number | undefinedStage pixels per math unit.
  • x?: readonly [number, number] | undefinedExtent in math units. Defaults to overscan past the frame edges, for warps that pull in.
  • y?: readonly [number, number] | undefined
  • color?: ColorInput | undefined
  • minor?: number | undefinedMinor grid lines per unit.
  • axisColor?: ColorInput | undefined
  • width?: number | undefined

quotefunction

The exact words of a source, with who said them and when: quote('the agent loop lives in Temporal', { by: 'Cursor', when: '2026-06-02', width: 900, color: 'orange' }).

function quote(words: string, options?: QuoteOptions): Quote

Quoteclass

The exact words of a source between quotation marks, with a rule at their left, and one line under them that says who said them, when, and where. .at(x, y) places the top end of the rule, so quotes of different lengths start at one corner. The object is as high as its words need: read quote.height.

new Quote(words
  • words: TextNodeThe words with their quotation marks, as one text. The film check reads it as one sentence.
  • source: TextNode | nullThe line under the words: the speaker, the date, and the place. Null when the film gives none of them.
  • rule: NodeThe line at the left, from the top of the words to the bottom of the source line.
  • baseline: numberThe y of the base line of the first line of the words, in the coordinates of the object. A label beside the quote can stand on it.
  • find(part: string): Node[]The glyphs of a part of the words, to color them or to move them. The part is as the film wrote the words. Spaces do not count, and the part may run over the end of a line. Places at the borders of words come first: find('not') gives the word "not" at each of its places, and not the letters in "nothing". A part that is only inside longer words gives those places. A part that is not in the words gives an empty list.
  • reading: stringWhat a viewer reads: the words and the source line, as one text. A quote stays up for readingSeconds(said.reading). The film check gives the words and the source line each its own time, which is less.
  • lineEnd(line?: number): numberThe x of the end of the ink of a line of the words, in the coordinates of the object. Line 0 is the first one.
  • enter(options?: AnimOptions): AnimThe rule grows down from the top, the words arrive line by line, and then the source line.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Quote
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Quote
  • drop(child: Node): Quote
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): QuoteA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): QuoteSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Quote
  • moveTo(target: Node | Vec): QuoteMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): QuoteMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): QuoteScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): QuoteRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): QuoteScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): QuotePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): QuoteLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): QuoteLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Quote
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Quote
  • color(color: ColorInput): QuoteRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Quote
  • glow(radius: number, color?: ColorInput | undefined): QuoteSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Quote
  • zIndex(value: number): Quote
  • pin(): QuotePin to the screen so the camera does not move this node.
  • hide(): Quote
  • show(): Quote
  • named(label: string): Quote
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

QuoteOptionsinterface

  • by?: string | undefinedWho said the words: a person, a company, or a document.
  • when?: string | undefinedWhen, written as the film wants it on screen, such as '2026-06-02'.
  • where?: string | undefinedWhere: the title of the paper, the page, or the talk.
  • width?: number | undefinedThe width of the object, from the left edge of the rule to the place where the words wrap. Nothing of the object passes it. Defaults to 900.
  • size?: number | undefinedFont size of the words. Defaults to 32.
  • color?: ColorInput | undefinedThe color of the rule and of the marked parts. Defaults to blue.
  • mark?: string | readonly string[] | undefinedParts of the words to set in markColor, such as the phrase that the voice says. A part starts and ends at the borders of words: 'not' is the word "not", and not the first letters of "nothing". A part that is in the words more than once is marked at all its places. A part with no such place is an error.
  • markColor?: ColorInput | undefinedThe color of the marked parts. Defaults to color.
  • cut?: boolean | undefinedThe film left words out. Write [...] in the words at each such place: the object adds none. With cut, each [...] is in dim, so the viewer sees that it is not a word of the source.
  • italic?: boolean | undefinedSet the words in italic. On by default.
  • sourceSize?: number | undefinedFont size of the source line. Defaults to 0.78 of size, and to 24 at least when size is 24 or more.
  • leading?: number | undefinedLine height of the words, as a multiple of size. Defaults to 1.3.
  • font?: FontFamily | undefinedThe font of the words and of the source line. Defaults to text-serif.

quotePairfunction

Two quotes side by side with a word between them: quotePair({ words: 'it is safe', by: 'A' }, { words: 'it is not', by: 'B' }, { width: 1700, versus: 'but' }).

function quotePair(first: QuoteSpec, second: QuoteSpec, options?: QuotePairOptions): QuotePair

QuotePairclass

Two quotes side by side, for two sources that disagree. They have one width and one top line, and an optional word stands between them. .at(x, y) places the top end of the rule of the first quote, and nothing of the pair is over that top line.

new QuotePair(first
  • quotes: readonly [Quote, Quote]The two quotes, the left one first.
  • versus: TextNode | nullThe word between the two quotes, or null.
  • enter(options?: AnimOptions): AnimThe first quote arrives, then the word, then the second quote.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): QuotePair
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): QuotePair
  • drop(child: Node): QuotePair
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): QuotePairA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): QuotePairSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): QuotePair
  • moveTo(target: Node | Vec): QuotePairMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): QuotePairMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): QuotePairScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): QuotePairRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): QuotePairScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): QuotePairPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): QuotePairLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): QuotePairLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): QuotePair
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): QuotePair
  • color(color: ColorInput): QuotePairRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): QuotePair
  • glow(radius: number, color?: ColorInput | undefined): QuotePairSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): QuotePair
  • zIndex(value: number): QuotePair
  • pin(): QuotePairPin to the screen so the camera does not move this node.
  • hide(): QuotePair
  • show(): QuotePair
  • named(label: string): QuotePair
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

QuotePairOptionsinterface

  • width?: number | undefinedThe width of the pair, from the rule of the first quote to the place where the words of the second one wrap. Defaults to 1700.
  • gap?: number | undefinedThe room between the two quotes. Defaults to 3 times the text size, or the larger one of two sizes.
  • versus?: string | undefinedA word between the two quotes, such as 'but' or 'against'. It has the same room at both sides: from the end of the first line of the first quote, and to the rule of the second quote.
  • font?: FontFamily | undefinedThe font of the words and of the source line. Defaults to text-serif.
  • size?: number | undefinedFont size of the words. Defaults to 32.
  • color?: ColorInput | undefinedThe color of the rule and of the marked parts. Defaults to blue.
  • markColor?: ColorInput | undefinedThe color of the marked parts. Defaults to color.
  • italic?: boolean | undefinedSet the words in italic. On by default.
  • sourceSize?: number | undefinedFont size of the source line. Defaults to 0.78 of size, and to 24 at least when size is 24 or more.
  • leading?: number | undefinedLine height of the words, as a multiple of size. Defaults to 1.3.

QuoteSpecinterface

One quote of a pair: its words and its own options. The pair gives it its width.

  • words: string
  • font?: FontFamily | undefinedThe font of the words and of the source line. Defaults to text-serif.
  • by?: string | undefinedWho said the words: a person, a company, or a document.
  • when?: string | undefinedWhen, written as the film wants it on screen, such as '2026-06-02'.
  • where?: string | undefinedWhere: the title of the paper, the page, or the talk.
  • size?: number | undefinedFont size of the words. Defaults to 32.
  • color?: ColorInput | undefinedThe color of the rule and of the marked parts. Defaults to blue.
  • mark?: string | readonly string[] | undefinedParts of the words to set in markColor, such as the phrase that the voice says. A part starts and ends at the borders of words: 'not' is the word "not", and not the first letters of "nothing". A part that is in the words more than once is marked at all its places. A part with no such place is an error.
  • markColor?: ColorInput | undefinedThe color of the marked parts. Defaults to color.
  • cut?: boolean | undefinedThe film left words out. Write [...] in the words at each such place: the object adds none. With cut, each [...] is in dim, so the viewer sees that it is not a word of the source.
  • italic?: boolean | undefinedSet the words in italic. On by default.
  • sourceSize?: number | undefinedFont size of the source line. Defaults to 0.78 of size, and to 24 at least when size is 24 or more.
  • leading?: number | undefinedLine height of the words, as a multiple of size. Defaults to 1.3.

readingSecondsfunction

The seconds that a viewer needs to read a plain text on screen: 20 characters in one second, and half a second at least. The motion scan of checkFilm uses the same limit for film.text_brief. Use it for the time that a text stays up, such as s.wait(readingSeconds('one forecast drifts, and the law breaks')). For a formula, the scan counts the signs that it draws, which are fewer than the characters of its source.

function readingSeconds(text: string, speed?: number): number

riemannfunction

Rectangles under a curve. Morph one set into a finer one to show the integral appear.

function riemann(axes: Axes, f: (x: number) => number, options?: RiemannOptions): Node

RiemannOptionsinterface

  • from?: number | undefined
  • to?: number | undefined
  • n?: number | undefined
  • rule?: "left" | "right" | "mid" | undefinedWhere each rectangle samples the function.
  • colors?: readonly ColorInput[] | undefined
  • opacity?: number | undefined
  • stroke?: ColorInput | undefined
  • strokeWidth?: number | undefined

rightAnglefunction

The small square that marks a right angle.

function rightAngle(vertex: Vec, a: Vec, b: Vec, options?: { size?: number | undefined; color?: ColorInput | undefined; width?: number | undefined; }): Node

ringBufferfunction

A ring buffer with a head and a tail: ringBuffer(8, { label: 'submission queue', color: 'blue' }). push() writes at the tail, and pop() reads at the head.

function ringBuffer(slots: number, options?: RingBufferOptions): RingBuffer

RingBufferclass

A ring buffer: a band of slots, the entries in them, and two pointers. The producer writes an entry at the tail with push(), and the consumer reads the entry at the head with pop(). The two indexes only move forward, and the slot of an index is the index modulo the number of slots. It is the picture of the two rings of io_uring, of a virtqueue, and of any bounded queue. enter() draws the band, then brings the pointers and the caption. .at() places the center of the ring. The bounds of the ring hold the outside name at every slot, so a zone or a card around a ring has room for it.

new RingBuffer(slots
  • slots: Node[]The outline of each slot. Slot 0 is at the top, and the slots follow clockwise.
  • entries: Node[]The entry of each slot: its fill, its outline, and its label. Its opacity is 0 while the slot is empty.
  • numbers: Node[]The number beside each slot. The list is empty without numbers.
  • headPointer: Node | nullThe arrow head and the name of each pointer, or null for a pointer whose name is null. Fade, scale, or recolor a pointer as one node. Its place is its tip, and the ring moves it: do not move it.
  • tailPointer: Node | null
  • writeMarker: Node | nullThe dim arrow head at the place where the producer writes. Null without tailFollows: 'publish'.
  • caption: Node | nullThe text under the ring, or null for a ring with no label.
  • size: numberThe number of slots.
  • radius: numberThe outer radius of the band, and the radial size of a slot.
  • thickness: number
  • head: numberThe running index of the consumer: the number of entries that were read. Its slot is head % size.
  • tail: numberThe running index of the producer: the number of entries that were written. Its slot is tail % size.
  • length: numberThe number of entries in the ring: tail - head. It is 0 for an empty ring, and size for a full ring.
  • pending: numberThe number of entries that are written and not published.
  • p(slot: number): [number, number]The middle of a slot in the coordinates of the ring, so that a film can fly an entry in from another place. The slot wraps: p(size) is p(0). A fraction gives a place between two slots.
  • clone(): RingBufferA copy with its own entries and pointers, at rest in the state that the ring has now.
  • push(entry?: RingBufferEntry, options?: AnimOptions): AnimThe producer writes at the tail. The slot at the tail fills, then the tail pointer moves one slot on. With counts, the number beside the name changes when the pointer arrives. A pending entry is a dashed outline with no fill until publish(). With tailFollows: 'publish', the tail pointer stays for a pending entry, and the mark of the writer moves.
  • publish(options?: AnimOptions): AnimThe producer publishes what it wrote: every pending entry fills. With a lag, the entries fill one after another, from the oldest. With tailFollows: 'publish', the tail pointer moves over them.
  • pop(options?: AnimOptions): AnimThe consumer reads at the head. The entry at the head empties, then the head pointer moves one slot on.
  • enter(options?: AnimOptions): AnimThe band draws slot by slot, from slot 0. Then the pointers and the caption arrive.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): RingBuffer
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): RingBuffer
  • drop(child: Node): RingBuffer
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): RingBufferSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): RingBuffer
  • moveTo(target: Node | Vec): RingBufferMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): RingBufferMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): RingBufferScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): RingBufferRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): RingBufferScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): RingBufferPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): RingBufferLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): RingBufferLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): RingBuffer
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): RingBuffer
  • color(color: ColorInput): RingBufferRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): RingBuffer
  • glow(radius: number, color?: ColorInput | undefined): RingBufferSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): RingBuffer
  • zIndex(value: number): RingBuffer
  • pin(): RingBufferPin to the screen so the camera does not move this node.
  • hide(): RingBuffer
  • show(): RingBuffer
  • named(label: string): RingBuffer
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

RingBufferEntryinterface

  • color?: ColorInput | undefinedDefaults to the color of the ring.
  • label?: string | undefinedA short text in the slot, such as 'A' or 'read'.
  • pending?: boolean | undefinedThe entry is written and not yet published: a dashed outline with no fill. publish() fills it.

RingBufferOptionsinterface

  • radius?: number | undefinedOuter radius. Defaults to 170.
  • thickness?: number | undefinedRadial size of a slot. Defaults to 0.32 of radius.
  • color?: ColorInput | undefinedThe outline of the slots, the caption, and the color of an entry that has none. Defaults to blue.
  • label?: string | undefinedA caption under the ring, such as 'submission queue'.
  • captionGap?: number | undefinedThe distance from the band to the top of the capital letters of the caption. The default is the room of an arrow head and a name of 5 em under the band, and of the numbers when the ring has numbers. It follows from radius, size and numbers, and from no other option. So two rings that share these three have their captions on one line. Give two rings that differ one captionGap.
  • size?: number | undefinedText size of the caption and the pointer names. Defaults to 26.
  • labelSize?: number | undefinedText size of the label of an entry. A label that is too wide for its slot is set smaller, down to 0.6 of this size. Defaults to 0.28 of thickness, and to size at the most. With the default thickness, a word of four letters such as 'read' then keeps the size, so short labels have one size.
  • head?: string | null | undefinedThe name of the head pointer. Null draws no head pointer. Defaults to 'head'.
  • tail?: string | null | undefinedThe name of the tail pointer. Null draws no tail pointer. Defaults to 'tail'.
  • headColor?: ColorInput | undefinedThe color of the arrow head and the name of the head pointer. Defaults to the color of the ring.
  • tailColor?: ColorInput | undefinedThe color of the arrow head and the name of the tail pointer. Defaults to the color of the ring.
  • outside?: "head" | "tail" | undefinedWhich pointer is outside the ring. The other one is inside. Defaults to 'head'.
  • tailFollows?: "push" | "publish" | undefinedWhen the tail pointer moves. With 'push', it moves at each push, also for a pending entry: it is the index that the producer keeps. With 'publish', it stays behind the pending entries until publish(): it is the index that the consumer reads. A dim arrow head with no name then shows where the producer writes. Defaults to 'push'.
  • counts?: boolean | undefinedShow the running index beside each pointer name, such as 'tail 5'.
  • numbers?: boolean | undefinedWrite the number of each slot beside it.
  • font?: FontFamily | undefined

ringThroughfunction

A closed outline shrunk to a parametric function.

function ringThrough(f: (t: number) => Vec, samples?: number): Path

samplePathfunction

Evenly spaced points along a path, by arc length.

function samplePath(path: Path, count: number): Vec[]

scatterfunction

function scatter(points: readonly ScatterPoint[], options?: ScatterOptions): Scatter

Scatterclass

new Scatter(points
  • dots: Node[]
  • axis: Node
  • groupLabels: Node[]
  • p(x: number, y: number): [number, number]
  • enter(options?: AnimOptions): AnimAxes draw, then points land from left to right.
  • fit(f: (x: number) => number, options?: { color?: ColorInput | undefined; width?: number | undefined; samples?: number | undefined; }): NodeA straight or curved fit through the data, drawn on the same axes.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Scatter
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Scatter
  • drop(child: Node): Scatter
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): ScatterA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): ScatterSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Scatter
  • moveTo(target: Node | Vec): ScatterMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): ScatterMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): ScatterScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): ScatterRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): ScatterScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): ScatterPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): ScatterLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): ScatterLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Scatter
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Scatter
  • color(color: ColorInput): ScatterRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Scatter
  • glow(radius: number, color?: ColorInput | undefined): ScatterSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Scatter
  • zIndex(value: number): Scatter
  • pin(): ScatterPin to the screen so the camera does not move this node.
  • hide(): Scatter
  • show(): Scatter
  • named(label: string): Scatter
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

ScatterOptionsinterface

  • x?: readonly [number, number] | undefined
  • y?: readonly [number, number] | undefined
  • radius?: number | undefined
  • xLabel?: string | undefined
  • yLabel?: string | undefined
  • groupLabels?: boolean | undefinedLabel each group near its center, instead of using a legend.
  • width?: number | undefined
  • height?: number | undefined
  • labelSize?: number | undefinedText size for direct labels and ticks.
  • color?: ColorInput | undefined
  • font?: FontFamily | undefinedThe font of the labels and the ticks. Defaults to the font of the film. A value that the chart prints is in mono.

ScatterPointinterface

  • x: number
  • y: number
  • color?: ColorInput | undefined
  • radius?: number | undefined
  • group?: string | undefinedPoints with the same group share a color and one direct label.

SceneClockclass

The clock of one scene. Every time is in film seconds.

new SceneClock(stage
  • id: string
  • start: number
  • end: number
  • beats: readonly PlacedBeat[]
  • cue(phrase: string, beat?: number | undefined): { start: number; end: number; }When the voice says a phrase. Pass a beat index to search one beat only. Throws if the phrase is not spoken.
  • on(phrase: string, build: () => void, offset?: number, beat?: number | undefined): SceneClockBuild when the voice starts a phrase. offset moves it, in seconds.
  • after(phrase: string, build: () => void, offset?: number, beat?: number | undefined): SceneClockBuild when the voice finishes a phrase.
  • onBeat(index: number, build: () => void, offset?: number): SceneClockBuild when a beat starts.
  • at(seconds: number, build: () => void): SceneClockBuild at a time counted from the start of the scene.
  • clear(targets: readonly (Node | Value)[], lead?: number, duration?: number): SceneClockFade nodes out just before the scene ends, so the next picture starts on a clean frame. A value goes to zero in the same time, for a dynamic drawing that takes its opacity from one.

secantLinefunction

The line through two points on a curve. Pass functions to shrink h on screen.

function secantLine(axes: Axes, f: (x: number) => number, a: Reactive, b: Reactive, style?: SecantOptions): Node

SecantOptionsinterface

  • extend?: number | undefinedExtra length past each point, in stage pixels.
  • points?: boolean | undefined
  • legs?: boolean | undefinedDraw the run and rise legs of the slope triangle.
  • legColor?: ColorInput | undefined
  • fill?: ColorInput | null | undefined
  • stroke?: ColorInput | null | undefined
  • width?: number | undefined
  • opacity?: number | undefined
  • glow?: number | undefined
  • dash?: readonly number[] | undefined
  • z?: number | undefined

setAssetBasefunction

Tell the browser build where fonts live. The URL must end with a slash.

function setAssetBase(url: string): void

sparklinefunction

A word-sized line chart, with no axes.

function sparkline(values: readonly number[], options?: SparklineOptions): Node

SparklineOptionsinterface

  • width?: number | undefined
  • height?: number | undefined
  • color?: ColorInput | undefined
  • weight?: number | undefined
  • dotted?: boolean | undefinedMark the latest value.
  • area?: number | undefined

spinfunction

Steady rotation for as long as it plays: radians per second, around the center or a point.

function spin(node: Node, rate: number, options?: AnimOptions & { about?: Vec | undefined; }): Anim

spotlightfunction

Put the light on one node or more: s.play(spotlight(row3)). The rest of the stage dims, and the targets keep their look. The light stays on. A second spotlight moves it, and spotlight(null) turns it off. The rest is every node that shows before the light starts and that is not a target, not in a target, and not an ancestor of a target. An ancestor keeps its look, and its other children dim. Pinned nodes and the nodes in keep stay bright as the targets do. A node that comes to the stage with the light, or later, is not dimmed. A dim node keeps its opacity. Its colors go toward the background of the film, so it still hides what is behind it, and a fade that the film makes while the light is on is still there when the light goes off. The verb only adds a light to the list of the stage. What is dim at a time comes from that list in time order, when the film is complete. So a film can name its lights, and bring its nodes, in any order.

function spotlight(target: Node | readonly Node[] | null, options?: SpotlightOptions): Anim

SpotlightOptionsinterface

  • dim?: number | undefinedThe part of its color that the rest keeps, from 0 to 1. At 0 the rest has the color of the background. Defaults to 0.3 on a dark look and to 0.4 on a light look, which leave dim text at the same contrast.
  • within?: Node | undefinedDim only inside this node, such as one chart or one group. The rest of the stage does not change.
  • keep?: Node | readonly Node[] | undefinedOne node or more that stay bright with the targets, such as a heading, a source line, or a backdrop.
  • duration?: number | undefined
  • ease?: Ease | undefined
  • lag?: number | undefinedFraction of one item's time between the starts of consecutive items.

stateGridfunction

A grid of cells in named states: stateGrid({ columns: 16, rows: 8, initial: 'absent' }), then grid.change([3, 4, 5], 'present').

function stateGrid(options: StateGridOptions): StateGrid

StateGridclass

A grid of cells, each in a named state: pages of memory, blocks of a disk, the bits of a bitmap, the hosts of a fleet. The state sets the look of the cell. change() moves cells to another state as a sweep, and count(), stateOf() and indexes() read the states, so a number beside the grid can follow it. enter() brings the cells in row by row, and legend() makes the key. .at() places the middle of the grid.

new StateGrid(options
  • cells: Node[]One rounded square per cell, row by row. The cell of a row and a column has the index row * columns + column.
  • columns: number
  • rows: number
  • size: numberThe number of cells.
  • p(index: number): [number, number]The middle of a cell, in the coordinates of the grid.
  • stateOf(index: number): stringThe state of a cell, after the changes that are scheduled so far.
  • count(state: string): numberThe number of cells in a state, after the changes that are scheduled so far.
  • indexes(state: string): number[]The cells in a state, by index, after the changes that are scheduled so far.
  • enter(options?: AnimOptions): AnimThe cells arrive row by row, from the top.
  • change(which: number | readonly number[] | ((index: number, state: string) => boolean), state: string, options?: AnimOptions): AnimCells go to another state. which is an index, a list of indexes, or a function of the index and the state of a cell, which the grid calls when the change is scheduled. So a second change in one sequence sees the states that the first one left. The cells change in index order, one after another, and the whole change takes duration. A cell that already has the state does not change and takes no time.
  • legend(items?: readonly (string | readonly [state: string, label: string])[] | undefined, options?: GridLegendOptions): NodeA key for the states, in one row: a sample cell and a name for each. It is a new node, and not a child of the grid. .at(x, y) places the left end of the row, and y is the middle line of the cells and the names. items lists the states to show, each as a name or as a [state, label] pair. Without items, the key shows the states that the grid has now, in the order of states.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): StateGrid
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): StateGrid
  • drop(child: Node): StateGrid
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): StateGridA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): StateGridSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): StateGrid
  • moveTo(target: Node | Vec): StateGridMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): StateGridMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): StateGridScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): StateGridRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): StateGridScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): StateGridPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): StateGridLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): StateGridLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): StateGrid
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): StateGrid
  • color(color: ColorInput): StateGridRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): StateGrid
  • glow(radius: number, color?: ColorInput | undefined): StateGridSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): StateGrid
  • zIndex(value: number): StateGrid
  • pin(): StateGridPin to the screen so the camera does not move this node.
  • hide(): StateGrid
  • show(): StateGrid
  • named(label: string): StateGrid
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

StateGridOptionsinterface

  • columns: number
  • rows: number
  • cell?: number | undefinedSide of one cell. Defaults to 28.
  • gap?: number | undefinedRoom between two cells. Defaults to 0.18 of cell, at least 3.
  • states?: Record<string, GridState> | undefinedThe states and their looks. Defaults to PAGE_STATES.
  • initial?: string | readonly string[] | ((index: number) => string) | undefinedThe state of each cell at the start: one name, one name per cell, or a function of the index. Defaults to the first state.

Stepinterface

  • label: stringThe name of the step, on one line.
  • note?: string | undefinedA short text under the box, such as the price of the step. It has one line, or two with a line break.

StepEdgetype

type StepEdge = "left" | "right" | "top" | "bottom"

stepsfunction

A row of named steps with one of them lit: steps(['batching', 'SQPOLL', 'register', 'I/O polling'], { width: 1800, numbered: true, current: 0 }). strip.go(1) moves the light.

function steps(list: readonly (string | Step)[], options?: StepsOptions): Steps

Stepsclass

A row of named steps with one of them lit: the chapters of an argument, the stages of a process, or a list of options that the film goes through one by one. The steps before the lit one are dim, and the steps after it are weaker, and still readable. go(index) moves the light. .at() places the middle of the boxes. The notes are outside them: under the row, or between the boxes of a column.

new Steps(steps
  • items: Node[]One node per step, which holds its box, its label and its note.
  • boxes: Node[]
  • labels: TextNode[]
  • notes: (TextNode | null)[]The note of each step, or null for a step that has none.
  • current: number | nullThe index of the lit step after the changes that are scheduled so far, or null when no step is lit.
  • stateOf(index: number): StepStateThe state of a step after the changes that are scheduled so far. With no lit step, every step is 'done': dim, and readable.
  • p(index: number, edge?: StepEdge | undefined): [number, number]A point on an edge of the box of a step, in the coordinates of the object, for a connector to the picture of the step. Without an edge: the bottom in a row, and the right side in a column. The bottom point of a step that has a note is under the note, with clear room under the tails of its letters, so a line from it does not touch the note.
  • enter(options?: AnimOptions): AnimThe steps arrive one after another, from the first to the last, each one with the look of its state.
  • go(index: number | null, options?: AnimOptions): AnimThe light moves to another step, or goes off with null. Each step whose state changes takes its new look: the lit one, a done one before it, or one that is ahead after it. A strip that is not on the stage comes to it at the start of the move, in the state before the move.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Steps
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Steps
  • drop(child: Node): Steps
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): StepsA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): StepsSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Steps
  • moveTo(target: Node | Vec): StepsMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): StepsMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): StepsScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): StepsRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): StepsScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): StepsPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): StepsLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): StepsLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Steps
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Steps
  • color(color: ColorInput): StepsRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Steps
  • glow(radius: number, color?: ColorInput | undefined): StepsSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Steps
  • zIndex(value: number): Steps
  • pin(): StepsPin to the screen so the camera does not move this node.
  • hide(): Steps
  • show(): Steps
  • named(label: string): Steps
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

StepsOptionsinterface

  • width?: number | undefinedIn a row: the width of the whole row. In a column: the width of each box. Defaults to 1600 for a row and to 360 for a column.
  • height?: number | undefinedThe height of one box. Defaults to 2.2 of size. A height with no room for a letter with a tail is an error.
  • gap?: number | undefinedThe room between two boxes. Defaults to 0.6 of size.
  • size?: number | undefinedText size of the labels. A label that is too wide for its box makes all labels smaller, down to 0.7 of this size. Defaults to 28.
  • noteSize?: number | undefinedText size of the notes. Defaults to 0.9 of size.
  • numbered?: boolean | undefinedWrite the number of each step before its label: "1 batching", "2 SQPOLL".
  • current?: number | null | undefinedThe index of the lit step, or null for none. Defaults to null.
  • direction?: "row" | "column" | undefined'row' puts the boxes side by side. 'column' puts them one under the other, with the labels at the left. Defaults to row.
  • color?: ColorInput | undefinedThe color of the border of the lit step. Defaults to ink.
  • font?: FontFamily | undefined

StepStatetype

Where a step is: the lit one, one before it, or one after it.

type StepState = "current" | "done" | "ahead"

streamLinesfunction

function streamLines(f: FieldFn, options?: StreamLinesOptions): StreamLines

StreamLinesclass

Flow made visible: lines are integrated once, then light runs along them. Drawing is batched by color and brightness, so hundreds of lines stay live.

new StreamLines(f
  • lineCount: number
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): StreamLines
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): StreamLines
  • drop(child: Node): StreamLines
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): StreamLinesA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): StreamLinesSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): StreamLines
  • moveTo(target: Node | Vec): StreamLinesMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): StreamLinesMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): StreamLinesScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): StreamLinesRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): StreamLinesScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): StreamLinesPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): StreamLinesLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): StreamLinesLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): StreamLines
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): StreamLines
  • color(color: ColorInput): StreamLinesRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): StreamLines
  • glow(radius: number, color?: ColorInput | undefined): StreamLinesSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): StreamLines
  • zIndex(value: number): StreamLines
  • pin(): StreamLinesPin to the screen so the camera does not move this node.
  • hide(): StreamLines
  • show(): StreamLines
  • named(label: string): StreamLines
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

StreamLinesOptionsinterface

  • x?: readonly [number, number] | undefined
  • y?: readonly [number, number] | undefined
  • unit?: number | undefined
  • spacing?: number | undefinedMath units between seed points. Smaller is denser.
  • dt?: number | undefinedIntegration step and number of steps for each line.
  • steps?: number | undefined
  • colors?: readonly ColorInput[] | undefined
  • max?: number | undefined
  • width?: number | undefined
  • speed?: number | undefinedPasses per second along a full line.
  • tail?: number | undefinedLit fraction of each line.
  • seed?: number | undefined
  • trace?: number | undefinedShow the whole lines faintly underneath the moving light.

surroundingBoxfunction

A rounded box around a node or nodes, measured now.

function surroundingBox(target: Node | readonly Node[], options?: SurroundOptions): Node

SurroundOptionsinterface

  • pad?: number | undefined
  • radius?: number | undefined
  • color?: ColorInput | undefined
  • width?: number | undefined
  • fill?: ColorInput | undefined
  • fillOpacity?: number | undefined
  • glow?: number | undefined

SvgNodeclass

An imported picture. It is a regular node tree, so every verb works on it.

new SvgNode(path?
  • byId: Map<string, Node>
  • pictureWidth: number
  • pictureHeight: number
  • find(id: string): NodeFind an element by its SVG id.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): SvgNode
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): SvgNode
  • drop(child: Node): SvgNode
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): SvgNodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): SvgNodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): SvgNode
  • moveTo(target: Node | Vec): SvgNodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): SvgNodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): SvgNodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): SvgNodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): SvgNodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): SvgNodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): SvgNodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): SvgNodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): SvgNode
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): SvgNode
  • color(color: ColorInput): SvgNodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): SvgNode
  • glow(radius: number, color?: ColorInput | undefined): SvgNodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): SvgNode
  • zIndex(value: number): SvgNode
  • pin(): SvgNodePin to the screen so the camera does not move this node.
  • hide(): SvgNode
  • show(): SvgNode
  • named(label: string): SvgNode
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

swapfunction

Two nodes trade places along opposite arcs.

function swap(a: Node, b: Node, options?: AnimOptions & { lift?: number | undefined; }): Anim

tagfunction

A word in a pill with a note, such as tag('MEASURED', { note: 'the study of June 2026', color: 'green' }).at(-912, -490).

function tag(word: string, options?: TagOptions): Tag

Tagclass

A word in a pill, with a note beside it: the kind of claim that is on the screen, and where it comes from. .at(x, y) places the left end of the pill, so tags with words of different lengths start at one x.

new Tag(word
  • pill: Node
  • word: Node
  • note: Node | null
  • color(color: ColorInput): TagRecolor the border of the pill and the word. The fill of the pill and the note keep their colors.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Tag
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Tag
  • drop(child: Node): Tag
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): TagA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): TagSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Tag
  • moveTo(target: Node | Vec): TagMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): TagMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): TagScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): TagRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): TagScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): TagPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): TagLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): TagLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Tag
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Tag
  • opacity(value: number): Tag
  • glow(radius: number, color?: ColorInput | undefined): TagSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Tag
  • zIndex(value: number): Tag
  • pin(): TagPin to the screen so the camera does not move this node.
  • hide(): Tag
  • show(): Tag
  • named(label: string): Tag
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

TagOptionsinterface

  • note?: string | undefinedPlain text beside the pill, such as the source of a claim and its date. It stays on one line.
  • color?: ColorInput | undefinedThe color of the pill and its word. Defaults to dim.
  • noteColor?: ColorInput | undefinedThe color of the note. Defaults to dim.
  • size?: number | undefinedFont size of the word and the note. Defaults to 26.
  • font?: FontFamily | undefinedThe font of the word. Defaults to mono.
  • noteFont?: FontFamily | undefinedThe font of the note. Defaults to the font of text().
  • fill?: ColorInput | null | undefinedThe fill of the pill. Pass null for none. Defaults to the surface color.

TagStateinterface

  • at: numberWhen this state starts, in seconds of the film.
  • word: string
  • note?: string | undefinedPlain text beside the pill, such as the source of a claim and its date. It stays on one line.
  • color?: ColorInput | undefinedThe color of the pill and its word. Defaults to dim.
  • noteColor?: ColorInput | undefinedThe color of the note. Defaults to dim.
  • size?: number | undefinedFont size of the word and the note. Defaults to 26.
  • font?: FontFamily | undefinedThe font of the word. Defaults to mono.
  • noteFont?: FontFamily | undefinedThe font of the note. Defaults to the font of text().
  • fill?: ColorInput | null | undefinedThe fill of the pill. Pass null for none. Defaults to the surface color.

tagTrackfunction

A tag that changes with time, at one place. It takes the states in order. One state is on screen at a time: a state fades out before the next one fades in. States that start out of order, or less than the two fades apart, are an error, so no moment shows two tags. Place it as any node: tagTrack(states, { until }).at(-912, -490) is the top left of a 1920 by 1080 frame. It is pinned, so a move or a zoom of the camera does not move it.

function tagTrack(states: readonly TagState[], options: TagTrackOptions): Node

TagTrackOptionsinterface

  • until: numberWhen the last state leaves, in seconds of the film.
  • fadeIn?: number | undefinedSeconds to fade a state in and out. Defaults to 0.25 and 0.18.
  • fadeOut?: number | undefined
  • note?: string | undefinedPlain text beside the pill, such as the source of a claim and its date. It stays on one line.
  • color?: ColorInput | undefinedThe color of the pill and its word. Defaults to dim.
  • noteColor?: ColorInput | undefinedThe color of the note. Defaults to dim.
  • size?: number | undefinedFont size of the word and the note. Defaults to 26.
  • font?: FontFamily | undefinedThe font of the word. Defaults to mono.
  • noteFont?: FontFamily | undefinedThe font of the note. Defaults to the font of text().
  • fill?: ColorInput | null | undefinedThe fill of the pill. Pass null for none. Defaults to the surface color.

tangentLinefunction

The tangent at x, as a line on the axes. Pass a function of time to make it slide.

function tangentLine(axes: Axes, f: (x: number) => number, x: Reactive, style?: TangentOptions): Node

TangentOptionsinterface

  • length?: number | undefinedLength of the drawn segment, in stage pixels.
  • point?: boolean | undefinedMark the point of tangency.
  • fill?: ColorInput | null | undefined
  • stroke?: ColorInput | null | undefined
  • width?: number | undefined
  • opacity?: number | undefined
  • glow?: number | undefined
  • dash?: readonly number[] | undefined
  • z?: number | undefined

terminalfunction

The output of a program in a panel, with the exact characters: terminal([{ text: './one-byte', kind: 'command' }, 'minor faults: 1'], { title: 'runs/01-one-byte.txt', note: 'Linux 7.0, arm64, 2026-11-08' }).

function terminal(lines: readonly (string | TerminalLine)[], options?: TerminalOptions): Terminal

Terminalclass

The output of a real program, as a terminal shows it: a panel with a bar that says where and when it ran, a command after its prompt, and the lines that the program printed, with the exact characters. It shows all its lines, unless it starts with shown: false. enter() brings the empty panel, type() types a command, and print() brings the next block of lines, up to the next command. find() selects one number, to color it or to point at it. .at() places the middle of the panel.

new Terminal(lines
  • frame: NodeThe panel: its fill and its border.
  • bar: NodeThe band at the top, behind the title and the note.
  • title: Node | null
  • note: Node | null
  • lines: Node[]One node per line. The node of a command holds its prompt.
  • prompts: (Node | null)[]The prompt of each command line, or null for another line.
  • find(text: string, occurrence?: number): NodeOne part of the text of a line, as one node: to color a number, to indicate it, or to point a callout at it. It matches the exact characters, spaces included, in the commands, the output and the notes, from the first line to the last. occurrence counts the matches from 0. codeBlock.find is different: it returns the glyphs of every match as a list, spaces do not count there, and its second argument is a line.
  • p(line: number, side?: "left" | "right"): [number, number]The start or the end of a line, in the coordinates of the panel, at the middle height of its letters. The start of a command is the start of its prompt. Defaults to the start.
  • clone(): TerminalA copy with its own record of the lines that are shown.
  • enter(options?: AnimOptions): AnimThe panel and the bar arrive, with no line. type(), print() and showLines() bring the lines. A line that one of them shows in the same play stays, whatever the order of the two.
  • type(line: number, options?: AnimOptions): AnimA command arrives character by character, at a steady rate, after its prompt. Lines count from 0. A command that is already shown is an error: start the terminal with shown: false, or play enter().
  • print(options?: AnimOptions & { from?: number | undefined; to?: number | undefined; }): AnimLines arrive one after another, in order, each at once, as a terminal prints them. Without from and to, it prints the next block: from the first line that is not yet shown, to the line before the next command that is not yet shown. A command at the start of the block arrives whole. So type() then print() types a command and prints its output, print() alone shows the command and its output, and a second print() goes on with the next block. With a range, such as { from: 1, to: 3 } for lines 1, 2 and 3, it prints every line of the range that is not yet shown.
  • showLines(options?: AnimOptions): AnimEvery line that is not yet shown fades in, all together: for a film that does not want the typing.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Terminal
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Terminal
  • drop(child: Node): Terminal
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): TerminalSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Terminal
  • moveTo(target: Node | Vec): TerminalMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): TerminalMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): TerminalScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): TerminalRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): TerminalScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): TerminalPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): TerminalLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): TerminalLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Terminal
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Terminal
  • color(color: ColorInput): TerminalRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Terminal
  • glow(radius: number, color?: ColorInput | undefined): TerminalSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Terminal
  • zIndex(value: number): Terminal
  • pin(): TerminalPin to the screen so the camera does not move this node.
  • hide(): Terminal
  • show(): Terminal
  • named(label: string): Terminal
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

TerminalLineinterface

  • text: string
  • kind?: "command" | "output" | "note" | undefined'command' draws the prompt before the text. 'output' is what the program printed. 'note' is a dim line that the film adds, such as '[...]' for lines that it left out. Defaults to output.
  • color?: ColorInput | undefinedThe color of the text. Defaults to ink, and to dim for a note.

TerminalOptionsinterface

  • title?: string | undefinedText in the bar at the top, at the left: a file path or a host name.
  • note?: string | undefinedDim text in the bar, at the right: where and when it ran, such as 'Linux 7.0, arm64, 2026-11-08'.
  • columns?: number | undefinedCharacters in one line. Defaults to the longest line, or to more when the title and the note need more room. A longer line is an error, or is cut with an ellipsis when clip is true. The spaces at the end of a line do not count: they are not drawn.
  • clip?: boolean | undefined
  • shown?: boolean | undefinedStart with every line on screen. Defaults to true, for a picture that does not move. Give false to a terminal that a film types and prints, so that its panel starts empty wherever the film adds it.
  • size?: number | undefinedText size. Defaults to 26.
  • prompt?: string | undefinedDrawn before a command. Defaults to '$ '.
  • color?: ColorInput | undefinedThe border and the bar. Defaults to grid.

tokenizefunction

A small tokenizer for film code. It colors the common cases and never blocks on odd input.

function tokenize(source: string, language?: string): Omit<CodeToken, "glyphs">[]

TokenKindtype

type TokenKind = "string" | "number" | "function" | "keyword" | "comment" | "type" | "punctuation" | "plain" | "space"

TokenRowclass

A sequence of token chips, as in a tokenizer's output. Small type by default.

new TokenRow(items
  • chips: Node[]
  • token(index: number): Node
  • enter(options?: AnimOptions): AnimChips arrive from left to right.
  • arcs(from: number, weights: readonly number[], options?: { color?: ColorInput | undefined; maxWidth?: number | undefined; lift?: number | undefined; }): NodeCurved links from one token to others, brighter for stronger weights. Add the result to the stage after this row is in place.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): TokenRow
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): TokenRow
  • drop(child: Node): TokenRow
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): TokenRowA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): TokenRowSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): TokenRow
  • moveTo(target: Node | Vec): TokenRowMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): TokenRowMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): TokenRowScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): TokenRowRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): TokenRowScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): TokenRowPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): TokenRowLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): TokenRowLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): TokenRow
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): TokenRow
  • color(color: ColorInput): TokenRowRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): TokenRow
  • glow(radius: number, color?: ColorInput | undefined): TokenRowSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): TokenRow
  • zIndex(value: number): TokenRow
  • pin(): TokenRowPin to the screen so the camera does not move this node.
  • hide(): TokenRow
  • show(): TokenRow
  • named(label: string): TokenRow
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

tokensfunction

function tokens(items: readonly (string | TokenSpec)[], options?: TokensOptions): TokenRow

TokensOptionsinterface

  • size?: number | undefined
  • maxWidth?: number | undefinedWrap to this width.
  • gap?: number | undefined
  • color?: ColorInput | undefined
  • colors?: readonly ColorInput[] | undefinedRamp of colors across the row.
  • font?: FontFamily | undefinedThe font of the tokens. Defaults to mono. The line under a chip is in mono.
  • subSize?: number | undefined
  • radius?: number | undefined

TokenSpecinterface

  • text: string
  • sub?: string | undefinedSmall line under the chip, such as an id or a probability.
  • color?: ColorInput | undefined

tracedfunction

The path a moving point has taken. It is computed by re-reading the point at earlier times, so it scrubs correctly in both directions. The point function should read Values or tracked node properties, not update overlays.

function traced(point: () => Vec, from: number, to: number, options?: TracedOptions): Node

TracedOptionsinterface

  • color?: ColorInput | undefined
  • width?: number | undefined
  • tail?: number | undefinedSeconds of history to keep. Older parts of the trail are gone.
  • fade?: number | undefinedBrightness at the old end, from 0 to 1. Use 1 for a solid trail.
  • rate?: number | undefinedSamples per second along the trail.
  • glow?: number | undefined

treefunction

function tree(root: TreeSpec, options?: TreeOptions): TreeGraph

TreeGraphclass

A tidy tree: parents center over children, and subtrees never overlap.

new TreeGraph(root
  • depths: Map<string, number>
  • enter(options?: AnimOptions): AnimGrow from the root, one level at a time.
  • nodes: Map<string, GraphNode>
  • edges: GraphEdge[]
  • edgeLayer: Node
  • nodeLayer: Node
  • node(id: string): GraphNode
  • edge(from: string, to: string): GraphEdge
  • pulseEdge(from: string, to: string, options?: AnimOptions & { color?: ColorInput | undefined; length?: number | undefined; }): AnimA lit signal travels along an edge.
  • visit(id: string, options?: AnimOptions & { color?: ColorInput | undefined; }): AnimMark a node as reached: its color changes and it swells for a moment.
  • moveNode(id: string, to: Vec, options?: AnimOptions): AnimMove a node. Its edges follow, re-routed as straight lines.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): TreeGraph
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): TreeGraph
  • drop(child: Node): TreeGraph
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): TreeGraphA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): TreeGraphSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): TreeGraph
  • moveTo(target: Node | Vec): TreeGraphMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): TreeGraphMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): TreeGraphScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): TreeGraphRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): TreeGraphScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): TreeGraphPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): TreeGraphLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): TreeGraphLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): TreeGraph
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): TreeGraph
  • color(color: ColorInput): TreeGraphRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): TreeGraph
  • glow(radius: number, color?: ColorInput | undefined): TreeGraphSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): TreeGraph
  • zIndex(value: number): TreeGraph
  • pin(): TreeGraphPin to the screen so the camera does not move this node.
  • hide(): TreeGraph
  • show(): TreeGraph
  • named(label: string): TreeGraph
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

TreeOptionsinterface

  • levelGap?: number | undefined
  • siblingGap?: number | undefined
  • direction?: "right" | "down" | undefined
  • fillOpacity?: number | undefinedFill nodes softly with their color instead of leaving them hollow.
  • font?: FontFamily | undefinedThe font of the node labels. Defaults to the font of the film.
  • radius?: number | undefined
  • labelSize?: number | undefined
  • nodeColor?: ColorInput | undefined
  • edgeColor?: ColorInput | undefined

TreeSpecinterface

  • id?: string | undefined
  • label?: string | undefined
  • color?: ColorInput | undefined
  • children?: readonly TreeSpec[] | undefined
  • math?: boolean | undefined

typewriterfunction

Characters appear one at a time, at a steady rate, with an optional cursor.

function typewriter(target: Target, options?: TypewriterOptions): Anim

TypewriterOptionsinterface

  • cursor?: boolean | undefinedShow a block cursor at the writing position.
  • cursorColor?: ColorInput | undefined
  • duration?: number | undefined
  • ease?: Ease | undefined
  • lag?: number | undefinedFraction of one item's time between the starts of consecutive items.

UnitArrangementinterface

  • rows?: number | undefinedMarks in one column. The chart fills column by column, so the width of a group shows its size.
  • columns?: number | undefinedMarks in one row. The chart fills row by row. Give rows or columns, not both.
  • split?: boolean | undefinedDraw each group as its own block, with its label over it. Without it, the groups follow each other in one grid.
  • mixed?: boolean | undefinedPut the marks of all groups at mixed places in one grid, to show a few among many.
  • seed?: number | undefinedA whole number. The same seed gives the same mixed places. Defaults to 1.

unitChartfunction

One mark for each unit, in groups: unitChart([{ count: 262 }, { count: 39, color: 'green', label: '39 better' }], { rows: 11, split: true }).

function unitChart(groups: readonly UnitGroup[], options?: UnitChartOptions): UnitChart

UnitChartclass

One mark for each unit: a count that the viewer can see, not only read. Groups share one grid, or stand as blocks side by side, or sit at mixed places to show a few among many. enter() brings the marks in line by line, paint() gives the groups their colors, and rearrange() moves the marks to another arrangement. .at() places the middle of the grid, or of the row of blocks. The labels are over the blocks.

new UnitChart(groups
  • marks: Node[]Every mark, group after group.
  • labels: (Node | null)[]The label of each group, or null for a group that has none. A label is part of the chart from the first time that the groups are split. Before that it is not drawn, and not a child of the chart.
  • total: numberThe number of marks.
  • groups: Node[][]The marks of each group, in the order of the groups.
  • p(index: number): [number, number]The place of a mark in the chart, by its index in marks, in the arrangement that the chart has now.
  • clone(): UnitChartA copy with its own marks and labels, in the arrangement that the chart has now.
  • enter(options?: AnimOptions): AnimThe marks arrive line by line, in the order that the chart fills. The label of a block arrives with its first line.
  • paint(options?: AnimOptions): AnimEach mark and each label takes the color of its group. Use it on a chart that starts plain.
  • rearrange(to: UnitArrangement, options?: AnimOptions): AnimThe marks move to another arrangement, such as { split: true } to gather mixed marks into blocks. The new arrangement keeps the rows or columns and the seed that it does not name. split and mixed turn each other off, and rows replaces columns. Labels leave before the move and arrive after it. Each group moves over the whole time, so a small group does not wait for a large one.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): UnitChart
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): UnitChart
  • drop(child: Node): UnitChart
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): UnitChartSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): UnitChart
  • moveTo(target: Node | Vec): UnitChartMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): UnitChartMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): UnitChartScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): UnitChartRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): UnitChartScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): UnitChartPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): UnitChartLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): UnitChartLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): UnitChart
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): UnitChart
  • color(color: ColorInput): UnitChartRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): UnitChart
  • glow(radius: number, color?: ColorInput | undefined): UnitChartSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): UnitChart
  • zIndex(value: number): UnitChart
  • pin(): UnitChartPin to the screen so the camera does not move this node.
  • hide(): UnitChart
  • show(): UnitChart
  • named(label: string): UnitChart
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

UnitChartOptionsinterface

  • cell?: number | undefinedSide or diameter of one mark. Defaults to 16.
  • gap?: number | undefinedRoom between two marks. Defaults to 0.6 of cell.
  • blockGap?: number | undefinedRoom between two blocks while the groups are split. Defaults to 2.5 marks with their gaps.
  • shape?: "square" | "dot" | undefinedDefaults to dot.
  • plain?: boolean | undefinedStart with every mark and label in plainColor. chart.paint() then gives each group its color.
  • plainColor?: ColorInput | undefinedThe color before paint(), for a chart that starts plain. Defaults to dim.
  • labelSize?: number | undefinedText size of the labels. Defaults to 28.
  • font?: FontFamily | undefined
  • rows?: number | undefinedMarks in one column. The chart fills column by column, so the width of a group shows its size.
  • columns?: number | undefinedMarks in one row. The chart fills row by row. Give rows or columns, not both.
  • split?: boolean | undefinedDraw each group as its own block, with its label over it. Without it, the groups follow each other in one grid.
  • mixed?: boolean | undefinedPut the marks of all groups at mixed places in one grid, to show a few among many.
  • seed?: number | undefinedA whole number. The same seed gives the same mixed places. Defaults to 1.

UnitGroupinterface

  • count: numberHow many marks the group has. A whole number, 0 or more.
  • color?: ColorInput | undefinedDefaults to dim.
  • label?: string | undefinedText over the block of the group. It shows only while the groups are split.

vectorFieldfunction

function vectorField(f: FieldFn, options?: VectorFieldOptions): VectorField

VectorFieldclass

A grid of arrows that shows a field's direction and strength. y points up in field space.

new VectorField(f
  • unit: number
  • arrows: Node[]
  • f: FieldFn
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): VectorField
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): VectorField
  • drop(child: Node): VectorField
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): VectorFieldA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): VectorFieldSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): VectorField
  • moveTo(target: Node | Vec): VectorFieldMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): VectorFieldMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): VectorFieldScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): VectorFieldRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): VectorFieldScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): VectorFieldPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): VectorFieldLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): VectorFieldLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): VectorField
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): VectorField
  • color(color: ColorInput): VectorFieldRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): VectorField
  • glow(radius: number, color?: ColorInput | undefined): VectorFieldSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): VectorField
  • zIndex(value: number): VectorField
  • pin(): VectorFieldPin to the screen so the camera does not move this node.
  • hide(): VectorField
  • show(): VectorField
  • named(label: string): VectorField
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

VectorFieldOptionsinterface

  • x?: readonly [number, number] | undefined
  • y?: readonly [number, number] | undefined
  • step?: number | undefinedMath units between arrows.
  • unit?: number | undefinedStage pixels per math unit.
  • maxLength?: number | undefinedLongest arrow, in stage pixels.
  • max?: number | undefinedMagnitude that reaches the last color.
  • colors?: readonly ColorInput[] | undefined
  • width?: number | undefinedThickness of the shaft.
  • animate?: boolean | undefinedRecompute from f(x, y, t) on every frame.

VideoCodectype

type VideoCodec = "h264" | "vp9"

wipefunction

Reveal marks in the order a moving edge reaches them. Each mark fades up as the edge passes, so a dense diagram opens like a sweep across the page.

function wipe(target: Target, options?: WipeOptions): Anim

WipeOptionsinterface

  • from?: "left" | "right" | "top" | "bottom" | undefinedEdge the reveal starts from.
  • soft?: number | undefinedShare of the time each mark takes to fade up as the edge passes.
  • travel?: number | undefinedSlide each mark this far as it arrives.
  • duration?: number | undefined
  • ease?: Ease | undefined
  • lag?: number | undefinedFraction of one item's time between the starts of consecutive items.

zonefunction

A named border around nodes, such as zone([vmm, guest], { title: 'jail', dash: true }). .at(x, y) places its middle.

function zone(content: Node | readonly Node[], options?: ZoneOptions): Zone

Zoneclass

A border around a group of nodes, with a name on it: a host, a network, a sandbox, a boundary of trust. The zone measures its content when it is built and takes the content as its children, so the zone and what it holds move, fade, and scale as one node. A zone can hold other zones.

new Zone(content
  • frame: NodeThe border. With a title it is an open line, so draw(zone.frame) traces it from one side of the title to the other.
  • backdrop: Node | nullThe fill inside the border, or null when the zone has none.
  • title: Node | nullThe title on the border, or null when the zone has none.
  • content: readonly Node[]The nodes inside the border, in the order given.
  • box: BoundsThe middle line of the border, in the coordinates of the zone, where (0, 0) is the middle of the border.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Zone
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Zone
  • drop(child: Node): Zone
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): ZoneA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): ZoneSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Zone
  • moveTo(target: Node | Vec): ZoneMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): ZoneMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): ZoneScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): ZoneRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): ZoneScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): ZonePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): ZoneLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): ZoneLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Zone
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Zone
  • color(color: ColorInput): ZoneRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Zone
  • glow(radius: number, color?: ColorInput | undefined): ZoneSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Zone
  • zIndex(value: number): Zone
  • pin(): ZonePin to the screen so the camera does not move this node.
  • hide(): Zone
  • show(): Zone
  • named(label: string): Zone
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

ZoneOptionsinterface

  • title?: string | undefinedThe name of the zone. It sits in a gap of the top border.
  • titleAlign?: "left" | "right" | "center" | undefinedWhere the title sits along the top border. Defaults to left.
  • titleSize?: number | undefinedFont size of the title. Defaults to 26.
  • padding?: number | undefinedSpace between the content and the border. Defaults to 32.
  • color?: ColorInput | undefinedThe color of the border and the title. Defaults to dim.
  • dash?: boolean | readonly number[] | undefinedA dashed border, for a boundary that is a rule and not a wall. Pass true for the default pattern.
  • fill?: ColorInput | null | undefinedThe fill inside the border. Defaults to none. Its top edge runs behind the title, so keep it faint.
  • fillOpacity?: number | undefinedOpacity of the fill. Defaults to 0.12, so that the content stays the strongest thing in the zone.
  • radius?: number | undefined
  • borderWidth?: number | undefinedWidth of the border. Defaults to 2.5.
  • font?: FontFamily | undefined
  • minWidth?: number | undefinedGive the zone this size when the content is smaller, so that zones of a row have one size.
  • minHeight?: number | undefined

3D

axes3dfunction

function axes3d(options?: Axes3DOptions): Axes3D

Axes3Dclass

Three axes with ticks and tips.

new Axes3D(options?
  • emit(view: View3D): void
  • labelsNow(view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Axes3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Axes3D
  • drop(child: Node): Axes3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Axes3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Axes3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Axes3D
  • moveTo(target: Node | Vec): Axes3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Axes3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Axes3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Axes3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Axes3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Axes3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Axes3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Axes3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Axes3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Axes3D
  • color(color: ColorInput): Axes3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Axes3D
  • glow(radius: number, color?: ColorInput | undefined): Axes3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Axes3D
  • zIndex(value: number): Axes3D
  • pin(): Axes3DPin to the screen so the camera does not move this node.
  • hide(): Axes3D
  • show(): Axes3D
  • named(label: string): Axes3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

Axes3DOptionsinterface

  • x?: readonly [number, number] | undefined
  • y?: readonly [number, number] | undefined
  • z?: readonly [number, number] | undefined
  • step?: number | undefined
  • color?: ColorInput | undefined
  • width?: number | undefined
  • labels?: boolean | readonly [string, string, string] | undefinedLabels at the axis tips. Pass false to leave them off.
  • labelSize?: number | undefined
  • numbers?: boolean | undefined
  • font?: FontFamily | undefinedThe font of the numbers. Defaults to the font of the film. The names of the axes are math.
  • ticks?: boolean | undefined
  • bias?: number | undefinedPull toward the camera, so axes lying in a surface do not break into dashes.
  • onTop?: boolean | undefined

curve3dfunction

function curve3d(f: (t: number) => Vec3, from: number, to: number, style?: Line3DStyle & { samples?: number | undefined; }): Curve3D

Curve3Dclass

A curve in space, cut into pieces so it passes correctly in front of and behind other marks.

new Curve3D(f: (t
  • emit(view: View3D): void
  • labelsNow(_view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Curve3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Curve3D
  • drop(child: Node): Curve3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Curve3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Curve3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Curve3D
  • moveTo(target: Node | Vec): Curve3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Curve3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Curve3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Curve3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Curve3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Curve3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Curve3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Curve3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Curve3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Curve3D
  • color(color: ColorInput): Curve3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Curve3D
  • glow(radius: number, color?: ColorInput | undefined): Curve3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Curve3D
  • zIndex(value: number): Curve3D
  • pin(): Curve3DPin to the screen so the camera does not move this node.
  • hide(): Curve3D
  • show(): Curve3D
  • named(label: string): Curve3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

gridPlane3dfunction

function gridPlane3d(options?: GridPlaneOptions): GridPlane3D

GridPlane3Dclass

A hairline grid on a horizontal plane, to ground a scene.

new GridPlane3D(options?
  • emit(view: View3D): void
  • labelsNow(_view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): GridPlane3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): GridPlane3D
  • drop(child: Node): GridPlane3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): GridPlane3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): GridPlane3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): GridPlane3D
  • moveTo(target: Node | Vec): GridPlane3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): GridPlane3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): GridPlane3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): GridPlane3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): GridPlane3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): GridPlane3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): GridPlane3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): GridPlane3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): GridPlane3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): GridPlane3D
  • color(color: ColorInput): GridPlane3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): GridPlane3D
  • glow(radius: number, color?: ColorInput | undefined): GridPlane3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): GridPlane3D
  • zIndex(value: number): GridPlane3D
  • pin(): GridPlane3DPin to the screen so the camera does not move this node.
  • hide(): GridPlane3D
  • show(): GridPlane3D
  • named(label: string): GridPlane3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

GridPlaneOptionsinterface

  • x?: readonly [number, number] | undefined
  • y?: readonly [number, number] | undefined
  • z?: number | undefined
  • step?: number | undefined
  • color?: ColorInput | undefined
  • width?: number | undefined
  • opacity?: number | undefined

label3dfunction

function label3d(content: string | Node, position: Reactive3, options?: Label3DOptions): Label3D

Label3Dclass

A label pinned to a point in space. It always faces the camera.

new Label3D(content
  • emit(): void
  • labelsNow(view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Label3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Label3D
  • drop(child: Node): Label3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Label3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Label3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Label3D
  • moveTo(target: Node | Vec): Label3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Label3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Label3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Label3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Label3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Label3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Label3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Label3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Label3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Label3D
  • color(color: ColorInput): Label3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Label3D
  • glow(radius: number, color?: ColorInput | undefined): Label3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Label3D
  • zIndex(value: number): Label3D
  • pin(): Label3DPin to the screen so the camera does not move this node.
  • hide(): Label3D
  • show(): Label3D
  • named(label: string): Label3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

Label3DOptionsinterface

  • size?: number | undefined
  • color?: ColorInput | undefined
  • math?: boolean | undefinedA label is math by default. Pass false for plain text.
  • font?: FontFamily | undefinedThe font of a plain label. Defaults to the font of the film.
  • offset?: Vec | undefined

line3dfunction

function line3d(a: Reactive3, b: Reactive3, style?: Line3DStyle & { pieces?: number | undefined; }): Line3D

Line3Dclass

A straight line in space. Ends can be functions, so it can follow moving points.

new Line3D(a
  • emit(view: View3D): void
  • labelsNow(_view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Line3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Line3D
  • drop(child: Node): Line3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Line3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Line3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Line3D
  • moveTo(target: Node | Vec): Line3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Line3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Line3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Line3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Line3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Line3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Line3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Line3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Line3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Line3D
  • color(color: ColorInput): Line3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Line3D
  • glow(radius: number, color?: ColorInput | undefined): Line3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Line3D
  • zIndex(value: number): Line3D
  • pin(): Line3DPin to the screen so the camera does not move this node.
  • hide(): Line3D
  • show(): Line3D
  • named(label: string): Line3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

Line3DStyleinterface

  • color?: ColorInput | undefined
  • colors?: readonly ColorInput[] | undefinedColor ramp along the line.
  • width?: number | undefined
  • opacity?: number | undefined
  • glow?: number | undefined
  • onTop?: boolean | undefinedDraw over everything else in the scene.
  • bias?: number | undefinedNudge toward the camera so a line lying on a surface stays visible.

Object3Dclass

A thing in a 3D scene. It is a regular node with an empty 2D path, so verbs work on it: fadeIn sets opacity, and draw animates its reveal through trimTo.

new Object3D()
  • emit(view: View3D, time: number): void
  • labelsNow(_view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Object3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Object3D
  • drop(child: Node): Object3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Object3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Object3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Object3D
  • moveTo(target: Node | Vec): Object3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Object3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Object3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Object3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Object3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Object3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Object3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Object3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Object3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Object3D
  • color(color: ColorInput): Object3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Object3D
  • glow(radius: number, color?: ColorInput | undefined): Object3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Object3D
  • zIndex(value: number): Object3D
  • pin(): Object3DPin to the screen so the camera does not move this node.
  • hide(): Object3D
  • show(): Object3D
  • named(label: string): Object3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

ParametricFntype

type ParametricFn = (u: number, v: number, t: number) => Vec3

parametricSurfacefunction

A surface over any two parameters.

function parametricSurface(fn: ParametricFn, u: readonly [number, number], v: readonly [number, number], options?: SurfaceOptions): Surface3D

point3dfunction

One point in space, as a convenience over points3d.

function point3d(point: Reactive3, style?: Points3DStyle): Points3D

points3dfunction

function points3d(points: readonly Vec3[] | (() => readonly Vec3[]), style?: Points3DStyle): Points3D

Points3Dclass

Points in space. Pass a function to move them. They shrink with distance and sort with everything else.

new Points3D(source
  • emit(view: View3D): void
  • labelsNow(_view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Points3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Points3D
  • drop(child: Node): Points3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Points3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Points3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Points3D
  • moveTo(target: Node | Vec): Points3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Points3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Points3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Points3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Points3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Points3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Points3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Points3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Points3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Points3D
  • color(color: ColorInput): Points3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Points3D
  • glow(radius: number, color?: ColorInput | undefined): Points3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Points3D
  • zIndex(value: number): Points3D
  • pin(): Points3DPin to the screen so the camera does not move this node.
  • hide(): Points3D
  • show(): Points3D
  • named(label: string): Points3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

Points3DStyleinterface

  • color?: ColorInput | undefined
  • colorAt?: ((index: number, point: Vec3) => ColorInput) | undefinedPer-point color.
  • radius?: number | undefinedRadius in stage pixels at the focus.
  • opacity?: number | undefined
  • onTop?: boolean | undefined
  • bias?: number | undefinedNudge toward the camera so a point resting on a surface is not cut by it.
  • halo?: number | undefinedSoft ring around each point.

scene3dfunction

function scene3d(options?: Scene3DOptions): Scene3D

Scene3Dclass

new Scene3D(options?
  • phi: Value
  • theta: Value
  • distance: Value
  • unit: Value
  • focusX: Value
  • focusY: Value
  • focusZ: Value
  • orbit(target: { phi?: number | undefined; theta?: number | undefined; distance?: number | undefined; unit?: number | undefined; focus?: Vec3 | undefined; }, options?: AnimOptions): AnimMove the camera over time. Any subset of phi, theta, distance, unit, and focus.
  • spin(rate?: number): Scene3DStart a slow ambient rotation here on the timeline, in radians per second.
  • stopSpin(): Scene3D
  • stagePoint(point: Vec3): [number, number]Stage point of a world position at this moment, for placing 2D notes.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Scene3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Scene3D
  • drop(child: Node): Scene3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Scene3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Scene3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Scene3D
  • moveTo(target: Node | Vec): Scene3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Scene3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Scene3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Scene3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Scene3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Scene3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Scene3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Scene3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Scene3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Scene3D
  • color(color: ColorInput): Scene3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Scene3D
  • glow(radius: number, color?: ColorInput | undefined): Scene3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Scene3D
  • zIndex(value: number): Scene3D
  • pin(): Scene3DPin to the screen so the camera does not move this node.
  • hide(): Scene3D
  • show(): Scene3D
  • named(label: string): Scene3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

Scene3DOptionsinterface

  • phi?: number | undefinedAngle down from straight overhead, in radians. 0 looks straight down.
  • theta?: number | undefinedRotation around the vertical axis, in radians.
  • distance?: number | undefinedCamera distance in math units. Smaller exaggerates perspective.
  • unit?: number | undefinedStage pixels per math unit.
  • focus?: Vec3 | undefined
  • perspective?: boolean | undefinedSet to false for an orthographic view.
  • light?: Vec3 | undefinedDirection toward the light, in world space.
  • ambient?: number | undefinedShare of light that reaches every face, from 0 to 1.
  • shine?: number | undefinedSize of the bright highlight. 0 turns it off.
  • fog?: number | undefinedHow much distant marks sink toward the background, from 0 to 1.
  • fogColor?: ColorInput | undefined
  • brightness?: number | undefinedMultiplies lit surface color. Defaults to 0.8 on dark looks, where large areas also bloom.

spherefunction

function sphere(radius?: number, options?: SurfaceOptions & { center?: Vec3 | undefined; }): Surface3D

surfacefunction

A height field z = f(x, y). f also receives time when animate is on.

function surface(f: (x: number, y: number, t: number) => number, options?: SurfaceOptions & { x?: readonly [number, number] | undefined; y?: readonly [number, number] | undefined; }): Surface3D

Surface3Dclass

A shaded mesh. Faces sort with everything else in the scene, so objects can intersect.

new Surface3D(fn
  • emit(view: View3D, time: number): void
  • labelsNow(_view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Surface3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Surface3D
  • drop(child: Node): Surface3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Surface3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Surface3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Surface3D
  • moveTo(target: Node | Vec): Surface3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Surface3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Surface3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Surface3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Surface3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Surface3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Surface3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Surface3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Surface3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Surface3D
  • color(color: ColorInput): Surface3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Surface3D
  • glow(radius: number, color?: ColorInput | undefined): Surface3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Surface3D
  • zIndex(value: number): Surface3D
  • pin(): Surface3DPin to the screen so the camera does not move this node.
  • hide(): Surface3D
  • show(): Surface3D
  • named(label: string): Surface3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

SurfaceOptionsinterface

  • resolution?: number | readonly [number, number] | undefinedGrid cells in each direction. A number applies to both.
  • color?: ColorInput | undefinedOne color for the whole surface.
  • colors?: readonly ColorInput[] | undefinedColor ramp by height.
  • checker?: readonly [ColorInput, ColorInput] | undefinedTwo colors in a checker pattern.
  • colorAt?: ((x: number, y: number, z: number, u: number, v: number) => Rgba) | undefinedAny color per face.
  • opacity?: number | undefined
  • mesh?: false | ColorInput | undefinedThin lines along the cells.
  • meshOpacity?: number | undefined
  • meshWidth?: number | undefined
  • shaded?: boolean | undefinedSet to false for flat, unlit color.
  • cull?: boolean | undefinedSkip faces pointing away. Good for closed shapes such as spheres.
  • animate?: boolean | undefinedRecompute the shape on every frame from time.
  • outwardFrom?: Vec3 | undefinedPoint normals away from this point. Closed shapes need it so cull keeps the near side.

trail3dfunction

function trail3d(point: () => Vec3, from: number, to: number, style?: Line3DStyle & { tail?: number | undefined; rate?: number | undefined; fade?: number | undefined; }): Trail3D

Trail3Dclass

The path a moving point has taken, with a fading tail. Scrubs correctly in both directions.

new Trail3D(point: () => Vec3, from
  • emit(view: View3D, time: number): void
  • labelsNow(_view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Trail3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Trail3D
  • drop(child: Node): Trail3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Trail3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Trail3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Trail3D
  • moveTo(target: Node | Vec): Trail3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Trail3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Trail3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Trail3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Trail3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Trail3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Trail3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Trail3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Trail3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Trail3D
  • color(color: ColorInput): Trail3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Trail3D
  • glow(radius: number, color?: ColorInput | undefined): Trail3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Trail3D
  • zIndex(value: number): Trail3D
  • pin(): Trail3DPin to the screen so the camera does not move this node.
  • hide(): Trail3D
  • show(): Trail3D
  • named(label: string): Trail3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

Vec3type

type Vec3 = readonly [number, number, number]

vector3dfunction

function vector3d(from: Reactive3, to: Reactive3, style?: Line3DStyle & { tip?: number | undefined; }): Vector3D

Vector3Dclass

An arrow in space. The head always faces the camera, so it reads from any angle.

new Vector3D(from
  • emit(view: View3D): void
  • labelsNow(_view: View3D): Node[]Screen-facing labels, drawn on top.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): Vector3D
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): Vector3D
  • drop(child: Node): Vector3D
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): Vector3DA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): Vector3DSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): Vector3D
  • moveTo(target: Node | Vec): Vector3DMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): Vector3DMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): Vector3DScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): Vector3DRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): Vector3DScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): Vector3DPlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): Vector3DLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): Vector3DLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): Vector3D
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): Vector3D
  • color(color: ColorInput): Vector3DRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): Vector3D
  • glow(radius: number, color?: ColorInput | undefined): Vector3DSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): Vector3D
  • zIndex(value: number): Vector3D
  • pin(): Vector3DPin to the screen so the camera does not move this node.
  • hide(): Vector3D
  • show(): Vector3D
  • named(label: string): Vector3D
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

View3Dclass

Everything an object needs to project itself for one frame.

new View3D()
  • ops: PathOp[]
  • depths: number[]
  • rx: number
  • ry: number
  • ux: number
  • uy: number
  • uz: number
  • dx: number
  • dy: number
  • dz: number
  • fx: number
  • fy: number
  • fz: number
  • distance: number
  • unit: number
  • perspective: boolean
  • matrix: Mat
  • alpha: number
  • scale: number
  • light: Vec3
  • half: Vec3
  • ambient: number
  • shine: number
  • fog: number
  • fogColor: Rgba
  • depthRange: number
  • brightness: number
  • px: number
  • py: number
  • pz: number
  • ps: number
  • project(x: number, y: number, z: number): booleanProject a world point. Returns false when it falls behind the camera.
  • screen(x: number, y: number, z: number): [number, number] | nullLocal stage point before the scene's own transform, for placing labels.
  • fogged(r: number, g: number, b: number, depth: number): RgbaMix a color toward the background for marks further from the camera.
  • push(op: PathOp, depth: number): void

Text and math

FontFamilytype

type FontFamily = "sans" | "serif" | "text-serif" | "mono" | "noto"

fontForfunction

Get a font now, or suspend the current compile until it arrives.

function fontFor(family: BundledFamily, weight?: FontWeight, italic?: boolean): LoadedFont

FontWeighttype

type FontWeight = 400 | 600 | 700

glyphPathfunction

Glyph outline scaled to a pixel size, with y pointing down and the origin on the baseline.

function glyphPath(font: LoadedFont, glyph: number, size: number): Path

parseFontfunction

function parseFont(bytes: ArrayBuffer): LoadedFont

texfunction

Typeset TeX with real math glyphs. tex.part('x^2') selects a term for color or morphing.

function tex(source: string, options?: TexOptions): TexNode

TexNodeclass

Typeset equation as glyph nodes. Ordinary characters keep their identity for morphs.

new TexNode(path?
  • glyphs: Node[]
  • source: string
  • part(fragment: string): Node[]Glyphs matching a TeX fragment, such as eq.part('b^2'). Use it to color or morph a term.
  • parts(fragment: string): Node[][]Every occurrence of a fragment, in order.
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): TexNode
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): TexNode
  • drop(child: Node): TexNode
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): TexNodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): TexNodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): TexNode
  • moveTo(target: Node | Vec): TexNodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): TexNodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): TexNodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): TexNodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): TexNodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): TexNodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): TexNodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): TexNodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): TexNode
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): TexNode
  • color(color: ColorInput): TexNodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): TexNode
  • glow(radius: number, color?: ColorInput | undefined): TexNodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): TexNode
  • zIndex(value: number): TexNode
  • pin(): TexNodePin to the screen so the camera does not move this node.
  • hide(): TexNode
  • show(): TexNode
  • named(label: string): TexNode
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

TexOptionsinterface

  • size?: number | undefined
  • color?: ColorInput | undefined
  • display?: boolean | undefined

textfunction

function text(content: string, options?: TextOptions): TextNode

TextNodeclass

A line or block of text as real vector glyphs. Each glyph is its own child, so text can be handwritten, staggered, or morphed. .chars lists them in order.

new TextNode(path?
  • chars: Node[]
  • source: string
  • font: FontFamilyThe font of the text: the font that it names, or the font of the film. text() records it when it makes the node.
  • find(fragment: string): Node[]Glyph nodes whose characters match, such as every "x".
  • id: number
  • parent: Node | null
  • children: Node[]
  • data: Record<string, unknown>Free-form metadata, such as the source character of a glyph.
  • label: stringLabel shown in timelines and diagnostics.
  • base: NodeProps
  • tracks: Map<keyof NodeProps, Track<unknown>> | null
  • overlay: Map<string, unknown> | null
  • overlayFrame: number
  • mounted: booleanOn stage: writes become timeline keys instead of initial state.
  • draw: ((time: number) => Node | readonly Node[] | null) | nullRebuilt on every frame from timeline values.
  • rawOps: ((matrix: Mat, alpha: number, ops: DrawOp[]) => void) | nullEmits draw operations directly, for objects with thousands of marks such as 3D meshes.
  • get<K extends PropName>(prop: K): NodeProps[K]
  • set<K extends PropName>(prop: K, value: NodeProps[K]): TextNode
  • track<K extends PropName>(prop: K): Track<NodeProps[K]>
  • tween<K extends PropName>(prop: K, to: NodeProps[K], t0: number, t1: number, ease: Ease | null): voidRecord a change from the current value to to over [t0, t1].
  • add(...nodes: Node[]): TextNode
  • drop(child: Node): TextNode
  • all(): Node[]Self and all descendants, parents first.
  • leaves(): Node[]Descendants that draw something. A leaf group returns itself if it draws.
  • clone(): TextNodeA static copy of the current state, off stage. An object that keeps its parts in fields, such as the glyphs of a text or the frame of a card, gets fields that point at the copies of those parts.
  • localMatrix(): Mat
  • worldMatrix(): Mat
  • toWorld(x: number, y: number): [number, number]
  • bounds(): BoundsStage-space bounds of this node and its descendants.
  • center: [number, number]
  • top: [number, number]
  • bottom: [number, number]
  • left: [number, number]
  • right: [number, number]
  • width: number
  • height: number
  • at(x: number | Vec, y?: number | undefined): TextNodeSet the local position of the origin.
  • shift(dx: number | Vec, dy?: number | undefined): TextNode
  • moveTo(target: Node | Vec): TextNodeMove so the center of the bounds lands on a stage point or on another node's center.
  • pivotAt(point: Vec): TextNodeMove the origin to a stage point without changing how anything looks.
  • scale(factor: number | Vec, about?: Vec | undefined): TextNodeScale around the center, or around a given stage point.
  • rotate(radians: number, about?: Vec | undefined): TextNodeRotate around the center, or around a given stage point.
  • fitTo(size: { width?: number | undefined; height?: number | undefined; }): TextNodeScale to an exact on-screen width or height, keeping proportions.
  • nextTo(target: Node | Vec, side?: Side, gap?: number): TextNodePlace beside another node or stage point, with a gap measured between bounds.
  • alignTo(target: Node | Vec, edge: Edge): TextNodeLine up one edge with another node's same edge.
  • arrange(side?: Side, gap?: number): TextNodeLay out children in a row or column, keeping the group's center.
  • fill(color: ColorInput | null, opacity?: number | undefined): TextNode
  • stroke(color: ColorInput | null, width?: number | undefined, opacity?: number | undefined): TextNode
  • color(color: ColorInput): TextNodeRecolor this node and its descendants, keeping whichever paints exist.
  • opacity(value: number): TextNode
  • glow(radius: number, color?: ColorInput | undefined): TextNodeSoft light around the shape. The radius is in stage pixels.
  • dash(pattern: readonly number[] | null, offset?: number): TextNode
  • zIndex(value: number): TextNode
  • pin(): TextNodePin to the screen so the camera does not move this node.
  • hide(): TextNode
  • show(): TextNode
  • named(label: string): TextNode
  • labelsOf(_part: Node): readonly Node[]The labels that belong to one part of this object, such as the name and the readout of a bar. A light on the part keeps them bright. An object that has such labels says so here.

TextOptionsinterface

  • size?: number | undefined
  • font?: FontFamily | undefinedDefaults to the font of the film, and to sans in a film that has none.
  • weight?: FontWeight | undefined
  • italic?: boolean | undefined
  • color?: ColorInput | undefined
  • align?: "left" | "right" | "center" | undefinedLine alignment inside the block.
  • anchor?: "left" | "right" | "center" | undefinedThe point of the block that .at(x, y) places: its left edge, its middle, or its right edge. The default is the middle. The height of the point does not change, so labels with different anchors on one y share a baseline. The block also scales and rotates about it.
  • maxWidth?: number | undefinedWrap to this width, in stage pixels.
  • leading?: number | undefinedLine height as a multiple of size.
  • tracking?: number | undefinedExtra space between letters, as a fraction of size.
  • uppercase?: boolean | undefined

Easing

bounceconst

const bounce: Ease

cubicBezierfunction

CSS-style cubic-bezier timing function.

function cubicBezier(x1: number, y1: number, x2: number, y2: number): Ease

duringfunction

Restrict an ease to a window of the animation.

function during(from: number, to: number, inner?: Ease): Ease

Easetype

Rate functions map animation progress in [0, 1] to eased progress.

type Ease = (t: number) => number

easeInCubicconst

const easeInCubic: Ease

easeInExpoconst

const easeInExpo: Ease

easeInOutCubicconst

const easeInOutCubic: Ease

easeInOutQuintconst

const easeInOutQuint: Ease

easeInQuadconst

const easeInQuad: Ease

easeOutCubicconst

const easeOutCubic: Ease

easeOutExpoconst

const easeOutExpo: Ease

easeOutQuadconst

const easeOutQuad: Ease

easeOutQuintconst

const easeOutQuint: Ease

linearconst

const linear: Ease

lingeringfunction

Holds at 1 for the last part of the time.

function lingering(hold?: number, inner?: Ease): Ease

notQuiteTherefunction

Stops short of the target, for an unfinished gesture.

function notQuiteThere(amount?: number, inner?: Ease): Ease

overshootfunction

Overshoot the target once, then settle.

function overshoot(amount?: number): Ease

runningStartfunction

Backs up briefly, then runs through to the target.

function runningStart(pull?: number): Ease

rushFromconst

const rushFrom: Ease

rushIntoconst

const rushInto: Ease

slowIntoconst

const slowInto: Ease

smoothconst

const smooth: Ease

smoothByfunction

The house default. A sigmoid with a calm start and a calm landing.

function smoothBy(inflection: number): Ease

smootherconst

Fifth-order smoothstep, for long camera moves.

const smoother: Ease

springfunction

Physically based settle. Exactly 1 at t=1 so holds never drift.

function spring(options?: { bounce?: number | undefined; frequency?: number | undefined; }): Ease

thereAndBackconst

Goes to 1 and returns to 0. Ends where it started, for emphasis.

const thereAndBack: Ease

thereAndBackWithPausefunction

function thereAndBackWithPause(pause?: number): Ease

wigglefunction

Oscillates around 0 and ends at 0.

function wiggle(cycles?: number): Ease

Color and looks

blueprintconst

Drafting-table navy with cool cyan linework.

const blueprint: Look

chalkconst

Near-black green with warm chalk, for classroom-style lessons.

const chalk: Look

colorAlongfunction

Color that travels along a stroke, such as a graph that warms from left to right.

function colorAlong(...colors: readonly ColorInput[]): AlongGradient

ColorInputtype

type ColorInput = string | Rgba | Gradient

cssfunction

function css(color: Rgba, alpha?: number): string

Gradienttype

type Gradient = LinearGradient | RadialGradient | AlongGradient

linearGradientfunction

function linearGradient(from: readonly [number, number], to: readonly [number, number], colors: readonly ColorInput[] | readonly (readonly [number, ColorInput])[]): LinearGradient

Lookinterface

A look is a complete art direction for a film: background, ink, a small set of named pigments, and how much light the image gives off. Authors write color: 'yellow', so one film renders correctly in every look.

  • name: string
  • dark: boolean
  • background: string
  • bloom: numberFull-frame bloom in the light-emitting looks. 0 turns it off.
  • colors: Readonly<Record<LookToken, string>>

LookNametype

type LookName = "midnight" | "paper" | "blueprint" | "chalk" | "neon"

LOOKSconst

const LOOKS: { readonly midnight: Look; readonly paper: Look; readonly blueprint: Look; readonly chalk: Look; readonly neon: Look; }

LookTokentype

type LookToken = "dim" | "bg" | "surface" | "ink" | "faint" | "grid" | "gridStrong" | "blue" | "teal" | "green" | "yellow" | "gold" | "orange" | "red" | "pink" | "purple"

midnightconst

Deep neutral black with luminous pigments. The default.

const midnight: Look

mixColorfunction

Mix two colors in OKLab, which keeps blends bright and even in tone.

function mixColor(a: Rgba, b: Rgba, t: number): Rgba

neonconst

Saturated light on pure black, for trailers and hero loops.

const neon: Look

Painttype

type Paint = Rgba | Gradient

paperconst

Warm paper and printed ink, for articles and print.

const paper: Look

parseColorfunction

function parseColor(input: string): Rgba

radialGradientfunction

function radialGradient(center: readonly [number, number], radius: number, colors: readonly ColorInput[]): RadialGradient

rampfunction

Evenly spaced colors between stops, for coloring a list of items.

function ramp(count: number, ...colors: readonly ColorInput[]): Rgba[]

resolveLookfunction

function resolveLook(look: Look | "midnight" | "paper" | "blueprint" | "chalk" | "neon" | undefined): Look

Rgbatype

r, g, b from 0 to 255 and alpha from 0 to 1.

type Rgba = readonly [number, number, number, number]

toPaintfunction

function toPaint(input: ColorInput): Paint

Geometry

applyfunction

function apply(m: Mat, x: number, y: number): [number, number]

arcPathfunction

Elliptical or circular arc, with one cubic per 45 degrees at most.

function arcPath(cx: number, cy: number, rx: number, ry: number, from: number, to: number): Path

Boundsinterface

  • x: number
  • y: number
  • width: number
  • height: number

circlePathfunction

function circlePath(cx: number, cy: number, r: number): Path

composefunction

Translate * Rotate * Scale * Translate(-pivot).

function compose(x: number, y: number, rotation: number, sx: number, sy: number, px: number, py: number): Mat

concatfunction

function concat(...paths: readonly Path[]): Path

curveThroughfunction

Hermite fit through samples. Non-finite samples split the curve into separate rings, so poles such as tan(x) leave gaps instead of drawing vertical strokes.

function curveThrough(points: readonly Vec[]): Path

EMPTY_BOUNDSconst

const EMPTY_BOUNDS: Bounds

IDENTITYconst

const IDENTITY: Mat

invertfunction

function invert(m: Mat): Mat

linePathfunction

function linePath(a: Vec, b: Vec): Path

Mattype

2x3 affine matrix: x' = a*x + c*y + e, y' = b*x + d*y + f.

type Mat = readonly [number, number, number, number, number, number]

matScalefunction

Mean scale of a matrix, used to scale stroke widths with the geometry.

function matScale(m: Mat): number

mulfunction

function mul(m: Mat, n: Mat): Mat

parametricPathfunction

Smooth open curve through samples of a parametric function.

function parametricPath(f: (t: number) => Vec, from: number, to: number, samples?: number): Path

parseSvgPathfunction

Parse SVG path data, including arcs and relative commands, into cubic rings.

function parseSvgPath(d: string): Path

Pathtype

type Path = readonly Ring[]

pathBoundsfunction

function pathBounds(path: Path): Bounds | null

pathLengthfunction

function pathLength(path: Path): number

pathToDfunction

Serialize a path to compact SVG path data.

function pathToD(path: Path): string

pointAtfunction

Point at an arc-length fraction of a path, in the path's own coordinates.

function pointAt(path: Path, fraction: number): [number, number]

polyPathfunction

function polyPath(points: readonly Vec[], closed?: boolean): Path

rectPathfunction

function rectPath(x: number, y: number, width: number, height: number, radius?: number): Path

reverseRingfunction

function reverseRing(r: Ring): Ring

ringfunction

function ring(points: ArrayLike<number>, closed?: boolean): Ring

Ringinterface

  • p: Float64Array<ArrayBufferLike>
  • closed: boolean
  • straight?: boolean | undefinedEvery segment is a straight line, so painters can use cheap line commands.

ringCenterfunction

function ringCenter(r: Ring): [number, number]

ringLengthfunction

function ringLength(r: Ring): number

segmentCountfunction

function segmentCount(r: Ring): number

signedAreafunction

Shoelace area over the anchors. The sign gives the winding direction.

function signedArea(r: Ring): number

smoothPathfunction

A smooth cubic spline through every point (Catmull-Rom, centripetal-ish tension).

function smoothPath(points: readonly Vec[], closed?: boolean, tension?: number): Path

subdivideEachfunction

Split every segment of a ring into n equal parameter pieces. Geometry is unchanged.

function subdivideEach(r: Ring, n: number): Ring

tangentAtfunction

Unit tangent at an arc-length fraction, in the path's own coordinates.

function tangentAt(path: Path, fraction: number): [number, number]

transformPathfunction

function transformPath(path: Path, m: Mat): Path

trimPathfunction

Keep a fraction of a path. With each, every ring draws at once, which suits glyphs. Without it, rings draw one after another along the total length.

function trimPath(path: Path, from: number, to: number, each?: boolean): Path

trimRingfunction

Keep the part of a ring between two arc-length fractions.

function trimRing(r: Ring, from: number, to: number): Ring | null

unionBoundsfunction

function unionBounds(a: Bounds | null, b: Bounds | null): Bounds | null

Vectype

Vector geometry for the stage engine. Every shape is a list of rings. A ring is a run of cubic Bezier segments in a flat array: [x0, y0, c1x, c1y, c2x, c2y, x1, y1, c1x, ...]. One representation for lines, arcs, glyphs, and imported SVG makes any shape morph into any other. Rings and paths are immutable by convention. Length tables and bounds are cached per ring, so sampling the same geometry on many frames stays cheap.

type Vec = readonly [number, number]

warpPathfunction

Deform a path through any point function. Segments split first, so curved maps stay smooth.

function warpPath(path: Path, f: (x: number, y: number) => Vec, subdivisions?: number): Path

Drawing

buildOpsfunction

The draw list of a tree. backdrop is the color that a dim node goes toward, and marks gives the node that each mark of a verb is as bright as. They have an effect only in a film with a light, where spotlight gives nodes a dim under 1.

function buildOps(root: Node, camera: CameraState, width: number, height: number, backdrop?: Rgba, marks?: ReadonlyMap<Node, Node> | null): DrawOp[]

Canvas2Dtype

type Canvas2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D

DrawOptype

type DrawOp = PathOp | ImageOp

Frameinterface

  • width: number
  • height: number
  • background: string | null
  • bloom: number
  • ops: readonly DrawOp[]
  • dark: boolean

frameInkBoundsfunction

Pixel-space bounds of a frame's ink, used by checks for off-canvas marks.

function frameInkBounds(frame: Frame): { x: number; y: number; width: number; height: number; } | null

frameToSvgfunction

Serialize a frame to standalone SVG. Text is already outlines, so no fonts are needed.

function frameToSvg(frame: Frame, options?: { scale?: number | undefined; transparent?: boolean | undefined; }): string

ImageOpinterface

  • kind: "image"
  • image: StageImage
  • matrix: Mat
  • alpha: number
  • node?: Node | undefined
  • dim?: number | undefinedA dim picture: each pixel keeps this part of its color, and the rest of it is backdrop. The alpha of each pixel stays, so the clear parts of the picture stay clear.
  • backdrop?: Rgba | undefined

paintFramefunction

Paint a frame to a 2D context at a device scale. Same result as the SVG backend.

function paintFrame(ctx: Canvas2D, frame: Frame, scale?: number, images?: ImageLookup | undefined): void

PathOpinterface

  • kind: "path"
  • path: Path
  • strokePath: PathStroke geometry when it differs from the fill, such as during a partial draw.
  • fill: Paint | null
  • fillAlpha: number
  • stroke: Paint | null
  • strokeAlpha: number
  • strokeWidth: number
  • cap: "round" | "butt" | "square"
  • join: "round" | "miter" | "bevel"
  • dash: readonly number[] | null
  • dashOffset: number
  • glow: number
  • glowColor: Rgba | null
  • blend: BlendMode
  • node?: Node | undefinedThe node that produced this mark, for checks and tools.

Search

↑ ↓ to navigateEnter to openEsc to close
Editable TSX

Example source

Open in the builder

Open the builder to edit this scene, preview animations, and export your visual.

Example preview