@cardstack/choreo 0.0.0 → 0.1.0-unstable.1
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 +22 -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 +201 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../src/measure.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAW/C,0BAA0B;AAC1B,eAAO,MAAM,IAAI,GAAI,GAAG,OAAO,KAAG,IAKhC,CAAC;AAEH,iEAAiE;AACjE,eAAO,MAAM,KAAK,GAAI,GAAG,OAAO,EAAE,GAAG,OAAO,KAAG,IAK7C,CAAC;AAEH,qEAAqE;AACrE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,OAAO,CAAC;IACZ,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,IAAI,OAAO,KAAG,OAAO,GAAG,SAY9C,CAAC;AAeF,gFAAgF;AAChF,eAAO,MAAM,SAAS,GAAI,IAAI,OAAO,KAAG,OAKb,CAAC;AAE5B,eAAO,MAAM,OAAO,GAAI,IAAI,OAAO,KAAG,QAWpC,CAAC;AAEH,iEAAiE;AACjE,eAAO,MAAM,QAAQ,GAAI,MAAM,QAAQ,EAAE,MAAM,OAAO,KAAG,MAMvD,CAAC;AAEH,oEAAoE;AACpE,eAAO,MAAM,aAAa,GAAI,IAAI,OAAO,EAAE,MAAM,OAAO,KAAG,MAC9B,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE CAMERA'S PATH — the arithmetic behind `c.Camera3D @through`, and
|
|
3
|
+
* the only place in Choreo that owns a curve rather than a tween.
|
|
4
|
+
*
|
|
5
|
+
* Everything here is a pure function of PROGRESS. That is the whole
|
|
6
|
+
* point: a seek must land the shot exactly where playing there would, so
|
|
7
|
+
* nothing in this file may remember a previous frame. A spline that is
|
|
8
|
+
* sampled rather than integrated can be scrubbed, rendered a frame at a
|
|
9
|
+
* time, and played, and all three agree by construction.
|
|
10
|
+
*/
|
|
11
|
+
import type { Camera3DState, Camera3DWaypoint } from './types.ts';
|
|
12
|
+
/**
|
|
13
|
+
* Sample the spline at overall progress p ∈ [0, 1] (uniform segments).
|
|
14
|
+
*
|
|
15
|
+
* SPLICES (docs/choreo-splices.md): a waypoint marked `cut` starts a new
|
|
16
|
+
* SHOT. Each shot is a clamped spline of its own points — endpoint
|
|
17
|
+
* tangents one-sided, so no shot's velocity crosses a seam — and each
|
|
18
|
+
* shot's window runs from its first slot to the next seam, its points
|
|
19
|
+
* spread uniformly across it. The outgoing shot therefore plays through
|
|
20
|
+
* the seam instant (its motion stretches by one slot rather than
|
|
21
|
+
* parking), the incoming one begins exactly on it, and the sampled pose
|
|
22
|
+
* is a step function at the seam. Waypoints keep their uniform slots, so
|
|
23
|
+
* cues anchored to waypoint moments keep their clock. A cut on the first
|
|
24
|
+
* waypoint drops the pose-in-force seed: the score opens inside its
|
|
25
|
+
* first shot.
|
|
26
|
+
*/
|
|
27
|
+
export declare function sampleThrough(from: Camera3DState, through: Camera3DWaypoint[], progress: number, tension?: number): Camera3DState;
|
|
28
|
+
/**
|
|
29
|
+
* A SETTLE — the operator's second hand, written as a function of time.
|
|
30
|
+
*
|
|
31
|
+
* A cardinal spline crosses its waypoints with continuous velocity but
|
|
32
|
+
* not continuous acceleration: at every control point the curvature
|
|
33
|
+
* steps, and the eye reads that step as a tick. The usual cure is a
|
|
34
|
+
* spring chasing the pose, which works and costs the two things a
|
|
35
|
+
* seekable engine cannot pay — it remembers the last frame, so a scrub
|
|
36
|
+
* lands somewhere a play would not, and it lags, so the camera is always
|
|
37
|
+
* behind the score by however much smoothing it was given.
|
|
38
|
+
*
|
|
39
|
+
* This is the same cure without either cost: the reported pose is a
|
|
40
|
+
* Hann-weighted average of the SAME spline sampled around the current
|
|
41
|
+
* progress. Averaging a curve is a low-pass filter, and a Hann window
|
|
42
|
+
* kills the acceleration steps outright, so the result is a hand rather
|
|
43
|
+
* than a mechanism. Being centred, it has no lag — it reads slightly
|
|
44
|
+
* ahead of the score exactly as much as it reads behind. Being an
|
|
45
|
+
* average of one pure function, it is still a pure function: play,
|
|
46
|
+
* scrub and frame-by-frame render all report the same pose.
|
|
47
|
+
*
|
|
48
|
+
* TWO EDGES IT MUST NOT CROSS. A cut is a step in the pose on purpose,
|
|
49
|
+
* and an average that straddled it would smear the cut into a very fast
|
|
50
|
+
* pan. The window is therefore TAPERED to the shot the progress is in:
|
|
51
|
+
* near either edge the kernel shrinks to the room it has, reaching zero
|
|
52
|
+
* at the edge itself. So a cut stays a cut, a path still lands exactly
|
|
53
|
+
* on its last waypoint, and the pose handed forward to the next cue is
|
|
54
|
+
* the waypoint rather than an average of one — the filter is an identity
|
|
55
|
+
* at every boundary and a smoother everywhere else.
|
|
56
|
+
*
|
|
57
|
+
* The taper is `tanh`, not a `min`, and the difference is the whole
|
|
58
|
+
* reason it works. A hard `min(width, 2 × room)` has a corner in it
|
|
59
|
+
* where the two branches meet, and a filter whose width has a corner
|
|
60
|
+
* puts one back into what it filters: measured against a path with two
|
|
61
|
+
* right-angle corners in it, the hard taper LOST ground as the window
|
|
62
|
+
* widened (worst jerk 8.7e-4 at a window of 0.175, 2.5e-3 at 0.3) while
|
|
63
|
+
* the smooth one held 8.0e-4 at every width against 4.2e-3 unfiltered.
|
|
64
|
+
* `tanh(x) ≤ x` everywhere, which is what keeps the taps inside the
|
|
65
|
+
* shot; it is smooth, which is what keeps the tick out.
|
|
66
|
+
*
|
|
67
|
+
* `width` is in progress, not seconds: the kinks being filtered are at
|
|
68
|
+
* the waypoints, which are spread uniformly across the clock, so a
|
|
69
|
+
* window measured against the clock is a window measured against the
|
|
70
|
+
* spacing of the things it exists to smooth. The caller converts.
|
|
71
|
+
*/
|
|
72
|
+
export declare function settleThrough(from: Camera3DState, through: Camera3DWaypoint[], progress: number, tension: number | undefined, width: number, taps?: number): Camera3DState;
|
|
73
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAmHlE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,CAwCf;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE,MAAM,EACb,IAAI,SAAK,GACR,aAAa,CA0Df"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A region is a participant host (glimmer-motion/participant): its root
|
|
3
|
+
* renders `data-motion-host` beside `data-choreo`, and registering a region
|
|
4
|
+
* here registers it as that element's participant host too, so the {{motion}}
|
|
5
|
+
* elements inside join it. The lookups below are Choreo's own, for code that
|
|
6
|
+
* already speaks in regions.
|
|
7
|
+
*/
|
|
8
|
+
import { type ParticipantHost } from 'glimmer-motion';
|
|
9
|
+
import type { ChoreoRun } from './run.ts';
|
|
10
|
+
import type { ChoreoNode, TimelineNode } from './types.ts';
|
|
11
|
+
declare module 'glimmer-motion/participant' {
|
|
12
|
+
interface ParticipantArgs {
|
|
13
|
+
/**
|
|
14
|
+
* How Choreo measures this element for a shape-matched flight.
|
|
15
|
+
* `'box'` (default) is the layout border box — right for plates, cards,
|
|
16
|
+
* stages. `'content'` is the shrink-wrap (the ink): a full-bleed title
|
|
17
|
+
* still matches as a word. Written as `data-choreo-pack`; an explicit
|
|
18
|
+
* `[data-choreo-substance]` descendant still wins.
|
|
19
|
+
*/
|
|
20
|
+
pack?: 'box' | 'content';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** anything that can put a node on a region's timeline — a step component, or a lane from outside */
|
|
24
|
+
export interface ChoreoProvider {
|
|
25
|
+
node(): TimelineNode;
|
|
26
|
+
}
|
|
27
|
+
export interface ChoreoHost extends ParticipantHost {
|
|
28
|
+
/** a destroyed participant asks whether the region still needs its element; true → the region unmounts it later */
|
|
29
|
+
claim(node: ChoreoNode): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* SPIKE (Lane): a provider from OUTSIDE the region's markup — a parent's
|
|
32
|
+
* lane addressed at this region — whose node joins the tree the region
|
|
33
|
+
* collects on every pass, after its own steps. Returns the remover.
|
|
34
|
+
*/
|
|
35
|
+
contribute(provider: ChoreoProvider): () => void;
|
|
36
|
+
/** the run the region is playing or holding, for an attachment to drive; null between runs */
|
|
37
|
+
currentRun(): ChoreoRun | null;
|
|
38
|
+
register(node: ChoreoNode): () => void;
|
|
39
|
+
}
|
|
40
|
+
export declare function setChoreoHost(el: Element, host: ChoreoHost | undefined): void;
|
|
41
|
+
export declare function closestChoreo(el: Element): ChoreoHost | undefined;
|
|
42
|
+
/** the host of a region element itself (not an ancestor's) */
|
|
43
|
+
export declare function choreoHostAt(el: Element): ChoreoHost | undefined;
|
|
44
|
+
/** the host of the region rendered with `@id` — a lane's way of naming the region it plays in */
|
|
45
|
+
export declare function choreoHostById(id: string): ChoreoHost | undefined;
|
|
46
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,gBAAgB,CAAC;AAE1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK3D,OAAO,QAAQ,4BAA4B,CAAC;IAC1C,UAAU,eAAe;QACvB;;;;;;WAMG;QACH,IAAI,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;KAC1B;CACF;AAED,qGAAqG;AACrG,MAAM,WAAW,cAAc;IAC7B,IAAI,IAAI,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,UAAW,SAAQ,eAAe;IACjD,mHAAmH;IACnH,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;IACjC;;;;OAIG;IACH,UAAU,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI,CAAC;IACjD,8FAA8F;IAC9F,UAAU,IAAI,SAAS,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,IAAI,CAAC;CACxC;AAMD,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,GAAG,SAAS,QAkBtE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAGjE;AAED,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAEhE;AAED,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAEjE"}
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import type { Camera3DState, CameraState, ChoreoNode, Compiled, Cue, PerformCommand, Sprite } from './types.ts';
|
|
2
|
+
/** how fast each value was moving, in units per second, keyed by element then property */
|
|
3
|
+
export type Velocities = Map<HTMLElement, Map<string, number>>;
|
|
4
|
+
export interface Run {
|
|
5
|
+
/** open the gate the run is parked at; mid-segment, complete the segment and park (§4.1) */
|
|
6
|
+
advance(): void;
|
|
7
|
+
/** stop everything; removed sprites are released unless a next run is keeping them (`keep`) */
|
|
8
|
+
cancel(keep?: Set<ChoreoNode>): void;
|
|
9
|
+
cues: Cue[];
|
|
10
|
+
/** the run's full length in seconds at 1×, gates included */
|
|
11
|
+
readonly duration: number;
|
|
12
|
+
finished: Promise<void>;
|
|
13
|
+
/** nothing left to play: the run completed or was cancelled */
|
|
14
|
+
isDone(): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The sprites this run is DRIVING through space right now — an
|
|
17
|
+
* unfinished move/spring/tween writing geometry — with each cue's
|
|
18
|
+
* transition. A replacement pass reads this to complete its score: a
|
|
19
|
+
* flying sprite the new score does not name gets a continuation move
|
|
20
|
+
* instead of a one-frame release to rest (§3.1).
|
|
21
|
+
*/
|
|
22
|
+
midflight(): Map<ChoreoNode, Record<string, unknown> | undefined>;
|
|
23
|
+
/** standing at a gate, waiting for advance() — a still, and settled */
|
|
24
|
+
readonly parked: boolean;
|
|
25
|
+
pause(): void;
|
|
26
|
+
/**
|
|
27
|
+
* The run is not advancing itself: paused, parked at a gate, or otherwise
|
|
28
|
+
* held. Its clock belongs to whoever stopped it.
|
|
29
|
+
*
|
|
30
|
+
* A held run keeps writing: inline width, height and transform stay on
|
|
31
|
+
* every sprite it owns, so the geometry the page reports is the run's
|
|
32
|
+
* rather than the stylesheet's. Anything deciding whether the world has
|
|
33
|
+
* changed by measuring it has to know not to trust what it sees.
|
|
34
|
+
*/
|
|
35
|
+
readonly paused: boolean;
|
|
36
|
+
play(): void;
|
|
37
|
+
/** a pass measured and decided to keep this run: put the picture back */
|
|
38
|
+
reassert(): void;
|
|
39
|
+
/** put every element this run has touched back to its resting layout NOW */
|
|
40
|
+
releaseForMeasure(): void;
|
|
41
|
+
/**
|
|
42
|
+
* One build backwards — Keynote's rule. Land PARKED at the previous
|
|
43
|
+
* gate with everything ahead re-closed, and HOLD: a retreat never
|
|
44
|
+
* plays, never self-opens a @delay gate, and the next advance() replays
|
|
45
|
+
* the un-built segment forward. False when nothing stands behind the
|
|
46
|
+
* clock (the caller falls through to whatever "back" means one level
|
|
47
|
+
* out — an outer run, the previous slide).
|
|
48
|
+
*/
|
|
49
|
+
retreat(): boolean;
|
|
50
|
+
/** which gate-bounded segment the clock is in */
|
|
51
|
+
readonly segment: number;
|
|
52
|
+
/** playback rate: 1 is normal, 0.5 half, as Motion's controls */
|
|
53
|
+
speed: number;
|
|
54
|
+
/**
|
|
55
|
+
* This run has no end of its own: its score is nothing but OPEN steps, so
|
|
56
|
+
* it holds them — drawing its wires, keeping its holds — until it is
|
|
57
|
+
* cancelled or replaced. A standing run is SETTLED, not in flight: there
|
|
58
|
+
* is nothing to wait for, and `finished` will not resolve until a cancel.
|
|
59
|
+
*/
|
|
60
|
+
readonly standing: boolean;
|
|
61
|
+
/** the clock, in seconds at 1× — settable; setting it across a gate parks there */
|
|
62
|
+
time: number;
|
|
63
|
+
/** what every driven value was doing at the moment of interruption */
|
|
64
|
+
velocities: Velocities;
|
|
65
|
+
}
|
|
66
|
+
interface RunOptions {
|
|
67
|
+
/** where the region's frame stands as this run begins */
|
|
68
|
+
camera?: CameraState;
|
|
69
|
+
/** where the SHOT stands as this run begins — a 3D host's own pose */
|
|
70
|
+
camera3d?: Camera3DState;
|
|
71
|
+
/** the aim point the prior run left applied — see ChoreoRun.cameraAim */
|
|
72
|
+
cameraAim?: {
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
} | null;
|
|
76
|
+
/** the element the camera transform drives (the region's scene wrapper) */
|
|
77
|
+
cameraFrame?: HTMLElement;
|
|
78
|
+
/**
|
|
79
|
+
* Nothing in this region is staying — every participant it can see is a
|
|
80
|
+
* leaver. See the note in `park`: it decides whether a gate this run stops
|
|
81
|
+
* at is a gate anybody could still open.
|
|
82
|
+
*/
|
|
83
|
+
doomed?: boolean;
|
|
84
|
+
inherit?: Velocities;
|
|
85
|
+
/** a camera step landed or the run ended: the frame's new resting state */
|
|
86
|
+
onCamera?(state: CameraState): void;
|
|
87
|
+
/**
|
|
88
|
+
* The 3D shot moved. Called every frame a `c.Camera3D` cue changes the
|
|
89
|
+
* pose — including on a scrub, because the pose is sampled from the
|
|
90
|
+
* score rather than remembered from playback. Choreo has no renderer of
|
|
91
|
+
* its own; this is where the host's does the drawing.
|
|
92
|
+
*/
|
|
93
|
+
onCamera3D?(state: Camera3DState): void;
|
|
94
|
+
/**
|
|
95
|
+
* A `c.Perform` command entered the folded set: dispatch it (§C4).
|
|
96
|
+
* Deferred past the render pass, in time order, once per fold entry.
|
|
97
|
+
*/
|
|
98
|
+
onPerform?(command: PerformCommand): void;
|
|
99
|
+
/**
|
|
100
|
+
* The folded set shrank — the clock moved to before a command the host
|
|
101
|
+
* already holds. Reset commanded state; the remaining prefix is
|
|
102
|
+
* re-dispatched, in order, immediately after.
|
|
103
|
+
*/
|
|
104
|
+
onPerformReset?(): void;
|
|
105
|
+
onSpriteDone(sprite: Sprite): void;
|
|
106
|
+
/** the region's elevated layer, where c.Raise promotes the living */
|
|
107
|
+
raisedLayer?: HTMLElement;
|
|
108
|
+
removed: Sprite[];
|
|
109
|
+
/** the svg the tethers draw into */
|
|
110
|
+
tetherLayer?: SVGSVGElement;
|
|
111
|
+
}
|
|
112
|
+
export declare class ChoreoRun implements Run {
|
|
113
|
+
cues: Cue[];
|
|
114
|
+
velocities: Velocities;
|
|
115
|
+
finished: Promise<void>;
|
|
116
|
+
private master;
|
|
117
|
+
private playing;
|
|
118
|
+
private parkedAt;
|
|
119
|
+
private rate;
|
|
120
|
+
private readonly scale;
|
|
121
|
+
readonly standing: boolean;
|
|
122
|
+
private readonly total;
|
|
123
|
+
private readonly gates;
|
|
124
|
+
private tracks;
|
|
125
|
+
private readonly rowEnd;
|
|
126
|
+
private released;
|
|
127
|
+
private pending;
|
|
128
|
+
private readonly options;
|
|
129
|
+
private borrowedValues;
|
|
130
|
+
/** rest is what releaseForMeasure jumps to: 0 for translates, 1 for scales, 'none' for clips */
|
|
131
|
+
private movedValues;
|
|
132
|
+
/** what the last releaseForMeasure retired, so a kept pass can put it back */
|
|
133
|
+
private retired;
|
|
134
|
+
private owned;
|
|
135
|
+
private cancelled;
|
|
136
|
+
private ended;
|
|
137
|
+
private resolveFinished;
|
|
138
|
+
private ticking;
|
|
139
|
+
private autoTimer;
|
|
140
|
+
constructor(compiled: Compiled, options: RunOptions);
|
|
141
|
+
get duration(): number;
|
|
142
|
+
get paused(): boolean;
|
|
143
|
+
get time(): number;
|
|
144
|
+
set time(seconds: number);
|
|
145
|
+
get speed(): number;
|
|
146
|
+
set speed(rate: number);
|
|
147
|
+
get segment(): number;
|
|
148
|
+
get parked(): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* ATTACH: write each attached region's clock from this one's.
|
|
151
|
+
*
|
|
152
|
+
* Several windows may name one region — a film's every beat has a plate
|
|
153
|
+
* window, and the plate is one region re-keyed per beat — so the run
|
|
154
|
+
* resolves ONE governing window per region on every evaluate: the window
|
|
155
|
+
* that holds `now`; else the latest past one, if it holds; else the
|
|
156
|
+
* earliest future one, which stands the child at its head (Remotion's
|
|
157
|
+
* premount: mounted early, clock frozen at `in`). The child's run is
|
|
158
|
+
* paused and told `in + (now − start) × rate`. No history is kept on
|
|
159
|
+
* either side, which is what makes a seek into a window land where
|
|
160
|
+
* playing there would.
|
|
161
|
+
*/
|
|
162
|
+
private driveAttachments;
|
|
163
|
+
/** does this run's score integrate — a spring, a follow — so that its state is its history? */
|
|
164
|
+
hasIntegrator(): boolean;
|
|
165
|
+
isDone(): boolean;
|
|
166
|
+
midflight(): Map<ChoreoNode, Record<string, unknown> | undefined>;
|
|
167
|
+
pause(): void;
|
|
168
|
+
play(): void;
|
|
169
|
+
advance(): void;
|
|
170
|
+
retreat(): boolean;
|
|
171
|
+
private startTicking;
|
|
172
|
+
private stopTicking;
|
|
173
|
+
private tick;
|
|
174
|
+
private park;
|
|
175
|
+
private finish;
|
|
176
|
+
private setPaused;
|
|
177
|
+
private seekTo;
|
|
178
|
+
/**
|
|
179
|
+
* The one cost WAAPI acceleration charges a scrubbable run: a finished
|
|
180
|
+
* accelerated animation commits its finals asynchronously, and that
|
|
181
|
+
* commit can land AFTER a still's jump and overwrite it. So a still is
|
|
182
|
+
* re-asserted on the two frames after it is entered — by then any
|
|
183
|
+
* pending commit has landed, and the computed frame wins again.
|
|
184
|
+
*/
|
|
185
|
+
private restillPending;
|
|
186
|
+
private scheduleRestill;
|
|
187
|
+
private restill;
|
|
188
|
+
private evaluate;
|
|
189
|
+
/** perform tracks whose commands the host currently holds (see foldPerforms) */
|
|
190
|
+
private performed;
|
|
191
|
+
/** dispatches queued for after the render pass, in fold order */
|
|
192
|
+
private pendingPerforms;
|
|
193
|
+
private performFlushBooked;
|
|
194
|
+
/**
|
|
195
|
+
* The command fold (§C4): the set of Perform cues at or before the
|
|
196
|
+
* clock IS the commanded state. Every evaluate — a play tick and a seek
|
|
197
|
+
* alike — re-derives the eligible set; growth dispatches the new
|
|
198
|
+
* commands in time order, and any shrink (a backward seek) resets the
|
|
199
|
+
* host first and replays the whole remaining prefix. Commands are
|
|
200
|
+
* idempotent statements of state by contract (`lamp.on`, never a
|
|
201
|
+
* toggle), which is exactly what makes the replay a re-derivation.
|
|
202
|
+
*
|
|
203
|
+
* Dispatches are DEFERRED past the render pass: the constructor's first
|
|
204
|
+
* evaluate runs while Glimmer may still be rendering, and a command
|
|
205
|
+
* exists to mutate application state. A reset collapses the queue — the
|
|
206
|
+
* dropped dispatches were never seen, and the replay that follows
|
|
207
|
+
* restates everything still standing.
|
|
208
|
+
*/
|
|
209
|
+
private foldPerforms;
|
|
210
|
+
/**
|
|
211
|
+
* Stand rewound tracks back on their origins — the part of a backward
|
|
212
|
+
* seek that must be ORDERED. A sprite with sequential cues has one
|
|
213
|
+
* origin per cue, each equal to the previous cue's landing; restored
|
|
214
|
+
* in track order they clobber forward and the sprite ends up standing
|
|
215
|
+
* on its LAST future cue's origin (the Playhead demo's hand parked on
|
|
216
|
+
* 'place' after a scrub to zero; its receipt refusing to dismiss). So:
|
|
217
|
+
* latest-first, which leaves the EARLIEST future cue's origin — the
|
|
218
|
+
* value the timeline actually holds at `now` — standing; and a key
|
|
219
|
+
* that any track AT or BEFORE `now` writes is not touched at all,
|
|
220
|
+
* because that track's own sample or landing is the answer.
|
|
221
|
+
*/
|
|
222
|
+
private rewind;
|
|
223
|
+
/** the eased progress of a plain clock-driven track */
|
|
224
|
+
private flightlessProgress;
|
|
225
|
+
/**
|
|
226
|
+
* The orbit pose in force. Public for the same reason `camera` is: it is
|
|
227
|
+
* hand-off state, and a replacement run must continue from where this
|
|
228
|
+
* one left the shot rather than snapping back to the framing.
|
|
229
|
+
*/
|
|
230
|
+
camera3d: Camera3DState;
|
|
231
|
+
private readonly initial3d;
|
|
232
|
+
camera: CameraState;
|
|
233
|
+
/**
|
|
234
|
+
* The aim point P in force, local px. With transform-origin pinned at
|
|
235
|
+
* 0 0, the applied transform is translate(x + (1−z)·P) scale(z) — the
|
|
236
|
+
* frame's centre cancels out of the algebra entirely, so neither a
|
|
237
|
+
* board that reflows mid-cue nor a stage that changes height between
|
|
238
|
+
* cues can move the picture: the formula reads no live DOM at all.
|
|
239
|
+
* z = 1 is the identity for any P. Public because it is hand-off state:
|
|
240
|
+
* the next run lerps from the point THIS run left aimed, exactly as it
|
|
241
|
+
* inherits the camera.
|
|
242
|
+
*/
|
|
243
|
+
cameraAim: {
|
|
244
|
+
x: number;
|
|
245
|
+
y: number;
|
|
246
|
+
} | null;
|
|
247
|
+
/**
|
|
248
|
+
* The absolute pose a camera cue lands on, resolved against the pose it
|
|
249
|
+
* starts from. Absolute fields pass through; missing fields hold; a
|
|
250
|
+
* relative cue (Pan / SlowZoom) offsets and multiplies the pose in
|
|
251
|
+
* force — which is why resolution happens AT START (live) or during the
|
|
252
|
+
* prefix fold (reconstruction), never at compile.
|
|
253
|
+
*/
|
|
254
|
+
private static resolveCameraTo;
|
|
255
|
+
private cameraProgress;
|
|
256
|
+
/**
|
|
257
|
+
* The camera and aim this run inherited, frozen at construction — the
|
|
258
|
+
* fold origin every reconstruction starts from. Public because a
|
|
259
|
+
* replacement run that re-executes the SAME score must inherit this
|
|
260
|
+
* origin, not the pose in force: the pose in force is what the score's
|
|
261
|
+
* prefix already produced, and folding the prefix from it applies every
|
|
262
|
+
* relative cue twice (the world-dock law).
|
|
263
|
+
*/
|
|
264
|
+
readonly initialCamera: CameraState;
|
|
265
|
+
readonly initialAim: {
|
|
266
|
+
x: number;
|
|
267
|
+
y: number;
|
|
268
|
+
} | null;
|
|
269
|
+
/**
|
|
270
|
+
* Rebuild the camera fold from the score prefix before a seek's still
|
|
271
|
+
* (notes/external-clock-camera-seek-handoff.md). Forward playback folds
|
|
272
|
+
* each camera cue's landing into the run's cumulative camera as the
|
|
273
|
+
* clock crosses it — but a random-access seek can jump clean over a
|
|
274
|
+
* window, and a cue that never starts never folds: the clock reads `t`
|
|
275
|
+
* while the picture holds an earlier shot. So every camera track's
|
|
276
|
+
* bookkeeping (started, cameraFrom, aimFrom/aimTo, cameraP) is
|
|
277
|
+
* re-derived here in timeline order from the run's initial camera;
|
|
278
|
+
* evaluate() then recomputes exactly the numbers forward playback would
|
|
279
|
+
* have produced, and play-after-scrub resumes from them. Pure
|
|
280
|
+
* arithmetic over frozen numbers, like the rest of the camera: no DOM
|
|
281
|
+
* is read, so backward and repeated seeks agree to the pixel.
|
|
282
|
+
*/
|
|
283
|
+
private reconstructCameraAt;
|
|
284
|
+
/**
|
|
285
|
+
* The damped counter-scale (§6.4): steady sprites scale with the host but
|
|
286
|
+
* not 1:1 — pow(z, .30) zoomed out so they stay readable, pow(z, .70)
|
|
287
|
+
* zoomed in so they don't feel stuck, clamped to what the eye tolerates.
|
|
288
|
+
*/
|
|
289
|
+
private static damped;
|
|
290
|
+
/**
|
|
291
|
+
* The frame's APPLIED transform for a camera state at aim progress `p`.
|
|
292
|
+
*
|
|
293
|
+
* Transform-origin is pinned at 0 0, so the applied transform is
|
|
294
|
+
* translate(x + (1−z)·P) scale(z) with P the lerped aim point — pure
|
|
295
|
+
* arithmetic over frozen numbers. Nothing here reads the DOM, so a board
|
|
296
|
+
* that reflows mid-cue cannot move the camera, and every boundary
|
|
297
|
+
* (landing, re-aim, next run) agrees to the pixel. At z = 1 the aim term
|
|
298
|
+
* vanishes: an unpanned camera is EXACTLY the identity.
|
|
299
|
+
*/
|
|
300
|
+
private appliedCamera;
|
|
301
|
+
private static cameraCss;
|
|
302
|
+
/**
|
|
303
|
+
* Fly the region's frame on the platform: two transform keyframes and the
|
|
304
|
+
* eased clock pre-sampled into a linear() easing. The biggest layer in the
|
|
305
|
+
* region composites off the main thread for the whole move.
|
|
306
|
+
*/
|
|
307
|
+
private startCameraAnimation;
|
|
308
|
+
/**
|
|
309
|
+
* Retire the frame's platform animation and hand the picture back to
|
|
310
|
+
* inline style, written from the shadow state — so a cancel mid-zoom
|
|
311
|
+
* freezes exactly where the eye was, and a landing holds its final.
|
|
312
|
+
*/
|
|
313
|
+
private dropCameraAnimation;
|
|
314
|
+
private applyCamera;
|
|
315
|
+
private tetherDrawScheduled;
|
|
316
|
+
private scheduleTetherDraw;
|
|
317
|
+
/**
|
|
318
|
+
* One frame of a derived value (§4.10): compose the context from the
|
|
319
|
+
* pass's measurements, hand it to the author's function, write what
|
|
320
|
+
* comes back.
|
|
321
|
+
*
|
|
322
|
+
* Nothing here touches the DOM — that is the design, not an
|
|
323
|
+
* optimisation (docs/postmortem-follow.md). The resting boxes were
|
|
324
|
+
* measured by the pass with every moved value released, and a source's
|
|
325
|
+
* `now` is its resting box composed with the motion values driving it
|
|
326
|
+
* this frame: JS-side numbers, not a measurement. So a follower is pure
|
|
327
|
+
* BY CONSTRUCTION — there is no live box in reach, it cannot read back
|
|
328
|
+
* its own output, and it cannot force a style recalculation in the
|
|
329
|
+
* middle of a move. It is also correct under INTERRUPTION for free: a
|
|
330
|
+
* replacement run's pass re-measures, so a run born mid-flight computes
|
|
331
|
+
* from rests that are right immediately, with no "last frame" to
|
|
332
|
+
* disagree with.
|
|
333
|
+
*
|
|
334
|
+
* `set`, not an animation: a derived value IS the frame, so there is
|
|
335
|
+
* nothing to interpolate toward and nothing the compositor could be
|
|
336
|
+
* given — this is the main-thread cost the step charges, and the reason
|
|
337
|
+
* it is the same cost `c.Tether` already pays.
|
|
338
|
+
*/
|
|
339
|
+
private drive;
|
|
340
|
+
/** the window closed (or was scrubbed out of): put the declared rest back */
|
|
341
|
+
private restDerived;
|
|
342
|
+
private drawTether;
|
|
343
|
+
/**
|
|
344
|
+
* The scale between the layer's own pixels and the screen's, per axis.
|
|
345
|
+
*
|
|
346
|
+
* A promotion reads client rects and writes LOCAL pixels, and every
|
|
347
|
+
* transform above the region — a camera zoom, a page crossing carrying the
|
|
348
|
+
* whole scene, any ancestor with a scale on it — sits between the two. Read
|
|
349
|
+
* off the layer itself: its rect is what the screen shows, its offset size
|
|
350
|
+
* is what its own coordinate system calls that. Dividing by the camera zoom
|
|
351
|
+
* alone would catch the region's own transform and miss everything outside
|
|
352
|
+
* it, which is the double-scale the tether draw already dodges by mapping
|
|
353
|
+
* through the screen CTM.
|
|
354
|
+
*/
|
|
355
|
+
private static layerScale;
|
|
356
|
+
private promote;
|
|
357
|
+
private restore;
|
|
358
|
+
private startScroll;
|
|
359
|
+
private stopScroll;
|
|
360
|
+
/** stop a track's animations at the value level — an async animation
|
|
361
|
+
* cancelled before it resolves stays 'idle' forever if only the controls
|
|
362
|
+
* are stopped, and its value then reads as animating for good */
|
|
363
|
+
private stopTrack;
|
|
364
|
+
/** land a cue's end values without ever having played it */
|
|
365
|
+
private jumpFinals;
|
|
366
|
+
private startTrack;
|
|
367
|
+
/** put the sprite at progress `p` of its sampled flight path (§4.4) */
|
|
368
|
+
private applyFlight;
|
|
369
|
+
/** the eased progress a flight sits at, `ms` into its window */
|
|
370
|
+
private flightProgress;
|
|
371
|
+
/**
|
|
372
|
+
* The sampled path as platform keyframes: each point becomes a transform,
|
|
373
|
+
* uniformly spaced (the points were sampled uniformly in progress), and
|
|
374
|
+
* the eased clock rides the animation's easing instead of per-frame JS.
|
|
375
|
+
*/
|
|
376
|
+
private flightKeyframes;
|
|
377
|
+
private startFlight;
|
|
378
|
+
/** compute one still frame of a cue and jump the values onto the element */
|
|
379
|
+
private sampleStill;
|
|
380
|
+
private completeTrack;
|
|
381
|
+
private pinStarts;
|
|
382
|
+
private sampleVelocities;
|
|
383
|
+
releaseForMeasure(): void;
|
|
384
|
+
/**
|
|
385
|
+
* A pass measured this run's world at rest and then decided to KEEP the
|
|
386
|
+
* run — but the measurement itself was destructive: releaseForMeasure
|
|
387
|
+
* cancels platform animations, returns borrowed values, and jumps every
|
|
388
|
+
* moved value to rest, and a MotionValue.jump() STOPS the animation
|
|
389
|
+
* driving it. Left like that, a kept run keeps its clock and its landing
|
|
390
|
+
* but loses its picture: the flight freezes at rest until the finals
|
|
391
|
+
* land — which on a busy page (the gallery: neighbours re-pass the
|
|
392
|
+
* region every render) is every crossing, every time. So the keep path
|
|
393
|
+
* calls this: moved and borrowed values are stood back where they were,
|
|
394
|
+
* their bookkeeping is re-registered, every in-flight track's animation
|
|
395
|
+
* is retired so evaluate re-enters it — the machinery a scrub-then-play
|
|
396
|
+
* already uses — and the re-entered animations are seeked back onto the
|
|
397
|
+
* run's own clock, so a keep is invisible rather than a restart.
|
|
398
|
+
*/
|
|
399
|
+
reassert(): void;
|
|
400
|
+
cancel(keep?: Set<ChoreoNode>): void;
|
|
401
|
+
}
|
|
402
|
+
/** every live run, for the test helpers that drive gates and clocks */
|
|
403
|
+
export declare const activeRuns: Set<ChoreoRun>;
|
|
404
|
+
export declare function execute(compiled: Compiled, options: RunOptions): ChoreoRun;
|
|
405
|
+
export {};
|
|
406
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The coordinate contract (docs/planes-and-cameras.md).
|
|
3
|
+
*
|
|
4
|
+
* A plane's camera is pure arithmetic over frozen numbers: with
|
|
5
|
+
* transform-origin pinned at 0 0, the applied transform is
|
|
6
|
+
* `translate(x + (1−z)·P) scale(z)` for aim point P (§6.3). Because it
|
|
7
|
+
* is arithmetic, it is invertible WITHOUT reading the DOM — and these
|
|
8
|
+
* two inverses are the whole compositor ⇄ plane-local ⇄ viewport
|
|
9
|
+
* conversion: cross-plane flights, cross-plane hit testing, and
|
|
10
|
+
* eventually cross-plane drag all reduce to them.
|
|
11
|
+
*
|
|
12
|
+
* A plane that scrolls adds its scroll offset to the same arithmetic —
|
|
13
|
+
* the one place a DOM read (the scroll position) legitimately enters,
|
|
14
|
+
* read once per conversion, never per frame.
|
|
15
|
+
*/
|
|
16
|
+
import type { CameraState, Rect } from './types.ts';
|
|
17
|
+
export interface PlanePoint {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The translate the camera actually applies at aim point `aim` — the
|
|
23
|
+
* same algebra `applyCamera` paints with. At z = 1 the aim term
|
|
24
|
+
* vanishes: an unpanned camera is exactly the identity.
|
|
25
|
+
*/
|
|
26
|
+
export declare function appliedCamera(cam: CameraState, aim?: PlanePoint): PlanePoint;
|
|
27
|
+
/** plane-local box → page space, through the plane's camera and scroll */
|
|
28
|
+
export declare function toPage(local: Rect, cam: CameraState, aim?: PlanePoint, scroll?: PlanePoint): Rect;
|
|
29
|
+
/** page-space box → the plane's local space: `(page − applied)/z + scroll` */
|
|
30
|
+
export declare function toLocal(page: Rect, cam: CameraState, aim?: PlanePoint, scroll?: PlanePoint): Rect;
|
|
31
|
+
//# sourceMappingURL=space.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space.d.ts","sourceRoot":"","sources":["../src/space.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,WAAW,EAChB,GAAG,GAAE,UAAmB,GACvB,UAAU,CAKZ;AAED,0EAA0E;AAC1E,wBAAgB,MAAM,CACpB,KAAK,EAAE,IAAI,EACX,GAAG,EAAE,WAAW,EAChB,GAAG,GAAE,UAAmB,EACxB,MAAM,GAAE,UAAmB,GAC1B,IAAI,CAQN;AAED,8EAA8E;AAC9E,wBAAgB,OAAO,CACrB,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,WAAW,EAChB,GAAG,GAAE,UAAmB,EACxB,MAAM,GAAE,UAAmB,GAC1B,IAAI,CAQN"}
|