Animation

Steps and cues as the runtime plays them: the keyframe tracks a cue.to declares, the interpolations that read them, and the controller that advances a step.

@internote/canvas-sdk21 exports

#Functions

anchorFiredAt
packages/canvas-sdk/src/animation/keyframes.ts:40
When an anchor fires, in scene-clock ms — or null if it has not fired at this progression.
(
    anchor: CueAnchor,
    steps: StepController,
    progress: StepProgress,
): number | null
easeSmooth
packages/canvas-sdk/src/animation/keyframes.ts:176
The canvas's ease-in-out, clamped to [0, 1].
(t: number): number

The one curve, named once. It is what easing: smooth means on a keyframe, what a cue's own window runs on, and what a view glides along — and it had been written out longhand in all three places plus twice more in the library, which is five chances for one of them to be a different curve.

resolveAttrValue
packages/canvas-sdk/src/animation/keyframes.ts:191
Resolve an attribute value that may or may not carry keyframes — the common read a Surface performs.
(
    value: unknown,
    steps: StepController,
    kind?: InterpolationKind,
    interpolations?: InterpolationRegistry,
): unknown
resolveTrackTransition
packages/canvas-sdk/src/animation/keyframes.ts:95
Where a !cue.to keyframe track is right now: the endpoints of its current move and the eased progress between them.
(track: KeyframeTrack, steps: StepController): TrackTransition

The last keyframe to fire is in effect. It holds the previous value for its delayMs lead-in, then eases over its over: window, then settles. Tied fire times keep source order.

track
The refined !cue.to chain: a base value and anchored keyframes.
steps
The scene's step controller, read for the current progression.
resolveTrackValue
packages/canvas-sdk/src/animation/keyframes.ts:147
The momentary value of a !cue.to keyframe track, blended by the attribute's interpolation kind while it moves.
(
    track: KeyframeTrack,
    steps: StepController,
    kind?: InterpolationKind,
    interpolations?: InterpolationRegistry,
): ResolvedTrackValue

Resolves the transition with resolveTrackTransition; mid-move, the interpolator registered for kind blends the endpoints, and a kind with no interpolator snaps.

track
The refined !cue.to chain.
steps
The scene's step controller.
kind
The attribute's declared interpolation kind.
interpolations
The registry to look kind up in.

#Classes

EnvironmentAnimationRuntime
packages/canvas-sdk/src/animation/EnvironmentAnimationRuntime.ts:96
The animation engine behind one canvas environment: presence, keyframe tracks and step dispatch.
typeof EnvironmentAnimationRuntime

Every cue construct lives inside the environment it animates and acts only within it; two environments synchronise only by anchoring to the same step indices, so a runtime never sees beyond its own node. The runtime:

  • tracks presence: children wrapped in cue/cue.draw appear when their in: anchor has fired and disappear when out: has;
  • resolves !cue.to keyframe tracks on attributes against the shared step controller;
  • calls the environment's step hook and verb handlers on step transitions — environments implement handlers, they never own timelines.

Headless by construction: no React, no DOM. Render hosts subscribe and re-render; the test host asserts directly. The host builds one per mounted environment and exposes it as ctx.animation.

InterpolationRegistry
packages/canvas-sdk/src/animation/interpolation.ts:159
How animatable value kinds blend between keyframes: one Interpolator per interpolation kind.
typeof InterpolationRegistry

Environments never own timelines, they only declare an attribute's kind, so this registry is the whole extension point for new value shapes. Interpolators run on refined values (numbers, interval records, coordinate lists…), not source text. Kinds with no meaningful in-between (discrete, and colour at the data layer — palette names are not blendable; a surface that wants visual blending resolves them to CSS and interpolates there) snap at t ≥ 0.5, as does any kind with nothing registered.

StepController
packages/canvas-sdk/src/animation/StepController.ts:75
Tracks which step a scene is on and when each step was entered, for every environment in the scene to animate against.
typeof StepController

A scene's step timeline is the partition sequence its step markers (===) carve out of the body: step 0 is the opening partition, step N becomes current when the reader passes the Nth marker. Every drive mode feeds the same controller:

  • reading view: the narrative scroll-spy calls goTo with the detected partition index;
  • presentation: keyboard step-advance calls advance/back — presentation is a drive mode over this API, not a fork;
  • headless tests: call any of them directly.

Steps also partition the scene's animation for the transport: replay plays the current step's choreography again and nothing else.

The controller records when each step was entered so time-relative anchors (at: 3 + 1.5s) and scene-time anchors (at: 1.5s) resolve against real progression. Time-based motion stays subordinate to steps.

#Constants

defaultInterpolations
packages/canvas-sdk/src/animation/interpolation.ts:187
Shared default registry — hosts that need custom kinds construct their own.
InterpolationRegistry

#Interfaces

