@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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@cardstack/choreo` are recorded here.
|
|
4
|
+
|
|
5
|
+
This file follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
`glimmer-motion` and `@cardstack/choreo` release in lockstep: every version
|
|
9
|
+
of one is a version of the other, and `@cardstack/choreo` peer-depends on the
|
|
10
|
+
exact `glimmer-motion` version it was released with.
|
|
11
|
+
|
|
12
|
+
Pre-1.0 caveat: the public API is intentionally unstable. Minor and patch
|
|
13
|
+
versions may change behavior until `1.0.0`.
|
|
14
|
+
|
|
15
|
+
## [Unreleased]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Cardstack Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,9 +1,58 @@
|
|
|
1
1
|
# @cardstack/choreo
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[
|
|
6
|
-
|
|
3
|
+
**Motion, choreographed.** `<Choreo>` watches a region's render passes, hands each one's changeset
|
|
4
|
+
(inserted, removed and kept participants, with their bounds before and after) to a timeline declared
|
|
5
|
+
inside it, and plays that timeline on the [Motion](https://motion.dev) engine. It is built on
|
|
6
|
+
[`glimmer-motion`](../glimmer-motion), whose `{{motion}}` elements are the participants.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
```gts
|
|
9
|
+
import { Choreo } from '@cardstack/choreo';
|
|
10
|
+
import { motion } from 'glimmer-motion';
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<Choreo as |c|>
|
|
14
|
+
{{#each @messages key='id' as |message|}}
|
|
15
|
+
<article {{motion id=message.id role='message'}}>
|
|
16
|
+
{{message.subject}}
|
|
17
|
+
</article>
|
|
18
|
+
{{/each}}
|
|
19
|
+
<c.Sequence>
|
|
20
|
+
<c.Tween @of={{c.removed 'message'}} @opacity={{0}} @ms={{200}} />
|
|
21
|
+
<c.Move @of={{c.kept 'message'}} />
|
|
22
|
+
</c.Sequence>
|
|
23
|
+
</Choreo>
|
|
24
|
+
</template>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
pnpm add @cardstack/choreo glimmer-motion motion-dom motion-utils
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Peers: `glimmer-motion` at exactly the same version (the two packages release together), `motion-dom` /
|
|
34
|
+
`motion-utils` in the same ranges glimmer-motion declares, so both packages share one engine,
|
|
35
|
+
`ember-modifier`, `@glimmer/component`, `@glimmer/tracking`, `ember-source >= 5.4`. A v2 addon with
|
|
36
|
+
TypeScript types and Glint signatures.
|
|
37
|
+
|
|
38
|
+
## Entry points
|
|
39
|
+
|
|
40
|
+
| import | what |
|
|
41
|
+
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
42
|
+
| `@cardstack/choreo` | `Choreo` and its yielded vocabulary, `beacon`, anchors (`at`, `after`), `createArming`, easings, the region registry, plane-space helpers, `StepComponent` and the timeline types |
|
|
43
|
+
| `@cardstack/choreo/film` | the film construct: `Film`, its clips, joins, overlays, player and graph |
|
|
44
|
+
| `@cardstack/choreo/test-support` | `setupChoreo(hooks)`, `advanceGate()`, `seekTo()`, `live()`, `orphanCount()`, `strandedTransforms()` |
|
|
45
|
+
|
|
46
|
+
Deep imports (`@cardstack/choreo/compile`, `@cardstack/choreo/film/math`, …) are the same modules.
|
|
47
|
+
|
|
48
|
+
## How it plugs into glimmer-motion
|
|
49
|
+
|
|
50
|
+
A region is a glimmer-motion participant host: `{{motion}}` elements with an `id` or `role` join the
|
|
51
|
+
nearest region when they mount, and a region can claim a leaving element to keep it on screen for as long
|
|
52
|
+
as the timeline names it. The region's in-flight runs count toward glimmer-motion's settle checks through a
|
|
53
|
+
busy probe, and `setupChoreo(hooks)` is glimmer-motion's `setupMotion(hooks)` with Choreo's document-wide
|
|
54
|
+
state (beacons, the far-match barrier, gesture samples) added to the resets it runs.
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT.
|
package/addon-main.cjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anchors — "with / after build N", as typed helpers rather than a string
|
|
3
|
+
* micro-DSL (docs/choreo-constructs.md §4.2). A step names itself with
|
|
4
|
+
* `@name`; any later step may start against it with `@at`:
|
|
5
|
+
*
|
|
6
|
+
* <c.Tween @name='head' … />
|
|
7
|
+
* <c.Tween @at={{at 'head' 0.4}} … /> start at 40% of head
|
|
8
|
+
* <c.Tween @at={{after 'head' 0.2}} … /> start 0.2s after head ends
|
|
9
|
+
*
|
|
10
|
+
* `at name 1` and `after name` are the same moment. Anchors point up the
|
|
11
|
+
* score, the way Keynote's build list does; a forward reference is a
|
|
12
|
+
* compile error, as is a duplicate name.
|
|
13
|
+
*/
|
|
14
|
+
export interface AnchorRef {
|
|
15
|
+
anchor: string;
|
|
16
|
+
/** seconds past the named step's end (`after`) */
|
|
17
|
+
delay?: number;
|
|
18
|
+
edge: 'end' | 'start';
|
|
19
|
+
/** 0..1 of the named step's own length (`at`) */
|
|
20
|
+
progress?: number;
|
|
21
|
+
}
|
|
22
|
+
/** start at the named step's start, plus `progress` (0–1) of its length */
|
|
23
|
+
export declare function at(name: string, progress?: number): AnchorRef;
|
|
24
|
+
/** start at the named step's end, plus `delay` seconds */
|
|
25
|
+
export declare function after(name: string, delay?: number): AnchorRef;
|
|
26
|
+
//# sourceMappingURL=anchors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchors.d.ts","sourceRoot":"","sources":["../src/anchors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IACtB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,2EAA2E;AAC3E,wBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,SAAS,CAExD;AAED,0DAA0D;AAC1D,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,SAAS,CAExD"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Run } from './run.ts';
|
|
2
|
+
/** the sliver of a region a watch needs: the run it is playing right now */
|
|
3
|
+
export interface ArmingRegion {
|
|
4
|
+
readonly run: Run | null | undefined;
|
|
5
|
+
}
|
|
6
|
+
export interface Arming {
|
|
7
|
+
/** tracked: a crossing this arming is watching is under way */
|
|
8
|
+
active(): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Arm now, and watch `region` until the run that survives has settled (or
|
|
11
|
+
* the deadline passes). Called again while armed, it re-arms: the earlier
|
|
12
|
+
* watch is abandoned rather than allowed to stand the new one down.
|
|
13
|
+
*/
|
|
14
|
+
begin(region: ArmingRegion): void;
|
|
15
|
+
/** stand down by hand — a test reset, or a host that knows the pass is off */
|
|
16
|
+
end(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Resolves when this arming stands down, immediately when nothing is armed.
|
|
19
|
+
* What a host waits on before paying for an expensive mount.
|
|
20
|
+
*/
|
|
21
|
+
settled(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export interface ArmingOptions {
|
|
24
|
+
/**
|
|
25
|
+
* How long to wait for a run to appear before standing down anyway, in ms
|
|
26
|
+
* (default 4000). The backstop for a crossing that never produced a pass.
|
|
27
|
+
*/
|
|
28
|
+
deadline?: number;
|
|
29
|
+
/** run whenever the arming stands down — where a host clears its own flags */
|
|
30
|
+
onStandDown?: () => void;
|
|
31
|
+
}
|
|
32
|
+
export declare function createArming(options?: ArmingOptions): Arming;
|
|
33
|
+
//# sourceMappingURL=arming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arming.d.ts","sourceRoot":"","sources":["../src/arming.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,MAAM;IACrB,+DAA+D;IAC/D,MAAM,IAAI,OAAO,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,8EAA8E;IAC9E,GAAG,IAAI,IAAI,CAAC;IACZ;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAeD,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAsEhE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const beacon: import("ember-modifier").FunctionBasedModifier<{
|
|
2
|
+
Args: {
|
|
3
|
+
Positional: [string];
|
|
4
|
+
Named: import("ember-modifier/-private/signature").EmptyObject;
|
|
5
|
+
};
|
|
6
|
+
Element: Element;
|
|
7
|
+
}>;
|
|
8
|
+
export default beacon;
|
|
9
|
+
//# sourceMappingURL=beacon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beacon.d.ts","sourceRoot":"","sources":["../src/beacon.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,MAAM;;;;;;EAMjB,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Bounds } from './types.ts';
|
|
2
|
+
export declare function registerBeacon(name: string, element: Element): () => void;
|
|
3
|
+
/**
|
|
4
|
+
* Measure every live beacon, in the same window the region measures `final`.
|
|
5
|
+
*
|
|
6
|
+
* Re-measured every pass, never cached: the trash can move without the list
|
|
7
|
+
* rendering at all — a header that hides, a column that resizes, a scroll.
|
|
8
|
+
*/
|
|
9
|
+
export declare function measureBeacons(root: DOMRect): Map<string, Bounds>;
|
|
10
|
+
/**
|
|
11
|
+
* Forget every claimed name. The registry outlives any one owner, so a test
|
|
12
|
+
* that tore down mid-flight would otherwise leave a dead element holding a
|
|
13
|
+
* name the next test wants — first-wins turns into first-test-wins.
|
|
14
|
+
* `setupChoreo(hooks)` runs this before and after every test; nothing in an
|
|
15
|
+
* app should.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resetBeacons(): void;
|
|
18
|
+
/** `{{c.beacon 'trash'}}` — a named point, not a sprite query */
|
|
19
|
+
export interface BeaconRef {
|
|
20
|
+
beacon: string;
|
|
21
|
+
}
|
|
22
|
+
export declare const isBeaconRef: (v: unknown) => v is BeaconRef;
|
|
23
|
+
//# sourceMappingURL=beacons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beacons.d.ts","sourceRoot":"","sources":["../src/beacons.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAKzC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,IAAI,CASzE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CASjE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,SAE3B;AAED,iEAAiE;AACjE,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,SAGD,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* boxel-motion's Changeset: the sprites one render pass produced, and the
|
|
3
|
+
* spritesFor / spriteFor queries its transitions selected them with.
|
|
4
|
+
*/
|
|
5
|
+
import type { Bounds, ChangesetLike, Query, Sprite } from './types.ts';
|
|
6
|
+
export declare class Changeset implements ChangesetLike {
|
|
7
|
+
readonly inserted: Sprite[];
|
|
8
|
+
readonly kept: Sprite[];
|
|
9
|
+
readonly removed: Sprite[];
|
|
10
|
+
/**
|
|
11
|
+
* The box a `{{beacon}}` claimed this pass, or null if nothing claimed that
|
|
12
|
+
* name. It is a measurement, not a sprite: a beacon is never inserted, kept
|
|
13
|
+
* or removed, and a missing one is a no-op for whatever wanted to borrow it.
|
|
14
|
+
*
|
|
15
|
+
* Closed over rather than stored as a field, so this class stays structurally
|
|
16
|
+
* identical to ChangesetLike — a property function written against the
|
|
17
|
+
* concrete Changeset must still accept the interface it is handed.
|
|
18
|
+
*/
|
|
19
|
+
readonly beacon: (name: string) => Bounds | null;
|
|
20
|
+
/**
|
|
21
|
+
* The camera zoom the world was measured under (§6.3). Every box in this
|
|
22
|
+
* changeset is a page-space measurement taken through the region's frame
|
|
23
|
+
* transform, but a step's values are written in the sprite's own local
|
|
24
|
+
* space — so geometry that becomes inline pixels must be divided back by
|
|
25
|
+
* this before it is animated. 1 when the frame is at rest.
|
|
26
|
+
*/
|
|
27
|
+
readonly measureZoom: number;
|
|
28
|
+
/** the frame's own size in local pixels, from the same final layout */
|
|
29
|
+
readonly frame?: {
|
|
30
|
+
height: number;
|
|
31
|
+
width: number;
|
|
32
|
+
};
|
|
33
|
+
/** what the page shows behind this region — see ChangesetLike.ground */
|
|
34
|
+
readonly ground?: string;
|
|
35
|
+
constructor(inserted: Sprite[], removed: Sprite[], kept: Sprite[], beacons?: Map<string, Bounds>, measureZoom?: number, frame?: {
|
|
36
|
+
height: number;
|
|
37
|
+
width: number;
|
|
38
|
+
}, ground?: string);
|
|
39
|
+
get all(): Sprite[];
|
|
40
|
+
/** something happened this pass that a choreography could animate */
|
|
41
|
+
get dirty(): boolean;
|
|
42
|
+
sprites(query: Query | Query[]): Sprite[];
|
|
43
|
+
sprite(query: Query | Query[]): Sprite | null;
|
|
44
|
+
}
|
|
45
|
+
export default Changeset;
|
|
46
|
+
//# sourceMappingURL=changeset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changeset.d.ts","sourceRoot":"","sources":["../src/changeset.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA+BvE,qBAAa,SAAU,YAAW,aAAa;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAE3B;;;;;;;;OAQG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAEjD;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAEnD,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAGvB,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAa,EACxC,WAAW,SAAI,EACf,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EACzC,MAAM,CAAC,EAAE,MAAM;IAWjB,IAAI,GAAG,IAAI,MAAM,EAAE,CAElB;IAED,qEAAqE;IACrE,IAAI,KAAK,IAAI,OAAO,CAMnB;IAED,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,MAAM,EAAE;IAuDzC,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,MAAM,GAAG,IAAI;CAS9C;AAED,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import type Owner from '@ember/owner';
|
|
2
|
+
import Component from '@glimmer/component';
|
|
3
|
+
import { type BeaconRef } from './beacons.ts';
|
|
4
|
+
import Changeset from './changeset.ts';
|
|
5
|
+
import { type Pass } from './far.ts';
|
|
6
|
+
import { type GestureRef } from './gesture.ts';
|
|
7
|
+
import { type ChoreoHost, type ChoreoProvider } from './registry.ts';
|
|
8
|
+
import { type ChoreoRun } from './run.ts';
|
|
9
|
+
import { Aim, Attach, Camera, Camera3D, Crossing, Follow, Frame, Gate, Hold, Move, Pan, Parallel, Perform, Raise, Scroll, Sequence, SlowZoom, Spring, Tether, Tween, Wait } from './steps';
|
|
10
|
+
import type { Camera3DState, CameraState, ChoreoNode, PerformCommand, Query } from './types.ts';
|
|
11
|
+
/** `{{c.kept 'card'}}` narrows by role; bare `{{c.kept}}` is handed over uncalled, so the function is a Query too */
|
|
12
|
+
type Selector = ((role?: string) => Query) & Query;
|
|
13
|
+
/** what the region yields: the step components and the sprite queries */
|
|
14
|
+
export interface ChoreoContext {
|
|
15
|
+
Aim: typeof Aim;
|
|
16
|
+
Attach: typeof Attach;
|
|
17
|
+
Camera: typeof Camera;
|
|
18
|
+
Camera3D: typeof Camera3D;
|
|
19
|
+
Crossing: typeof Crossing;
|
|
20
|
+
Follow: typeof Follow;
|
|
21
|
+
Frame: typeof Frame;
|
|
22
|
+
Gate: typeof Gate;
|
|
23
|
+
Hold: typeof Hold;
|
|
24
|
+
Move: typeof Move;
|
|
25
|
+
Pan: typeof Pan;
|
|
26
|
+
Parallel: typeof Parallel;
|
|
27
|
+
Perform: typeof Perform;
|
|
28
|
+
Raise: typeof Raise;
|
|
29
|
+
Scroll: typeof Scroll;
|
|
30
|
+
Sequence: typeof Sequence;
|
|
31
|
+
SlowZoom: typeof SlowZoom;
|
|
32
|
+
Spring: typeof Spring;
|
|
33
|
+
Tether: typeof Tether;
|
|
34
|
+
Tween: typeof Tween;
|
|
35
|
+
Wait: typeof Wait;
|
|
36
|
+
/** open the gate the run is parked at; template-stable, because gates are wired in templates */
|
|
37
|
+
advance: () => void;
|
|
38
|
+
all: Selector;
|
|
39
|
+
/** `{{c.beacon 'trash'}}` — a named box to borrow, for Move's @from / @to */
|
|
40
|
+
beacon: (name: string) => BeaconRef;
|
|
41
|
+
/**
|
|
42
|
+
* Where the region's frame stands — tracked, updated when a camera step
|
|
43
|
+
* lands or cancels, deliberately not per frame (§9): app logic may derive
|
|
44
|
+
* from it (the zoom-threshold transmute) without a feedback loop.
|
|
45
|
+
*/
|
|
46
|
+
readonly camera: CameraState;
|
|
47
|
+
/** the removed half an arriving element claimed — orphaned, ready to cross-fade */
|
|
48
|
+
counterpart: Selector;
|
|
49
|
+
/** the live drag as geometry: its pose as a box, its velocity into springs */
|
|
50
|
+
gesture: GestureRef;
|
|
51
|
+
id: (id: string) => Query;
|
|
52
|
+
inserted: Selector;
|
|
53
|
+
kept: Selector;
|
|
54
|
+
moved: Selector;
|
|
55
|
+
/** narrow any query to sprites a viewport can actually see (§4.7) */
|
|
56
|
+
onstage: (query: Query) => Query;
|
|
57
|
+
/** kept only because it claimed a leaver's identity: the receiving half of a counterpart or far match */
|
|
58
|
+
received: Selector;
|
|
59
|
+
removed: Selector;
|
|
60
|
+
role: (role: string) => Query;
|
|
61
|
+
/** the current pass's run, as a value you can hold — null between passes (§4.6) */
|
|
62
|
+
readonly run: ChoreoRun | null;
|
|
63
|
+
still: Selector;
|
|
64
|
+
}
|
|
65
|
+
interface Signature {
|
|
66
|
+
Args: {
|
|
67
|
+
/**
|
|
68
|
+
* WHERE THE SHOT STANDS BEFORE THE FIRST RUN. A `@through` spline
|
|
69
|
+
* prepends the pose in force, and with no prior run that pose is the
|
|
70
|
+
* default rig — dolly 1, yaw 0 — somewhere no film ever authored. A
|
|
71
|
+
* host that hard-opens on a known pose (it seated its own scene there
|
|
72
|
+
* before the score existed) declares it here, and the first segment
|
|
73
|
+
* starts from the shot instead of travelling to it. Read once, before
|
|
74
|
+
* the first run; after that the pose in force is the run's own.
|
|
75
|
+
*/
|
|
76
|
+
camera3dFrom?: Camera3DState;
|
|
77
|
+
/** outline the region and its participants; console.table each run */
|
|
78
|
+
debug?: boolean;
|
|
79
|
+
id?: string;
|
|
80
|
+
/**
|
|
81
|
+
* A `c.Camera3D` cue moved the shot. Called every frame it changes —
|
|
82
|
+
* scrubs included, since the pose is sampled from the score — with a
|
|
83
|
+
* pose the host applies to whatever it is drawing with.
|
|
84
|
+
*/
|
|
85
|
+
onCamera3D?: (state: Camera3DState) => void;
|
|
86
|
+
/**
|
|
87
|
+
* The dispatcher for `<c.Perform>` commands (§C4). Called once per
|
|
88
|
+
* command as the run's clock comes to include it — during forward
|
|
89
|
+
* playback as the clock crosses it, after a seek that lands past it,
|
|
90
|
+
* and again for the whole remaining prefix after a backward fold.
|
|
91
|
+
* Dispatches are deferred past the render pass, so a command may
|
|
92
|
+
* mutate tracked state freely.
|
|
93
|
+
*/
|
|
94
|
+
onPerform?: (command: PerformCommand) => void;
|
|
95
|
+
/**
|
|
96
|
+
* The backward half of the fold: the clock moved to before a command
|
|
97
|
+
* the host already holds. Reset every commanded state here; the run
|
|
98
|
+
* re-dispatches the remaining prefix, in order, immediately after.
|
|
99
|
+
*/
|
|
100
|
+
onPerformReset?: () => void;
|
|
101
|
+
/**
|
|
102
|
+
* Freeze the rest of the page for the span of each run (§4.7): when a
|
|
103
|
+
* run starts, every animation in the document that is running AT THAT
|
|
104
|
+
* MOMENT — and that the run itself does not own — is paused, and played
|
|
105
|
+
* again when the run lands or is cancelled. The run's own animations
|
|
106
|
+
* are exempt by construction: the sweep happens before they exist.
|
|
107
|
+
* Pausing is not stopping — a loop resumes exactly where it was, which
|
|
108
|
+
* is what makes this safe to do to work the region did not write.
|
|
109
|
+
* Animations that START during the run are not caught; gating those is
|
|
110
|
+
* the host's job (the crossing flag the gallery's entrances check).
|
|
111
|
+
*/
|
|
112
|
+
quiet?: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Treat a subtree swap as one crossing pass (§4.7): scroll intent is
|
|
115
|
+
* applied inside the pass — after the swap renders, before final bounds
|
|
116
|
+
* are measured — and the tempo control's zero means no run at all. The
|
|
117
|
+
* region stays router-agnostic (§9): any swap qualifies, however the
|
|
118
|
+
* host caused it.
|
|
119
|
+
*/
|
|
120
|
+
route?: boolean;
|
|
121
|
+
/** where the arriving scene wants the window: the top, or wherever the thunk says */
|
|
122
|
+
scroll?: 'top' | (() => number);
|
|
123
|
+
};
|
|
124
|
+
Blocks: {
|
|
125
|
+
default: [ChoreoContext];
|
|
126
|
+
};
|
|
127
|
+
Element: HTMLDivElement;
|
|
128
|
+
}
|
|
129
|
+
export declare class Choreo extends Component<Signature> implements ChoreoHost {
|
|
130
|
+
private element?;
|
|
131
|
+
private orphanLayer?;
|
|
132
|
+
private raisedLayer?;
|
|
133
|
+
private tetherLayer?;
|
|
134
|
+
/** tracked mirror of the frame's resting state — see ChoreoContext.camera */
|
|
135
|
+
cameraState: CameraState;
|
|
136
|
+
/**
|
|
137
|
+
* The same state, untracked, for the pass pipeline itself. A pass runs
|
|
138
|
+
* inside computations that must not CONSUME the tracked mirror — a pass
|
|
139
|
+
* that read it would be invalidated by the very landing it causes, and
|
|
140
|
+
* the region would render forever.
|
|
141
|
+
*/
|
|
142
|
+
/** where a c.Camera3D left the shot, carried between runs — seeded by
|
|
143
|
+
* `@camera3dFrom` when the host knows its own opening pose */
|
|
144
|
+
private resting3d;
|
|
145
|
+
private restingCamera;
|
|
146
|
+
private participants;
|
|
147
|
+
/** registered since the last pass */
|
|
148
|
+
private arrived;
|
|
149
|
+
/** destroyed before the pass that removed them has been processed */
|
|
150
|
+
private claimed;
|
|
151
|
+
/** removed participants this region is keeping alive in its orphan layer */
|
|
152
|
+
private orphans;
|
|
153
|
+
/** participants whose Presence is letting them go: removed once, not on every pass while they leave */
|
|
154
|
+
private leaving;
|
|
155
|
+
private snapshots;
|
|
156
|
+
private rootSnapshot?;
|
|
157
|
+
private passPending;
|
|
158
|
+
private rendered;
|
|
159
|
+
run?: ChoreoRun;
|
|
160
|
+
private context;
|
|
161
|
+
/** the last changeset this region built — read it from a property function or a test */
|
|
162
|
+
changeset?: Changeset;
|
|
163
|
+
constructor(owner: Owner, args: Signature['Args']);
|
|
164
|
+
/** SPIKE (Lane): providers from outside the markup, appended to every collected tree */
|
|
165
|
+
private contributors;
|
|
166
|
+
contribute(provider: ChoreoProvider): () => void;
|
|
167
|
+
/** the run an attachment drives: the one playing or holding, none between runs */
|
|
168
|
+
currentRun(): ChoreoRun | null;
|
|
169
|
+
/** the region's own steps in document order, then whatever was contributed from outside */
|
|
170
|
+
private collectTree;
|
|
171
|
+
register(node: ChoreoNode): () => void;
|
|
172
|
+
claim(node: ChoreoNode): boolean;
|
|
173
|
+
get renderDetector(): undefined;
|
|
174
|
+
private snapshot;
|
|
175
|
+
/** phase 1: what changed this pass, measured — nothing is played yet */
|
|
176
|
+
measurePass(): Pass | undefined;
|
|
177
|
+
/** phase 3: identities are settled — compile this region's timeline and play it */
|
|
178
|
+
finishPass(pass: Pass): void;
|
|
179
|
+
private orphanBounds;
|
|
180
|
+
/** the fingerprint of the tree the current run compiled from (see treePrint) */
|
|
181
|
+
private scorePrint?;
|
|
182
|
+
/** the layout every participant stood in when the run compiled (see layoutPrint) */
|
|
183
|
+
private layoutPrint?;
|
|
184
|
+
/**
|
|
185
|
+
* Where the stylesheet puts each participant, as a string.
|
|
186
|
+
*
|
|
187
|
+
* `offsetLeft/Top/Width/Height` and NOT a bounding rect, because the
|
|
188
|
+
* difference is the whole point: a rect includes the transform a flight
|
|
189
|
+
* is writing, so a moving element reads as different on every frame,
|
|
190
|
+
* while offsets are the box layout asked for — steady under a transform,
|
|
191
|
+
* and different the moment something actually reflows. Integers, too,
|
|
192
|
+
* which quietly forgives the sub-pixel noise a busy page generates.
|
|
193
|
+
*
|
|
194
|
+
* A Move that animates real width/height (`@size={{true}}`) does change
|
|
195
|
+
* these, so such a run never takes the fast path. That is the honest
|
|
196
|
+
* answer rather than a missed optimisation: a run writing layout cannot
|
|
197
|
+
* be told apart from a page writing layout without measuring.
|
|
198
|
+
*
|
|
199
|
+
* Offsets are accumulated up the offset chain to the region, not read
|
|
200
|
+
* at the participant alone, because what a render moves may be an
|
|
201
|
+
* ANCESTOR that is no participant of anything — Escort's seat, one
|
|
202
|
+
* positioned wrapper carrying three participants. Read flat, the
|
|
203
|
+
* fingerprint was blind to exactly the reflow a retarget makes, the
|
|
204
|
+
* pass was declined, and the old run played on against the moved
|
|
205
|
+
* layout: card, badge and shadow teleported a whole bay, together. The
|
|
206
|
+
* walk stops at the region's edge so the page above it stays out of the
|
|
207
|
+
* print — a busy neighbour reflowing above the region must not cancel
|
|
208
|
+
* its runs.
|
|
209
|
+
*/
|
|
210
|
+
private layoutOf;
|
|
211
|
+
/**
|
|
212
|
+
* Can this pass be declined outright? Only while a run is in flight, and
|
|
213
|
+
* only when nothing the pass could discover would change it: no arrivals,
|
|
214
|
+
* no retentions pending, every participant either present or already a
|
|
215
|
+
* known leaver, the collected timeline tree fingerprints identical to the
|
|
216
|
+
* one the run compiled from (an EDIT always replays), and every
|
|
217
|
+
* participant standing in the same layout box it compiled in (a REFLOW
|
|
218
|
+
* always replays — it is what a Move is FOR). Anything else takes the
|
|
219
|
+
* full pipeline.
|
|
220
|
+
*/
|
|
221
|
+
private fastKeep;
|
|
222
|
+
/** what quiet() paused, accumulated across replaced runs, resumed as one */
|
|
223
|
+
private quieted;
|
|
224
|
+
private quiet;
|
|
225
|
+
private unquiet;
|
|
226
|
+
private orphan;
|
|
227
|
+
/** a removed sprite's row has ended */
|
|
228
|
+
private finish;
|
|
229
|
+
private drop;
|
|
230
|
+
private log;
|
|
231
|
+
host: import("ember-modifier").FunctionBasedModifier<{
|
|
232
|
+
Args: {
|
|
233
|
+
Positional: unknown[];
|
|
234
|
+
Named: import("ember-modifier/-private/signature").EmptyObject;
|
|
235
|
+
};
|
|
236
|
+
Element: HTMLDivElement;
|
|
237
|
+
}>;
|
|
238
|
+
layer: import("ember-modifier").FunctionBasedModifier<{
|
|
239
|
+
Args: {
|
|
240
|
+
Positional: unknown[];
|
|
241
|
+
Named: import("ember-modifier/-private/signature").EmptyObject;
|
|
242
|
+
};
|
|
243
|
+
Element: HTMLDivElement;
|
|
244
|
+
}>;
|
|
245
|
+
raised: import("ember-modifier").FunctionBasedModifier<{
|
|
246
|
+
Args: {
|
|
247
|
+
Positional: unknown[];
|
|
248
|
+
Named: import("ember-modifier/-private/signature").EmptyObject;
|
|
249
|
+
};
|
|
250
|
+
Element: HTMLDivElement;
|
|
251
|
+
}>;
|
|
252
|
+
tethers: import("ember-modifier").FunctionBasedModifier<{
|
|
253
|
+
Args: {
|
|
254
|
+
Positional: unknown[];
|
|
255
|
+
Named: import("ember-modifier/-private/signature").EmptyObject;
|
|
256
|
+
};
|
|
257
|
+
Element: SVGSVGElement;
|
|
258
|
+
}>;
|
|
259
|
+
}
|
|
260
|
+
export default Choreo;
|
|
261
|
+
//# sourceMappingURL=choreo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"choreo.d.ts","sourceRoot":"","sources":["../src/choreo.gts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ChangesetLike, Compiled, Cue, DeliveryOrder, Sprite, TimelineNode } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The rung each index takes on the stagger ladder, under a delivery order.
|
|
4
|
+
* 'center' delivers from the middle outward; 'random' shuffles per run —
|
|
5
|
+
* seeded input is the native driver's requirement, not this one's.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ladder(n: number, order: DeliveryOrder): number[];
|
|
8
|
+
export default function compile(tree: TimelineNode[], cs: ChangesetLike): Compiled;
|
|
9
|
+
/**
|
|
10
|
+
* A replacement pass's continuity cue (§3.1): the prior run was driving
|
|
11
|
+
* this sprite through space and the new score does not name it. Unnamed
|
|
12
|
+
* it would be released to its rest in one frame — the whole-bay snap —
|
|
13
|
+
* so the region completes the score: one shape-matched move from the
|
|
14
|
+
* painted box (which is what a mid-flight sprite's `initial` IS, by
|
|
15
|
+
* design) to its rest. Transform-only, so a continuation can never
|
|
16
|
+
* reflow the scene it is tidying; on the interrupted cue's own spring
|
|
17
|
+
* when it had one, so the carry-on keeps the flight's character.
|
|
18
|
+
*/
|
|
19
|
+
export declare function continuation(sprite: Sprite, cs: ChangesetLike, inherited?: Record<string, unknown>): Cue | null;
|
|
20
|
+
/**
|
|
21
|
+
* Whether two compiled scores are the SAME statement — used by the region
|
|
22
|
+
* to keep an in-flight run when an unrelated render replays the pass (the
|
|
23
|
+
* render detector is volatile by design, so on a busy page every region
|
|
24
|
+
* re-passes on every app render; a neighbouring demo writing tracked state
|
|
25
|
+
* per frame must not restart this region's clock).
|
|
26
|
+
*
|
|
27
|
+
* The comparison is deliberately conservative. A FLIGHT is measured off the
|
|
28
|
+
* page and is not comparable by value: any cue carrying one makes the scores
|
|
29
|
+
* different, and the pass replays exactly as it always did. Values that ARE
|
|
30
|
+
* comparable (targets, transitions, delivery plans, holds, camera aims)
|
|
31
|
+
* compare structurally, so an edit that retimes or re-aims anything replays.
|
|
32
|
+
*
|
|
33
|
+
* Tethers, raises and scrolls used to be lumped in with flights, and that was
|
|
34
|
+
* wrong in a way that only showed up on standing annotations: a wire that is
|
|
35
|
+
* simply ON was recompiled to the identical statement on every pass and, being
|
|
36
|
+
* declared different every time, had its run torn down and rebuilt — the path
|
|
37
|
+
* element removed from the layer and a new one appended, sixty times a second
|
|
38
|
+
* on a busy page. None of the three carries measured geometry in its cue: a
|
|
39
|
+
* tether is two sprites and a function, a raise is a sprite and a flag, a
|
|
40
|
+
* scroll is a sprite and an alignment. They compare by IDENTITY, which is
|
|
41
|
+
* exactly what "the same statement" means for them — and it matters most for
|
|
42
|
+
* the scroll, where replacing the cue is a visible restart of the scroll.
|
|
43
|
+
*/
|
|
44
|
+
export declare function sameScore(a: Cue[], b: Cue[]): boolean;
|
|
45
|
+
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAGV,aAAa,EACb,QAAQ,EACR,GAAG,EACH,aAAa,EAWb,MAAM,EAEN,YAAY,EAEb,MAAM,YAAY,CAAC;AAoIpB;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,EAAE,CA2BhE;AAw6BD,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,IAAI,EAAE,YAAY,EAAE,EACpB,EAAE,EAAE,aAAa,GAChB,QAAQ,CAuQV;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,aAAa,EACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,GAAG,GAAG,IAAI,CAuBZ;AAID;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAErD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Cue, DeliveryBy, Easing, SpringSpec } from './types.ts';
|
|
2
|
+
interface Slot {
|
|
3
|
+
el: HTMLElement;
|
|
4
|
+
}
|
|
5
|
+
interface Split {
|
|
6
|
+
/** put the original nodes back; safe to call twice */
|
|
7
|
+
restore(): void;
|
|
8
|
+
slots: Slot[];
|
|
9
|
+
}
|
|
10
|
+
export declare function split(el: HTMLElement, by: Exclude<DeliveryBy, 'item'>): Split;
|
|
11
|
+
export interface Window {
|
|
12
|
+
at: number;
|
|
13
|
+
ms: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* `@stagger` seconds between starts, window = what remains of the span; with
|
|
17
|
+
* no stagger, the Build Order demo's policy: a 0.55-of-span window with the
|
|
18
|
+
* starts distributed across the remainder.
|
|
19
|
+
*/
|
|
20
|
+
export declare function windows(n: number, span: number, stagger: number): Window[];
|
|
21
|
+
/** cue.target, as WAAPI property-indexed keyframes */
|
|
22
|
+
export declare function keyframesOf(target: Record<string, unknown>, times?: number[], ease?: string): PropertyIndexedKeyframes;
|
|
23
|
+
export declare function cssEasing(ease: Easing | undefined, ms: number): string;
|
|
24
|
+
/** a spring's clock, pre-sampled: its real duration and a linear() easing */
|
|
25
|
+
export declare function springEasing(spec: SpringSpec | undefined): {
|
|
26
|
+
easing: string;
|
|
27
|
+
ms: number;
|
|
28
|
+
};
|
|
29
|
+
export interface Delivery {
|
|
30
|
+
cancel(): void;
|
|
31
|
+
/** finish NOW: land the end values and give the text back — a scrub past
|
|
32
|
+
* the cue's end must not leave paused spans standing in for the sprite */
|
|
33
|
+
complete(): void;
|
|
34
|
+
finished: Promise<void>;
|
|
35
|
+
pause(): void;
|
|
36
|
+
play(): void;
|
|
37
|
+
/** place the whole delivery at `ms` past its cue start (unscaled) */
|
|
38
|
+
seek(ms: number): void;
|
|
39
|
+
speed(rate: number): void;
|
|
40
|
+
}
|
|
41
|
+
/** play one delivery cue: split, animate the slots, restore, land the end values */
|
|
42
|
+
export declare function deliver(cue: Cue, speed: number): Delivery;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=deliver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../src/deliver.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,GAAG,EACH,UAAU,EACV,MAAM,EAEN,UAAU,EACX,MAAM,YAAY,CAAC;AAKpB,UAAU,IAAI;IACZ,EAAE,EAAE,WAAW,CAAC;CACjB;AAED,UAAU,KAAK;IACb,sDAAsD;IACtD,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AA8BD,wBAAgB,KAAK,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,KAAK,CA+E7E;AAID,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAa1E;AAYD,sDAAsD;AACtD,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,IAAI,CAAC,EAAE,MAAM,GACZ,wBAAwB,CA2B1B;AAkBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAWtE;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,GAAG;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACZ,CAMA;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,IAAI,IAAI,CAAC;IACf;+EAC2E;IAC3E,QAAQ,IAAI,IAAI,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,qEAAqE;IACrE,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,oFAAoF;AACpF,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CA0FzD"}
|