@cardstack/choreo 0.0.0 → 0.1.0-unstable.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +55 -6
- package/addon-main.cjs +4 -0
- package/declarations/anchors.d.ts +26 -0
- package/declarations/anchors.d.ts.map +1 -0
- package/declarations/arming.d.ts +33 -0
- package/declarations/arming.d.ts.map +1 -0
- package/declarations/beacon.d.ts +9 -0
- package/declarations/beacon.d.ts.map +1 -0
- package/declarations/beacons.d.ts +23 -0
- package/declarations/beacons.d.ts.map +1 -0
- package/declarations/changeset.d.ts +46 -0
- package/declarations/changeset.d.ts.map +1 -0
- package/declarations/choreo.d.ts +261 -0
- package/declarations/choreo.d.ts.map +1 -0
- package/declarations/compile.d.ts +45 -0
- package/declarations/compile.d.ts.map +1 -0
- package/declarations/deliver.d.ts +44 -0
- package/declarations/deliver.d.ts.map +1 -0
- package/declarations/easings.d.ts +20 -0
- package/declarations/easings.d.ts.map +1 -0
- package/declarations/far.d.ts +33 -0
- package/declarations/far.d.ts.map +1 -0
- package/declarations/film/clip.d.ts +51 -0
- package/declarations/film/clip.d.ts.map +1 -0
- package/declarations/film/clips.d.ts +155 -0
- package/declarations/film/clips.d.ts.map +1 -0
- package/declarations/film/film.d.ts +1208 -0
- package/declarations/film/film.d.ts.map +1 -0
- package/declarations/film/graph/adjust.d.ts +112 -0
- package/declarations/film/graph/adjust.d.ts.map +1 -0
- package/declarations/film/graph/compile.d.ts +140 -0
- package/declarations/film/graph/compile.d.ts.map +1 -0
- package/declarations/film/graph/host.d.ts +67 -0
- package/declarations/film/graph/host.d.ts.map +1 -0
- package/declarations/film/graph/nodes.d.ts +287 -0
- package/declarations/film/graph/nodes.d.ts.map +1 -0
- package/declarations/film/index.d.ts +24 -0
- package/declarations/film/index.d.ts.map +1 -0
- package/declarations/film/joins.d.ts +143 -0
- package/declarations/film/joins.d.ts.map +1 -0
- package/declarations/film/math.d.ts +15 -0
- package/declarations/film/math.d.ts.map +1 -0
- package/declarations/film/overlays.d.ts +54 -0
- package/declarations/film/overlays.d.ts.map +1 -0
- package/declarations/film/picture.d.ts +104 -0
- package/declarations/film/picture.d.ts.map +1 -0
- package/declarations/film/plate.d.ts +37 -0
- package/declarations/film/plate.d.ts.map +1 -0
- package/declarations/film/player.d.ts +120 -0
- package/declarations/film/player.d.ts.map +1 -0
- package/declarations/film/rail.d.ts +40 -0
- package/declarations/film/rail.d.ts.map +1 -0
- package/declarations/film/schedule.d.ts +93 -0
- package/declarations/film/schedule.d.ts.map +1 -0
- package/declarations/film/seam.d.ts +38 -0
- package/declarations/film/seam.d.ts.map +1 -0
- package/declarations/film/titles.d.ts +37 -0
- package/declarations/film/titles.d.ts.map +1 -0
- package/declarations/film/types.d.ts +544 -0
- package/declarations/film/types.d.ts.map +1 -0
- package/declarations/film.d.ts +3 -0
- package/declarations/film.d.ts.map +1 -0
- package/declarations/gesture.d.ts +33 -0
- package/declarations/gesture.d.ts.map +1 -0
- package/declarations/index.d.ts +26 -0
- package/declarations/index.d.ts.map +1 -0
- package/declarations/measure.d.ts +29 -0
- package/declarations/measure.d.ts.map +1 -0
- package/declarations/path.d.ts +73 -0
- package/declarations/path.d.ts.map +1 -0
- package/declarations/registry.d.ts +46 -0
- package/declarations/registry.d.ts.map +1 -0
- package/declarations/run.d.ts +406 -0
- package/declarations/run.d.ts.map +1 -0
- package/declarations/space.d.ts +31 -0
- package/declarations/space.d.ts.map +1 -0
- package/declarations/steps.d.ts +479 -0
- package/declarations/steps.d.ts.map +1 -0
- package/declarations/test-support/index.d.ts +30 -0
- package/declarations/test-support/index.d.ts.map +1 -0
- package/declarations/types.d.ts +761 -0
- package/declarations/types.d.ts.map +1 -0
- package/dist/anchors.js +34 -0
- package/dist/anchors.js.map +1 -0
- package/dist/arming.js +120 -0
- package/dist/arming.js.map +1 -0
- package/dist/beacon.js +25 -0
- package/dist/beacon.js.map +1 -0
- package/dist/beacons.js +77 -0
- package/dist/beacons.js.map +1 -0
- package/dist/changeset.js +129 -0
- package/dist/changeset.js.map +1 -0
- package/dist/choreo.js +1026 -0
- package/dist/choreo.js.map +1 -0
- package/dist/compile.js +1403 -0
- package/dist/compile.js.map +1 -0
- package/dist/deliver.js +326 -0
- package/dist/deliver.js.map +1 -0
- package/dist/easings.js +39 -0
- package/dist/easings.js.map +1 -0
- package/dist/far.js +147 -0
- package/dist/far.js.map +1 -0
- package/dist/film/clip.js +100 -0
- package/dist/film/clip.js.map +1 -0
- package/dist/film/clips.js +147 -0
- package/dist/film/clips.js.map +1 -0
- package/dist/film/film.js +4424 -0
- package/dist/film/film.js.map +1 -0
- package/dist/film/graph/adjust.js +160 -0
- package/dist/film/graph/adjust.js.map +1 -0
- package/dist/film/graph/compile.js +225 -0
- package/dist/film/graph/compile.js.map +1 -0
- package/dist/film/graph/host.js +77 -0
- package/dist/film/graph/host.js.map +1 -0
- package/dist/film/graph/nodes.js +500 -0
- package/dist/film/graph/nodes.js.map +1 -0
- package/dist/film/index.js +18 -0
- package/dist/film/index.js.map +1 -0
- package/dist/film/joins.js +260 -0
- package/dist/film/joins.js.map +1 -0
- package/dist/film/math.js +49 -0
- package/dist/film/math.js.map +1 -0
- package/dist/film/overlays.js +66 -0
- package/dist/film/overlays.js.map +1 -0
- package/dist/film/picture.js +58 -0
- package/dist/film/picture.js.map +1 -0
- package/dist/film/plate.js +36 -0
- package/dist/film/plate.js.map +1 -0
- package/dist/film/player.js +79 -0
- package/dist/film/player.js.map +1 -0
- package/dist/film/rail.js +38 -0
- package/dist/film/rail.js.map +1 -0
- package/dist/film/schedule.js +238 -0
- package/dist/film/schedule.js.map +1 -0
- package/dist/film/seam.js +64 -0
- package/dist/film/seam.js.map +1 -0
- package/dist/film/titles.js +45 -0
- package/dist/film/titles.js.map +1 -0
- package/dist/film/types.js +2 -0
- package/dist/film/types.js.map +1 -0
- package/dist/film.js +18 -0
- package/dist/film.js.map +1 -0
- package/dist/gesture.js +111 -0
- package/dist/gesture.js.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/measure.js +99 -0
- package/dist/measure.js.map +1 -0
- package/dist/path.js +272 -0
- package/dist/path.js.map +1 -0
- package/dist/registry.js +55 -0
- package/dist/registry.js.map +1 -0
- package/dist/run.js +2423 -0
- package/dist/run.js.map +1 -0
- package/dist/space.js +57 -0
- package/dist/space.js.map +1 -0
- package/dist/steps.js +831 -0
- package/dist/steps.js.map +1 -0
- package/dist/test-support/index.js +150 -0
- package/dist/test-support/index.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +202 -6
|
@@ -0,0 +1,761 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vocabulary of a choreography — boxel-motion's Sprite / Changeset /
|
|
3
|
+
* AnimationDefinition, as this binding keeps them. See docs/choreography.md.
|
|
4
|
+
*/
|
|
5
|
+
import type { MotionParticipant } from 'glimmer-motion';
|
|
6
|
+
import type { AnchorRef } from './anchors.ts';
|
|
7
|
+
import type { BeaconRef } from './beacons.ts';
|
|
8
|
+
import type { GestureRef } from './gesture.ts';
|
|
9
|
+
export type SpriteType = 'inserted' | 'kept' | 'removed';
|
|
10
|
+
export interface Rect {
|
|
11
|
+
height: number;
|
|
12
|
+
width: number;
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
}
|
|
16
|
+
/** one measurement of a participant, in the three spaces a step may want it in */
|
|
17
|
+
export interface Bounds {
|
|
18
|
+
/** relative to the <Choreo> box — where an orphan is locked */
|
|
19
|
+
context: Rect;
|
|
20
|
+
/** viewport coordinates */
|
|
21
|
+
page: Rect;
|
|
22
|
+
/**
|
|
23
|
+
* The computed background the element wore when this box was taken —
|
|
24
|
+
* captured with the geometry because a removed skin's element is detached
|
|
25
|
+
* by the time a crossing wants to turn its alpha into an actual color
|
|
26
|
+
* (§4.7), and a detached element's computed style is empty.
|
|
27
|
+
*/
|
|
28
|
+
paint?: string;
|
|
29
|
+
/** relative to the element's offset parent — where a kept sprite moves */
|
|
30
|
+
parent: Rect;
|
|
31
|
+
/**
|
|
32
|
+
* The box of the element's declared subject at measure time, in page
|
|
33
|
+
* space: a `[data-choreo-substance]` descendant, or the shrink-wrap
|
|
34
|
+
* (`pack="content"`) of the element itself. A shape-matched flight
|
|
35
|
+
* aligns the SUBSTANCE when either end declares one — Keynote matches
|
|
36
|
+
* objects, not slide frames — deriving the undeclared end by fraction.
|
|
37
|
+
*/
|
|
38
|
+
substance?: Rect;
|
|
39
|
+
}
|
|
40
|
+
/** what a choreography needs from one {{motion}} element: a participant of the region it is in */
|
|
41
|
+
export type ChoreoNode = MotionParticipant;
|
|
42
|
+
export interface Sprite {
|
|
43
|
+
/** this removed sprite's identity was claimed by an arriving element as its counterpart */
|
|
44
|
+
claimed?: boolean;
|
|
45
|
+
/** the removed element an inserted id replaced in the same pass */
|
|
46
|
+
counterpart?: Sprite;
|
|
47
|
+
/** final − initial, parent-relative (kept sprites) */
|
|
48
|
+
delta?: Rect;
|
|
49
|
+
element: HTMLElement;
|
|
50
|
+
/** measured after the render pass (kept, inserted) */
|
|
51
|
+
final?: Bounds;
|
|
52
|
+
id: string | null;
|
|
53
|
+
/** measured before the render pass (kept, removed) */
|
|
54
|
+
initial?: Bounds;
|
|
55
|
+
node: ChoreoNode;
|
|
56
|
+
role: string | null;
|
|
57
|
+
/** far matching: this sprite's identity was received by another region, so its own region lets it go */
|
|
58
|
+
sent?: boolean;
|
|
59
|
+
type: SpriteType;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* boxel-motion's spritesFor criteria, plus the boundsDelta filter from its
|
|
63
|
+
* motion-study and the two halves of a counterpart pair. `received` is a kept
|
|
64
|
+
* sprite that arrived this pass carrying a counterpart — the receiving half of
|
|
65
|
+
* counterpart or far matching; `counterpart` is the removed half it claimed.
|
|
66
|
+
* Both exist so a step can address exactly the flight passes and none of the
|
|
67
|
+
* ordinary ones: a kept query also matches a sprite whose bounds merely
|
|
68
|
+
* changed, which is every resize the region ever sees.
|
|
69
|
+
*/
|
|
70
|
+
export interface Query {
|
|
71
|
+
id?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Keynote's slide rule (§4.7): only animate what a viewport can see.
|
|
74
|
+
* A removed sprite is judged against where it stood when the old scene
|
|
75
|
+
* was on screen (its initial box, measured before any crossing scroll);
|
|
76
|
+
* everything else against where it will stand (its final box, measured
|
|
77
|
+
* after). Sprites entirely outside the window are simply not selected —
|
|
78
|
+
* a leaver nobody can watch drops without a frame, an arrival below the
|
|
79
|
+
* fold just stands.
|
|
80
|
+
*/
|
|
81
|
+
onstage?: boolean;
|
|
82
|
+
role?: string;
|
|
83
|
+
type?: SpriteType | 'moved' | 'still' | 'received' | 'counterpart'
|
|
84
|
+
/** removed and claimed by nobody: what only the old scene had */
|
|
85
|
+
| 'departed';
|
|
86
|
+
}
|
|
87
|
+
export type PropValue = number | string;
|
|
88
|
+
/** a property target: one value, or a keyframe array (a round trip is an array that returns) */
|
|
89
|
+
export type PropTarget = PropValue | PropValue[];
|
|
90
|
+
/** a step property: a target, or a function of the sprite and the whole changeset */
|
|
91
|
+
export type PropSource = PropTarget | ((sprite: Sprite, changeset: ChangesetLike) => PropTarget);
|
|
92
|
+
export interface ChangesetLike {
|
|
93
|
+
all: Sprite[];
|
|
94
|
+
/** the box a `{{beacon}}` claimed this pass, or null */
|
|
95
|
+
beacon(name: string): Bounds | null;
|
|
96
|
+
/** something happened this pass a choreography could animate */
|
|
97
|
+
dirty: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* The region frame's own size in LOCAL pixels, from the same final
|
|
100
|
+
* layout every sprite was measured in — the camera's centre reference.
|
|
101
|
+
*/
|
|
102
|
+
frame?: {
|
|
103
|
+
height: number;
|
|
104
|
+
width: number;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* The color the page actually shows behind this region — the nearest
|
|
108
|
+
* ancestor with a real background. What a semi-transparent skin's alpha
|
|
109
|
+
* is blended against when a crossing turns it into an actual color.
|
|
110
|
+
*/
|
|
111
|
+
ground?: string;
|
|
112
|
+
inserted: Sprite[];
|
|
113
|
+
kept: Sprite[];
|
|
114
|
+
/**
|
|
115
|
+
* The camera zoom the world was measured under (§6.3): page-space boxes
|
|
116
|
+
* carry the frame's transform, local inline values do not, and this is
|
|
117
|
+
* the ratio between the two spaces. Absent means 1 — the frame at rest.
|
|
118
|
+
*/
|
|
119
|
+
measureZoom?: number;
|
|
120
|
+
removed: Sprite[];
|
|
121
|
+
sprite(query: Query | Query[]): Sprite | null;
|
|
122
|
+
sprites(query: Query | Query[]): Sprite[];
|
|
123
|
+
}
|
|
124
|
+
export interface SpringSpec {
|
|
125
|
+
bounce?: number;
|
|
126
|
+
damping?: number;
|
|
127
|
+
mass?: number;
|
|
128
|
+
/** how far from the target still counts as arrived (the legacy's restDisplacementThreshold) */
|
|
129
|
+
restDelta?: number;
|
|
130
|
+
/** how slow still counts as stopped (the legacy's restVelocityThreshold) */
|
|
131
|
+
restSpeed?: number;
|
|
132
|
+
stiffness?: number;
|
|
133
|
+
/** present so the `spring` helper's output fits both `@spring=` and `transition=` */
|
|
134
|
+
type?: 'spring';
|
|
135
|
+
velocity?: number;
|
|
136
|
+
visualDuration?: number;
|
|
137
|
+
}
|
|
138
|
+
interface StepBase {
|
|
139
|
+
/** start against a named step instead of this step's place in its block */
|
|
140
|
+
at?: AnchorRef;
|
|
141
|
+
/**
|
|
142
|
+
* Milliseconds before the step starts, inside its slot. The template speaks
|
|
143
|
+
* seconds (`@delay={{0.2}}`, as Motion does); the step components convert at
|
|
144
|
+
* the boundary, and everything from here down is one ms clock.
|
|
145
|
+
*/
|
|
146
|
+
delay?: number;
|
|
147
|
+
/**
|
|
148
|
+
* The yield rule (§4.7): a generic step surrenders any sprite that a
|
|
149
|
+
* specific (non-generic) step in the same timeline also names. That is
|
|
150
|
+
* how "a special exit that is NOT just a dissolve" is said — write the
|
|
151
|
+
* step, and the canned dissolve yields the sprite entirely.
|
|
152
|
+
*
|
|
153
|
+
* A COMPOSITE step should mark the children it generates generic. It is
|
|
154
|
+
* what makes an opinionated default feel like a default rather than a
|
|
155
|
+
* cage: whoever uses the composite can override one role by writing a
|
|
156
|
+
* plain step beside it, and needs no exclusion syntax to do it. Steps
|
|
157
|
+
* written directly in a template are never generic — saying it there
|
|
158
|
+
* would mean "ignore me if anyone else asks".
|
|
159
|
+
*/
|
|
160
|
+
generic?: boolean;
|
|
161
|
+
/** a label other steps may anchor against (`@at={{at 'name'}}`) */
|
|
162
|
+
name?: string;
|
|
163
|
+
of: Query | Query[];
|
|
164
|
+
/**
|
|
165
|
+
* Milliseconds between one matched sprite and the next, in the order the
|
|
166
|
+
* query returned them (seconds in the template). The step's own length grows
|
|
167
|
+
* by the whole ladder, so a sequence still waits for the last sprite.
|
|
168
|
+
*/
|
|
169
|
+
stagger?: number;
|
|
170
|
+
}
|
|
171
|
+
/** a named engine easing, a cubic-bezier as four numbers, or any function of 0..1 */
|
|
172
|
+
export type Easing = string | readonly number[] | ((t: number) => number);
|
|
173
|
+
/** Keynote's delivery panel: what the unit of delivery is, and in what order */
|
|
174
|
+
export type DeliveryBy = 'character' | 'item' | 'paragraph' | 'word';
|
|
175
|
+
export type DeliveryOrder = 'center' | 'forward' | 'random' | 'reverse';
|
|
176
|
+
export interface TweenStep extends StepBase {
|
|
177
|
+
/** split a text sprite's delivery; 'item' (default) delivers whole sprites */
|
|
178
|
+
by?: DeliveryBy;
|
|
179
|
+
ease?: Easing;
|
|
180
|
+
kind: 'tween';
|
|
181
|
+
ms: number;
|
|
182
|
+
order?: DeliveryOrder;
|
|
183
|
+
props: Record<string, PropSource>;
|
|
184
|
+
/** extra plays after the first; Infinity is an ambient loop, phase on the run clock */
|
|
185
|
+
repeat?: number;
|
|
186
|
+
repeatType?: 'loop' | 'mirror' | 'reverse';
|
|
187
|
+
/** Normalized keyframe offsets; omitted means evenly spaced. */
|
|
188
|
+
times?: number[];
|
|
189
|
+
}
|
|
190
|
+
export interface SpringStep extends StepBase {
|
|
191
|
+
by?: DeliveryBy;
|
|
192
|
+
kind: 'spring';
|
|
193
|
+
order?: DeliveryOrder;
|
|
194
|
+
props: Record<string, PropSource>;
|
|
195
|
+
spring?: SpringSpec;
|
|
196
|
+
}
|
|
197
|
+
export interface MoveStep extends StepBase {
|
|
198
|
+
ease?: Easing;
|
|
199
|
+
/** borrow a beacon's box — or the live gesture — as the start of the move */
|
|
200
|
+
from?: BeaconRef | GestureRef;
|
|
201
|
+
kind: 'move';
|
|
202
|
+
ms?: number;
|
|
203
|
+
/**
|
|
204
|
+
* An SVG path for the journey, drawn from where the sprite stands (§4.4).
|
|
205
|
+
* The path is similarity-mapped so its start is the sprite's start and its
|
|
206
|
+
* end is the measured landing — the path bends the journey, never the
|
|
207
|
+
* destination.
|
|
208
|
+
*/
|
|
209
|
+
path?: string;
|
|
210
|
+
/** 'auto' orients along the tangent; a number adds a constant offset to it */
|
|
211
|
+
rotate?: 'auto' | number;
|
|
212
|
+
/** animate width/height as well as position (default true) */
|
|
213
|
+
/**
|
|
214
|
+
* `false` skips size; `'scale'` matches shape by TRANSFORM about the
|
|
215
|
+
* centre instead of animating layout width/height — a flight that must
|
|
216
|
+
* not reflow the scene around it (the crossing's receiver was
|
|
217
|
+
* stretching its whole grid row). Content distorts through the flight
|
|
218
|
+
* exactly as a Magic Move's does; the crossfade hides it. `'crop'` is
|
|
219
|
+
* iOS's rule instead: UNIFORM scale, matched by cover, with the aspect
|
|
220
|
+
* mismatch carried by an animated crop window — the old box at liftoff,
|
|
221
|
+
* the element's own at landing — so nothing ever stretches.
|
|
222
|
+
*/
|
|
223
|
+
size?: boolean | 'crop' | 'scale';
|
|
224
|
+
/**
|
|
225
|
+
* Which space the delta is measured in (§6.1). 'page' (default) is the
|
|
226
|
+
* one space two regions agree on; 'parent' resolves the flight against
|
|
227
|
+
* the sprite's own (possibly animating) container.
|
|
228
|
+
*/
|
|
229
|
+
space?: 'page' | 'parent';
|
|
230
|
+
spring?: SpringSpec;
|
|
231
|
+
/** the counterpart-skin policy: cross mid-flight, carry to the landing, or neither (§6.3) */
|
|
232
|
+
swap?: 'during' | 'none' | 'settle';
|
|
233
|
+
/** borrow a beacon's box as the end of the move instead of where the sprite landed */
|
|
234
|
+
to?: BeaconRef;
|
|
235
|
+
}
|
|
236
|
+
export interface HoldStep extends StepBase {
|
|
237
|
+
/** keep the values after the window instead of releasing them */
|
|
238
|
+
fill?: boolean;
|
|
239
|
+
kind: 'hold';
|
|
240
|
+
/** the window; without it, the enclosing block's span */
|
|
241
|
+
ms?: number;
|
|
242
|
+
props: Record<string, PropSource>;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The steps that have no subject. A wait is a hole in a sequence and a
|
|
246
|
+
* tether reads only its two ends — neither has anything to say about the
|
|
247
|
+
* sprite `of` would name, and requiring one meant every author wrote
|
|
248
|
+
* `@of={{c.all}}`: a query run on every pass to answer a question nothing
|
|
249
|
+
* asks, and a lie about what the step reads. Absent, the step produces one
|
|
250
|
+
* cue rather than one per sprite.
|
|
251
|
+
*/
|
|
252
|
+
interface SubjectlessBase extends Omit<StepBase, 'of'> {
|
|
253
|
+
of?: Query | Query[];
|
|
254
|
+
}
|
|
255
|
+
export interface WaitStep extends SubjectlessBase {
|
|
256
|
+
kind: 'wait';
|
|
257
|
+
ms: number;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* A semantic command on the timeline (§C4): dispatched once as playback
|
|
261
|
+
* crosses its time, included by a seek that lands past it, excluded — via
|
|
262
|
+
* reset-and-replay — by a seek that lands before it. A command is an
|
|
263
|
+
* idempotent statement of state (`lightbox.open`), never a time-sensitive
|
|
264
|
+
* toggle: the fold re-derives the commanded state from the clock, so a
|
|
265
|
+
* command may be dispatched again whenever the state is re-derived.
|
|
266
|
+
*/
|
|
267
|
+
export interface PerformStep extends SubjectlessBase {
|
|
268
|
+
action: string;
|
|
269
|
+
kind: 'perform';
|
|
270
|
+
payload?: unknown;
|
|
271
|
+
target?: string;
|
|
272
|
+
}
|
|
273
|
+
/** a `c.Perform` command as the run hands it to the host's dispatcher */
|
|
274
|
+
export interface PerformCommand {
|
|
275
|
+
action: string;
|
|
276
|
+
payload?: unknown;
|
|
277
|
+
target?: string;
|
|
278
|
+
/** the command's place on the run's clock, seconds at 1× */
|
|
279
|
+
time: number;
|
|
280
|
+
}
|
|
281
|
+
/** scroll the sprite's container so the sprite lands at @align (§6.1) */
|
|
282
|
+
export interface ScrollStep extends StepBase {
|
|
283
|
+
align?: 'center' | 'end' | 'start';
|
|
284
|
+
kind: 'scroll';
|
|
285
|
+
ms?: number;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Promote the sprites to the region's elevated layer for the window (§6.3):
|
|
289
|
+
* above every stacking context and overflow clip in the region. `z-index`
|
|
290
|
+
* cannot say this; a real layer can.
|
|
291
|
+
*/
|
|
292
|
+
export interface RaiseStep extends StepBase {
|
|
293
|
+
kind: 'raise';
|
|
294
|
+
/** the window; without it, the enclosing block's span */
|
|
295
|
+
ms?: number;
|
|
296
|
+
/** cast on the layer below — the tray's shadow on the plane beneath */
|
|
297
|
+
shadow?: boolean;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* The region's frame as a timeline step (§6.3): zoom and pan the scene,
|
|
301
|
+
* `@origin` aiming at a sprite, `@steady` naming sprites that keep their
|
|
302
|
+
* size (damped by default — the relative-scale research's curves, §6.4).
|
|
303
|
+
*/
|
|
304
|
+
export interface CameraStep extends StepBase {
|
|
305
|
+
/**
|
|
306
|
+
* Dive on this sprite and centre it: the library computes zoom AND pan
|
|
307
|
+
* from the sprite's rest-layout box and the frame's own size — the same
|
|
308
|
+
* measurement space FLIP uses, so it is correct even when the click
|
|
309
|
+
* lands mid-flight on a different tile. `null` (as opposed to absent)
|
|
310
|
+
* says "fit nothing": back to the resting identity. `@zoom` alongside
|
|
311
|
+
* overrides the computed magnification but keeps the centring.
|
|
312
|
+
*/
|
|
313
|
+
/** recentre on this sprite, zoom held — the Aim preset's field */
|
|
314
|
+
aim?: Query;
|
|
315
|
+
ease?: Easing;
|
|
316
|
+
fit?: Query | null;
|
|
317
|
+
kind: 'camera';
|
|
318
|
+
/**
|
|
319
|
+
* With `fit`: the fraction of the frame the sprite fills once centred,
|
|
320
|
+
* on whichever axis fits first. Defaults to 0.72.
|
|
321
|
+
*/
|
|
322
|
+
margin?: number;
|
|
323
|
+
ms?: number;
|
|
324
|
+
/** aim the zoom at this sprite's centre — held in place, not recentred */
|
|
325
|
+
origin?: Query;
|
|
326
|
+
/** shift the pose in force by this many px — the Pan preset's field */
|
|
327
|
+
panBy?: {
|
|
328
|
+
x?: number;
|
|
329
|
+
y?: number;
|
|
330
|
+
};
|
|
331
|
+
spring?: SpringSpec;
|
|
332
|
+
/** sprites that hold their size against the zoom, damped */
|
|
333
|
+
steady?: Query | Query[];
|
|
334
|
+
x?: number;
|
|
335
|
+
y?: number;
|
|
336
|
+
zoom?: number;
|
|
337
|
+
/** multiply the zoom in force by this factor — the SlowZoom preset */
|
|
338
|
+
zoomBy?: number;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Geometry continuously derived from sprites (§6.1): every frame of the run
|
|
342
|
+
* (and every scrubbed still), `@path` receives both endpoints' boxes,
|
|
343
|
+
* region-relative, and returns the path data the tether draws.
|
|
344
|
+
*/
|
|
345
|
+
/**
|
|
346
|
+
* An orbit pose, in the terms a shoot uses rather than a matrix: where the
|
|
347
|
+
* eye stands relative to the subject.
|
|
348
|
+
*
|
|
349
|
+
* Choreo does not own a 3D renderer and should not pretend to. What it owns
|
|
350
|
+
* is TIME — the ordering, the easing, and the guarantee that a pose is a
|
|
351
|
+
* pure function of the clock — so `Camera3D` carries intent and the host
|
|
352
|
+
* applies it to whatever it is actually drawing with: three.js, a CSS 3D
|
|
353
|
+
* stage, anything that can take three numbers. That is the same split the
|
|
354
|
+
* composition doc asks for (§ "The second primitive: camera"): the preset
|
|
355
|
+
* expands into one seekable step, and an adapter does the drawing.
|
|
356
|
+
*/
|
|
357
|
+
export interface Camera3DState {
|
|
358
|
+
/** distance as a multiple of the host's own framing; 1 is "as framed" */
|
|
359
|
+
dolly: number;
|
|
360
|
+
/**
|
|
361
|
+
* The orbit's CENTRE, in the host's own scene units — the missing sixth
|
|
362
|
+
* number the Sylva spike had to route around the score as Perform cues.
|
|
363
|
+
* A pose with an implied centre works while a scene has one subject; the
|
|
364
|
+
* moment it has several, the centre must move, and it must move ON THE
|
|
365
|
+
* CLOCK: part of the tweened pose, reconstructible by a scrub, not a
|
|
366
|
+
* side-channel with an easing of its own. Optional, so every host that
|
|
367
|
+
* never aims (the mockup's phone is always the centre) is untouched.
|
|
368
|
+
*/
|
|
369
|
+
look?: {
|
|
370
|
+
x: number;
|
|
371
|
+
y: number;
|
|
372
|
+
z: number;
|
|
373
|
+
};
|
|
374
|
+
/** degrees above the subject */
|
|
375
|
+
pitch: number;
|
|
376
|
+
/**
|
|
377
|
+
* Truck and pedestal, as fractions of the subject's framed height.
|
|
378
|
+
*
|
|
379
|
+
* Dolly alone cannot hold a tall subject in frame: push in on a phone
|
|
380
|
+
* and its top leaves the picture. A real operator moves the camera
|
|
381
|
+
* sideways and up as they push, so the part being read stays centred —
|
|
382
|
+
* these are that move, and they are what makes a close-up legible
|
|
383
|
+
* rather than a crop.
|
|
384
|
+
*/
|
|
385
|
+
x: number;
|
|
386
|
+
y: number;
|
|
387
|
+
/** degrees around it */
|
|
388
|
+
yaw: number;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* One waypoint on a `@through` path. Anything omitted carries forward from
|
|
392
|
+
* the previous waypoint (and, for the first, from the pose in force), the
|
|
393
|
+
* way keyframe holds work everywhere else.
|
|
394
|
+
*/
|
|
395
|
+
export interface Camera3DWaypoint {
|
|
396
|
+
/**
|
|
397
|
+
* A SPLICE. This waypoint is the first frame of a NEW SHOT: the path
|
|
398
|
+
* splits here, each side is sampled as its own clamped spline, and the
|
|
399
|
+
* pose is a step function at this waypoint's own instant — the outgoing
|
|
400
|
+
* shot plays through the seam, the incoming one begins exactly on it,
|
|
401
|
+
* and nothing interpolates across. Time is not redistributed, so cues
|
|
402
|
+
* anchored to waypoint moments keep their clock. A cut on the FIRST
|
|
403
|
+
* waypoint drops the pose-in-force seed: the score opens already inside
|
|
404
|
+
* its first shot. See docs/choreo-splices.md.
|
|
405
|
+
*/
|
|
406
|
+
cut?: boolean;
|
|
407
|
+
dolly?: number;
|
|
408
|
+
look?: {
|
|
409
|
+
x: number;
|
|
410
|
+
y: number;
|
|
411
|
+
z: number;
|
|
412
|
+
};
|
|
413
|
+
pitch?: number;
|
|
414
|
+
x?: number;
|
|
415
|
+
y?: number;
|
|
416
|
+
yaw?: number;
|
|
417
|
+
}
|
|
418
|
+
export interface Camera3DStep extends StepBase {
|
|
419
|
+
/** add to the pose in force instead of replacing it — Pan's rule, in 3D */
|
|
420
|
+
by?: boolean;
|
|
421
|
+
dolly?: number;
|
|
422
|
+
ease?: Easing;
|
|
423
|
+
kind: 'camera3d';
|
|
424
|
+
/** the orbit centre this shot aims at — see Camera3DState.look */
|
|
425
|
+
look?: {
|
|
426
|
+
x: number;
|
|
427
|
+
y: number;
|
|
428
|
+
z: number;
|
|
429
|
+
};
|
|
430
|
+
ms?: number;
|
|
431
|
+
pitch?: number;
|
|
432
|
+
/**
|
|
433
|
+
* SMOOTHING, in seconds of the cue's own clock: the reported pose is a
|
|
434
|
+
* centred average of the path over a window this wide, which takes the
|
|
435
|
+
* curvature step out of every waypoint without a spring and without
|
|
436
|
+
* lag. It stays a pure function of the clock, so a scrub and a render
|
|
437
|
+
* agree with a play. The window tapers to nothing at a `cut` and at
|
|
438
|
+
* either end of the path, so cuts stay hard and the landing is exact.
|
|
439
|
+
* A quarter of the gap between waypoints is a good starting point;
|
|
440
|
+
* much more and the path stops visiting them.
|
|
441
|
+
*/
|
|
442
|
+
settle?: number;
|
|
443
|
+
spring?: SpringSpec;
|
|
444
|
+
/**
|
|
445
|
+
* A PATH, not a pair: the shot runs from the pose in force THROUGH these
|
|
446
|
+
* waypoints on one clock, sampled along a Catmull-Rom spline in pose
|
|
447
|
+
* space — so the camera crosses every waypoint with continuous velocity
|
|
448
|
+
* instead of parking at each one, which no chain of two-point tweens can
|
|
449
|
+
* do without hand-matched eases. The step's own pose args are ignored
|
|
450
|
+
* when this is present; the last waypoint is the destination. `@by` does
|
|
451
|
+
* not combine with it, and the ease applies to progress along the WHOLE
|
|
452
|
+
* path ('linear' is usually what a path wants — the spline is the shape).
|
|
453
|
+
* Yaw is interpolated numerically: unwrap it in the waypoints, the way
|
|
454
|
+
* any tween here expects.
|
|
455
|
+
*/
|
|
456
|
+
/**
|
|
457
|
+
* How tight a `@through` path holds its line: 0 is classic Catmull-Rom
|
|
458
|
+
* (lively, will sway), 1 is piecewise-linear, and the default 0.5 is a
|
|
459
|
+
* camera operator's steady hand.
|
|
460
|
+
*/
|
|
461
|
+
tension?: number;
|
|
462
|
+
through?: Camera3DWaypoint[];
|
|
463
|
+
/** truck / pedestal, in fractions of the framed height */
|
|
464
|
+
x?: number;
|
|
465
|
+
y?: number;
|
|
466
|
+
yaw?: number;
|
|
467
|
+
}
|
|
468
|
+
export interface TetherStep extends SubjectlessBase {
|
|
469
|
+
from: Query;
|
|
470
|
+
kind: 'tether';
|
|
471
|
+
/** the window; without it, the enclosing block's span */
|
|
472
|
+
ms?: number;
|
|
473
|
+
path: (from: Rect, to: Rect) => string;
|
|
474
|
+
to: Query;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* One source of a derived value: the boxes the PASS measured, in region
|
|
478
|
+
* space, named for which box each one is — because the distinction
|
|
479
|
+
* between resting and live geometry is the whole correctness argument
|
|
480
|
+
* (docs/postmortem-follow.md). `from` and `to` are resting layout, where
|
|
481
|
+
* the stylesheet put the sprite on either side of this change; `now` is
|
|
482
|
+
* `to` composed with the transform the run is driving this frame. None
|
|
483
|
+
* of the three is read from the page while the run plays.
|
|
484
|
+
*/
|
|
485
|
+
export interface FollowSource {
|
|
486
|
+
/** its resting box before this change (equal to `to` when it did not move) */
|
|
487
|
+
from: Rect;
|
|
488
|
+
/** where the run holds it THIS frame — arithmetic, not a measurement */
|
|
489
|
+
now: Rect;
|
|
490
|
+
/** its resting box after the change — where the run will land it */
|
|
491
|
+
to: Rect;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* What a derived value is computed FROM, handed to `@read` every frame
|
|
495
|
+
* and every scrubbed still. All geometry comes from the pass's own
|
|
496
|
+
* measurements, region-relative, so a follower lands on its source at
|
|
497
|
+
* any camera zoom — and never touches the page while it runs.
|
|
498
|
+
*/
|
|
499
|
+
export interface DeriveContext {
|
|
500
|
+
/** where the region's frame stands this frame */
|
|
501
|
+
camera: CameraState;
|
|
502
|
+
/** 0..1 across this step's own window */
|
|
503
|
+
p: number;
|
|
504
|
+
/** the driven sprite's own RESTING box — it never contains what the follower writes */
|
|
505
|
+
rest: Rect;
|
|
506
|
+
/** the sprites named by `@to`, in the order the query returned them */
|
|
507
|
+
sources: FollowSource[];
|
|
508
|
+
/** seconds on the run's clock */
|
|
509
|
+
t: number;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* A value derived from the scene rather than interpolated between two
|
|
513
|
+
* keyframes (§4.10) — a badge that rides a flying card, a label held
|
|
514
|
+
* upright under a rotating parent, a readout that tracks a box.
|
|
515
|
+
*
|
|
516
|
+
* `@read` is pure BY CONSTRUCTION: it is handed boxes the pass already
|
|
517
|
+
* measured — never the live page — so there is no way for a follower to
|
|
518
|
+
* read back what it just wrote, and nothing it does can force a style
|
|
519
|
+
* recalculation mid-move. It must still be a pure function of its
|
|
520
|
+
* context: the run is scrubbable in both directions, and a derived value
|
|
521
|
+
* with memory would make a seek irreproducible. It is computed on the
|
|
522
|
+
* main thread every frame — a follower can never be handed to the
|
|
523
|
+
* compositor — and it may only write transform, opacity and filter
|
|
524
|
+
* properties, because a derived write that changed layout would fail the
|
|
525
|
+
* region's fast keep on every frame.
|
|
526
|
+
*/
|
|
527
|
+
export interface FollowStep extends StepBase {
|
|
528
|
+
kind: 'follow';
|
|
529
|
+
/** the window; without it, the enclosing block's span */
|
|
530
|
+
ms?: number;
|
|
531
|
+
read: (ctx: DeriveContext) => Record<string, PropValue>;
|
|
532
|
+
/** what each written property is at rest, so a measure pass can undo it */
|
|
533
|
+
rest: Record<string, PropValue>;
|
|
534
|
+
/** what to read — one query, however many sprites it returns */
|
|
535
|
+
to: Query | Query[];
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* ATTACH — drive another region's run over a window of this one's clock
|
|
539
|
+
* (docs/film-graph/CONSTRUCTS.md, construct 1). The child is named by its
|
|
540
|
+
* `@id`; while the window is open its run is paused and told the time,
|
|
541
|
+
* `in + (now − start) × rate`, on every evaluate — so the child is a pure
|
|
542
|
+
* function of the parent's clock and a seek into the window lands it
|
|
543
|
+
* where playing there would. Past the window the end policy holds it at
|
|
544
|
+
* its tail (`hold`) or leaves it to whoever unmounts it (`remove`).
|
|
545
|
+
* Under `exact`, a child whose score integrates (a spring, a follow) is
|
|
546
|
+
* refused: an integrator's state is its history, and a driven clock has
|
|
547
|
+
* none.
|
|
548
|
+
*/
|
|
549
|
+
export interface AttachStep extends SubjectlessBase {
|
|
550
|
+
/** past the window: stand the child at its tail, or leave it alone */
|
|
551
|
+
end?: 'hold' | 'remove';
|
|
552
|
+
/** refuse a child that cannot be driven exactly */
|
|
553
|
+
exact?: boolean;
|
|
554
|
+
/** seconds into the child's run at the window's head */
|
|
555
|
+
in?: number;
|
|
556
|
+
kind: 'attach';
|
|
557
|
+
/** the window on this run's clock, ms */
|
|
558
|
+
ms: number;
|
|
559
|
+
/** the child's seconds per parent second */
|
|
560
|
+
rate?: number;
|
|
561
|
+
/** the region to drive: its `@id` */
|
|
562
|
+
region: string;
|
|
563
|
+
}
|
|
564
|
+
export type Step = AttachStep | Camera3DStep | CameraStep | FollowStep | HoldStep | MoveStep | PerformStep | RaiseStep | ScrollStep | SpringStep | TetherStep | TweenStep | WaitStep;
|
|
565
|
+
/** park the run until advance(); `ms` opens it by itself (§4.1) */
|
|
566
|
+
export interface GateNode {
|
|
567
|
+
kind: 'gate';
|
|
568
|
+
/** self-open delay, ms (template: `@delay` seconds) */
|
|
569
|
+
ms?: number;
|
|
570
|
+
}
|
|
571
|
+
export interface Block {
|
|
572
|
+
/**
|
|
573
|
+
* Start against a named step or block instead of this block's place in
|
|
574
|
+
* its own block's flow. An anchored block lifts out exactly as an
|
|
575
|
+
* anchored step does (§4.2): it neither pushes a sequence forward nor
|
|
576
|
+
* stretches its parent's span.
|
|
577
|
+
*/
|
|
578
|
+
at?: AnchorRef;
|
|
579
|
+
children: TimelineNode[];
|
|
580
|
+
/**
|
|
581
|
+
* Milliseconds before the block's contents start, inside its slot. The
|
|
582
|
+
* template speaks seconds; the block component converts at the boundary.
|
|
583
|
+
*/
|
|
584
|
+
delay?: number;
|
|
585
|
+
kind: 'parallel' | 'sequence';
|
|
586
|
+
/**
|
|
587
|
+
* A label other steps may anchor against — the block's span is its
|
|
588
|
+
* contents, so `{{after 'intro'}}` means after the LONGEST thing in it.
|
|
589
|
+
* This is what makes a composite step (a `node()` that returns a block —
|
|
590
|
+
* `c.Crossing`, and anything an author writes) something the rest of the
|
|
591
|
+
* score can point at, rather than an opaque lump.
|
|
592
|
+
*/
|
|
593
|
+
name?: string;
|
|
594
|
+
}
|
|
595
|
+
export type TimelineNode = Block | GateNode | Step;
|
|
596
|
+
/** a gate, placed on the run's clock */
|
|
597
|
+
export interface GateMark {
|
|
598
|
+
at: number;
|
|
599
|
+
/** self-open: resume this long after parking, unadvanced */
|
|
600
|
+
auto?: number;
|
|
601
|
+
}
|
|
602
|
+
export interface Compiled {
|
|
603
|
+
cues: Cue[];
|
|
604
|
+
gates: GateMark[];
|
|
605
|
+
/**
|
|
606
|
+
* The score has no length of its own: every cue in it is an OPEN step
|
|
607
|
+
* (a tether, hold, raise or follow without `@duration`) and there is no
|
|
608
|
+
* enclosing span for them to borrow. Such a score is an annotation that
|
|
609
|
+
* is simply on, and its run stands rather than ending — see Cue.standing.
|
|
610
|
+
*/
|
|
611
|
+
open?: boolean;
|
|
612
|
+
}
|
|
613
|
+
/** where the region's frame stands — yielded, tracked, updated at step boundaries */
|
|
614
|
+
export interface CameraState {
|
|
615
|
+
x: number;
|
|
616
|
+
y: number;
|
|
617
|
+
zoom: number;
|
|
618
|
+
}
|
|
619
|
+
/** a sampled flight path: points at even progress, in the sprite's own space */
|
|
620
|
+
export interface FlightPath {
|
|
621
|
+
points: {
|
|
622
|
+
x: number;
|
|
623
|
+
y: number;
|
|
624
|
+
}[];
|
|
625
|
+
/** what the element's x/y are at rest, to subtract for kept sprites */
|
|
626
|
+
rest: {
|
|
627
|
+
x: number;
|
|
628
|
+
y: number;
|
|
629
|
+
};
|
|
630
|
+
/** tangent-follow: degrees added on top when a number was given */
|
|
631
|
+
rotate?: 'auto' | number;
|
|
632
|
+
}
|
|
633
|
+
/** one resolved thing to do to one sprite, in milliseconds from the run's start */
|
|
634
|
+
export interface Cue {
|
|
635
|
+
/**
|
|
636
|
+
* These values are BORROWED, not owned: the run removes them — motion
|
|
637
|
+
* value and inline style both — when it ends or is released, so the
|
|
638
|
+
* stylesheet's own declaration stands again. The crossing's color-carry
|
|
639
|
+
* uses this: the solid it paints mid-flight is handed back to the real
|
|
640
|
+
* alpha blend on landing.
|
|
641
|
+
*/
|
|
642
|
+
attach?: {
|
|
643
|
+
end: 'hold' | 'remove';
|
|
644
|
+
exact: boolean;
|
|
645
|
+
in: number;
|
|
646
|
+
rate: number;
|
|
647
|
+
region: string;
|
|
648
|
+
};
|
|
649
|
+
borrow?: boolean;
|
|
650
|
+
/** camera: drive the region's frame */
|
|
651
|
+
camera?: {
|
|
652
|
+
/** relative move: resolved against the pose in force at cue start */
|
|
653
|
+
by?: {
|
|
654
|
+
x?: number;
|
|
655
|
+
y?: number;
|
|
656
|
+
zoom?: number;
|
|
657
|
+
};
|
|
658
|
+
/** the frame's centre in the same final layout `origin` was measured in */
|
|
659
|
+
centre?: {
|
|
660
|
+
x: number;
|
|
661
|
+
y: number;
|
|
662
|
+
};
|
|
663
|
+
origin?: {
|
|
664
|
+
x: number;
|
|
665
|
+
y: number;
|
|
666
|
+
};
|
|
667
|
+
steady: Sprite[];
|
|
668
|
+
to: {
|
|
669
|
+
x?: number;
|
|
670
|
+
y?: number;
|
|
671
|
+
zoom?: number;
|
|
672
|
+
};
|
|
673
|
+
};
|
|
674
|
+
/** camera3d: hand an orbit pose to the host, every frame it changes */
|
|
675
|
+
camera3d?: {
|
|
676
|
+
by?: boolean;
|
|
677
|
+
/** smoothing window for a `through` path, seconds — see Camera3DStep */
|
|
678
|
+
settle?: number;
|
|
679
|
+
tension?: number;
|
|
680
|
+
through?: Camera3DWaypoint[];
|
|
681
|
+
to: {
|
|
682
|
+
dolly?: number;
|
|
683
|
+
look?: {
|
|
684
|
+
x: number;
|
|
685
|
+
y: number;
|
|
686
|
+
z: number;
|
|
687
|
+
};
|
|
688
|
+
pitch?: number;
|
|
689
|
+
x?: number;
|
|
690
|
+
y?: number;
|
|
691
|
+
yaw?: number;
|
|
692
|
+
};
|
|
693
|
+
};
|
|
694
|
+
/** text delivery: the run splits the sprite and plays the slots inside `duration` */
|
|
695
|
+
delivery?: {
|
|
696
|
+
by: DeliveryBy;
|
|
697
|
+
order: DeliveryOrder;
|
|
698
|
+
stagger: number;
|
|
699
|
+
};
|
|
700
|
+
/** follow: compute this sprite's values from the pass's measurements, every frame */
|
|
701
|
+
derive?: {
|
|
702
|
+
read: (ctx: DeriveContext) => Record<string, PropValue>;
|
|
703
|
+
rest: Record<string, PropValue>;
|
|
704
|
+
/** the follower's own resting box, region space, from the pass */
|
|
705
|
+
restBox: Rect;
|
|
706
|
+
/** each source's measured ends, with the sprite whose transform composes `now` */
|
|
707
|
+
sources: {
|
|
708
|
+
from: Rect;
|
|
709
|
+
sprite: Sprite;
|
|
710
|
+
to: Rect;
|
|
711
|
+
}[];
|
|
712
|
+
};
|
|
713
|
+
duration: number;
|
|
714
|
+
/** move: travel along this sampled path instead of the straight line */
|
|
715
|
+
flight?: FlightPath;
|
|
716
|
+
/** hold: the values to set (and whether to keep them) */
|
|
717
|
+
hold?: {
|
|
718
|
+
fill: boolean;
|
|
719
|
+
values: Record<string, PropValue>;
|
|
720
|
+
};
|
|
721
|
+
kind: Step['kind'];
|
|
722
|
+
/** an infinite-repeat tween: plays past the run's end, excluded from its length */
|
|
723
|
+
loop?: boolean;
|
|
724
|
+
/** perform: the semantic command the fold dispatches at this cue's time */
|
|
725
|
+
perform?: {
|
|
726
|
+
action: string;
|
|
727
|
+
payload?: unknown;
|
|
728
|
+
target?: string;
|
|
729
|
+
};
|
|
730
|
+
/** raise: promote to the elevated layer for the window */
|
|
731
|
+
raise?: {
|
|
732
|
+
shadow: boolean;
|
|
733
|
+
};
|
|
734
|
+
/** scroll: animate the sprite's scroll container to this alignment */
|
|
735
|
+
scroll?: {
|
|
736
|
+
align: 'center' | 'end' | 'start';
|
|
737
|
+
};
|
|
738
|
+
sprite: Sprite;
|
|
739
|
+
/**
|
|
740
|
+
* An open step in a score with no span to borrow: it holds from its start
|
|
741
|
+
* until the run is cancelled or replaced, and its (infinite) duration is
|
|
742
|
+
* excluded from the run's length. The standing wire, the standing raise —
|
|
743
|
+
* an annotation whose lifetime is the scene's, not a step's.
|
|
744
|
+
*/
|
|
745
|
+
standing?: boolean;
|
|
746
|
+
start: number;
|
|
747
|
+
/** tween / spring / move: the engine target… */
|
|
748
|
+
target?: Record<string, unknown>;
|
|
749
|
+
/** tether: draw between these two, every frame */
|
|
750
|
+
tether?: {
|
|
751
|
+
from: Sprite | null;
|
|
752
|
+
/** the step's @name, forwarded so the path can be styled per wire */
|
|
753
|
+
name?: string;
|
|
754
|
+
path: (from: Rect, to: Rect) => string;
|
|
755
|
+
to: Sprite | null;
|
|
756
|
+
};
|
|
757
|
+
/** …and its transition, without the delay the start supplies */
|
|
758
|
+
transition?: Record<string, unknown>;
|
|
759
|
+
}
|
|
760
|
+
export {};
|
|
761
|
+
//# sourceMappingURL=types.d.ts.map
|