CompiledNode
packages/canvas-sdk/src/animation/EnvironmentAnimationRuntime.ts:26
A compiled chalk node: the fields the canvas reads from each element of a compiled document.
attributes
The (…) attributes in source order, values already refined to their wire shapes.
Array<{ identifier: string; value: unknown }>
body
The {…} body: child nodes, inline content or a value, per the node's body policy.
unknown
detail
The […] detail, where the node has one (a scene's canvas content).
unknown
id
Author-declared chalk node id (curve#flight, D22) — absent unless written.
string
identifierRequired
The node's kind as written, such as canvas.graph, curve or cue.draw.
string
instance_id
The durable id the compiler gives every node instance; survives edits elsewhere in the source.
string
EnvironmentAnimationOptions
packages/canvas-sdk/src/animation/EnvironmentAnimationRuntime.ts:62
What an EnvironmentAnimationRuntime is built from.
ctxRequired
Handed through to hooks/handlers (the host passes the EnvironmentContext).
Ctx
interpolations
How keyframed values blend between keyframes; the built-in registry when absent.
InterpolationRegistry
nodeRequired
The compiled canvas.<name> node this runtime animates.
CompiledNode
onStep
The environment's step hook.
(step: number, ctx: Ctx) => void
stepsRequired
The scene's step controller, shared by every environment in the scene.
StepController
verbs
Type verbs beyond the cue family, keyed by vocabulary identifier.
Record<string, VerbHandler<Ctx>>
ResolvedTrackValue
packages/canvas-sdk/src/animation/keyframes.ts:52
A keyframe track's value at the current moment, blended when mid-transition.
activeFrameRequired
The keyframe currently in effect, if any.
CueKeyframe | null
transitioningRequired
True while inside an over: transition window.
boolean
valueRequired
The attribute's momentary value.
unknown
StepControllerOptions
packages/canvas-sdk/src/animation/StepController.ts:24
What a StepController is built from.
clock
The clock the controller reads, in ms; tests pass a manual one.
() => number
DefaultDate.now
initialStep
The step to start on; earlier steps start settled, so their content renders finished.
number
Default0
stepCountRequired
Number of step markers in the scene body; valid steps are 0..stepCount.
number
StepProgress
packages/canvas-sdk/src/animation/StepController.ts:11
Where a scene is on its step timeline and scene clock at one moment.
sceneTimeMsRequired
ms since the scene became active (controller creation or reset).
number
stepRequired
Current step index, 0-based (0 = before any marker).
number
timeInStepMsRequired
ms since the current step was entered (briefly negative during a replay's lead-in).
number
TrackTransition
packages/canvas-sdk/src/animation/keyframes.ts:66
A track's momentary transition: where it is coming from, going to, and how far along (eased).
elapsedMs
ms since that keyframe's anchor fired — the whole of its window, lead-in delay included. What a surface animating alongside the value reads: a !cue.zoom box is drawn out of this while the value is still holding.
number
frame
The keyframe in effect, when one has fired.
CueKeyframe
fromRequired
The value moving away from: the previous keyframe's, or the track's base.
unknown
tRequired
Eased progress, 1 when settled.
number
toRequired
The value moving towards; equal to from once settled or during a lead-in delay.
unknown
transitioningRequired
Whether the value is inside an over: window and actually moving.
boolean
VerbInvocation
packages/canvas-sdk/src/animation/EnvironmentAnimationRuntime.ts:43
One call to a verb handler: a vocabulary element whose anchor fired on this step.
nodeRequired
The element itself.
CompiledNode
phaseRequired
Whether the element's entry anchor (in: or at:) or its out: anchor fired.
enterexit
stepRequired
The step being entered.
number
verbRequired
The element's identifier, which selected the handler.
string

#Types

BuiltinInterpolationKind
packages/canvas-sdk/src/animation/interpolation.ts:18
The interpolation kinds the LANGUAGE has, each with an interpolator in the SDK's built-in registry.
numbernumber-listedgescolourpointintervaldiscrete

Declared per attribute; !cue.to on an attribute with no declared kind is a semantic error, so the animatable surface grows deliberately.

InterpolationKind
packages/canvas-sdk/src/animation/interpolation.ts:40
How an animatable attribute's value interpolates between keyframes: one of the built-in kinds, or a kind the environment invented.
BuiltinInterpolationKind | (string & {})

Open on purpose. An environment may declare a shape of its own and supply the interpolator for it through its definition's interpolations — the graph's plane transform is one, and while this union was closed it could only be honoured by adding 'transform' here and its interpolator to the SDK's defaults, which is how a package that knows nothing about graphs came to carry a { kind: 'matrix' } lerp. The intersection with {} is what keeps the built-in names in autocomplete while admitting the rest.

Interpolator
packages/canvas-sdk/src/animation/interpolation.ts:43
Blends two refined values of one kind at progress t (0 to 1).
(from: unknown, to: unknown, t: number) => unknown
StepListener
packages/canvas-sdk/src/animation/StepController.ts:21
Called after the current step changes, with the new step and the one left.
(step: number, previous: number) => void
VerbHandler
packages/canvas-sdk/src/animation/EnvironmentAnimationRuntime.ts:59
Called when a vocabulary element's step anchor fires, with the invocation and the environment's context.
(invocation: VerbInvocation, ctx: Ctx) => void

Only step anchors dispatch verbs; time anchors do not.

Last updated