Motion
The clock a scene keeps, the two kinds of cue anchored to it, and the durations and easings they take.
#The timeline
A scene has a timeline, and step markers (=== in the narrative) carve it into steps. Everything animated anchors to that clock: a step index (2), an absolute scene time (1500ms), or a step with an offset (2 + 500ms). The scene's duration, autoplay and loop attributes govern playback.
Cues take two forms, distinguished by where they are written: six wrap the content they act on, two are written inside an attribute's value. Both anchor the same way and take the same easing.
#Wrapping cues
- cue — fades its content in at
in:and out atout:. - cue.draw — draws it instead of fading: strokes draw along their own length, fills arrive as the stroke completes.
- cue.trace — moves its content along a referenced curve:
cue.trace{ point(x: 0; y: 0) }(path: #flight; at: 2). - cue.highlight — pushes two rings out of the mark's edge, without changing whether it is there.
- cue.spotlight — dims the rest of the pane and leaves its content lit.
- cue.type — types code in, character by character.
canvas.graph{
scatter(data: (1, 2.0), (2, 2.4), (3, 3.1))
cue{
fit(model: polynomial; degree: 1)
}(
in: 1
in-duration: 800ms
)
}#Keyframe cues
A cue may move a value instead of wrapping content. It is written inside the attribute's value, and what is written there is the base state.
#!cue.to
Each !cue.to names the value to move to and when.
canvas.graph{
curve(expression: 100 - 4.9x^2)
}(
x-domain: [0, 5] !cue.to{[0, 10]}(at: 2)
)They chain left to right on one attribute — zoom: 5 !cue.to{6.5}(at: 2) !cue.to{8}(at: 4 + 1.5s; over: 800ms) — and the animatable surface is deliberately narrow: domains, grid spacing, the show- switches, mark coordinates, hidden (a reveal that still frames the plot) and colours. Anything else is refused rather than ignored:
canvas.graph{
curve(expression: x^2)
}(
x-axis-label: time !cue.to{distance}(at: 2)
)[attribute]node `canvas.graph`: attribute `x-axis-label`: unknown micronode `cue.to`
!cue.zoom is the same move for a graph's domains, with an announcement first: a box is drawn around the smaller of the two windows and held, and only then does the view move — into the box when zooming in, out of it when zooming out. The box never moves in data coordinates. draw: and hold: time it, colour: paints it, and one chain may mix the two forms.
x-domain: [0, 10] !cue.zoom{[2, 4]}(at: 2; draw: 400ms; hold: 300ms; colour: blue)#easing, in-duration, out-duration and over
Every transition takes an easing — smooth by default, linear for constant speed — and a duration: in-duration / out-duration on cues (500ms for fades, 1500ms for draws), over: on the micronodes (1500ms). Durations are written in milliseconds, with ms and s suffixes accepted where a time is written.