@ssgoi/core 6.7.0-beta.1 → 7.0.0-beta.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.
Files changed (100) hide show
  1. package/README.md +80 -230
  2. package/dist/animation/animation.d.ts +2 -2
  3. package/dist/animation/frame-scheduler.d.ts +36 -0
  4. package/dist/animation/frame-scheduler.d.ts.map +1 -0
  5. package/dist/animation/multi-animation.d.ts +3 -2
  6. package/dist/animation/multi-animation.d.ts.map +1 -1
  7. package/dist/animation/web-animation.d.ts +16 -4
  8. package/dist/animation/web-animation.d.ts.map +1 -1
  9. package/dist/index.cjs +15 -15
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1282 -1125
  13. package/dist/internal.cjs +1 -1
  14. package/dist/internal.d.ts +1 -1
  15. package/dist/internal.d.ts.map +1 -1
  16. package/dist/internal.js +692 -521
  17. package/dist/multi-animation-6124HEke.cjs +1 -0
  18. package/dist/multi-animation-ZFZBDBGr.js +439 -0
  19. package/dist/ssgoi-transition/create-ssgoi-transition-context.d.ts.map +1 -1
  20. package/dist/ssgoi-transition/navigation-detector-strategy.d.ts +24 -9
  21. package/dist/ssgoi-transition/navigation-detector-strategy.d.ts.map +1 -1
  22. package/dist/ssgoi-transition/navigation-direction.d.ts +13 -0
  23. package/dist/ssgoi-transition/navigation-direction.d.ts.map +1 -0
  24. package/dist/ssgoi-transition/observe-ssgoi-transitions.d.ts +1 -0
  25. package/dist/ssgoi-transition/observe-ssgoi-transitions.d.ts.map +1 -1
  26. package/dist/ssgoi-transition/path-pattern.d.ts +15 -0
  27. package/dist/ssgoi-transition/path-pattern.d.ts.map +1 -0
  28. package/dist/ssgoi-transition/resolve-transition-rule.d.ts +16 -0
  29. package/dist/ssgoi-transition/resolve-transition-rule.d.ts.map +1 -0
  30. package/dist/ssgoi-transition/unmount-observer.d.ts +11 -2
  31. package/dist/ssgoi-transition/unmount-observer.d.ts.map +1 -1
  32. package/dist/transitions/axis/index.d.ts +5 -7
  33. package/dist/transitions/axis/index.d.ts.map +1 -1
  34. package/dist/transitions/axis/types.d.ts +0 -1
  35. package/dist/transitions/axis/types.d.ts.map +1 -1
  36. package/dist/transitions/blind/index.d.ts +2 -3
  37. package/dist/transitions/blind/index.d.ts.map +1 -1
  38. package/dist/transitions/drill/index.d.ts +6 -7
  39. package/dist/transitions/drill/index.d.ts.map +1 -1
  40. package/dist/transitions/drill/provider/crossfade.d.ts.map +1 -1
  41. package/dist/transitions/drill/provider/parallax.d.ts.map +1 -1
  42. package/dist/transitions/drill/transition.d.ts.map +1 -1
  43. package/dist/transitions/drill/types.d.ts +0 -1
  44. package/dist/transitions/drill/types.d.ts.map +1 -1
  45. package/dist/transitions/fade/index.d.ts +3 -5
  46. package/dist/transitions/fade/index.d.ts.map +1 -1
  47. package/dist/transitions/film/index.d.ts +3 -5
  48. package/dist/transitions/film/index.d.ts.map +1 -1
  49. package/dist/transitions/hero/fit.d.ts +5 -0
  50. package/dist/transitions/hero/fit.d.ts.map +1 -0
  51. package/dist/transitions/hero/index.d.ts +3 -5
  52. package/dist/transitions/hero/index.d.ts.map +1 -1
  53. package/dist/transitions/hero/transition.d.ts +12 -1
  54. package/dist/transitions/hero/transition.d.ts.map +1 -1
  55. package/dist/transitions/hero/types.d.ts +2 -1
  56. package/dist/transitions/hero/types.d.ts.map +1 -1
  57. package/dist/transitions/jaemin/index.d.ts +3 -5
  58. package/dist/transitions/jaemin/index.d.ts.map +1 -1
  59. package/dist/transitions/media-geometry.d.ts +55 -0
  60. package/dist/transitions/media-geometry.d.ts.map +1 -0
  61. package/dist/transitions/rotate/index.d.ts +3 -5
  62. package/dist/transitions/rotate/index.d.ts.map +1 -1
  63. package/dist/transitions/scroll/index.d.ts +4 -5
  64. package/dist/transitions/scroll/index.d.ts.map +1 -1
  65. package/dist/transitions/scroll/transition.d.ts +1 -1
  66. package/dist/transitions/scroll/transition.d.ts.map +1 -1
  67. package/dist/transitions/sheet/index.d.ts +6 -7
  68. package/dist/transitions/sheet/index.d.ts.map +1 -1
  69. package/dist/transitions/sheet/provider/static.d.ts.map +1 -1
  70. package/dist/transitions/sheet/transition.d.ts.map +1 -1
  71. package/dist/transitions/sheet/types.d.ts +0 -1
  72. package/dist/transitions/sheet/types.d.ts.map +1 -1
  73. package/dist/transitions/slide/index.d.ts +3 -5
  74. package/dist/transitions/slide/index.d.ts.map +1 -1
  75. package/dist/transitions/slide/transition.d.ts +0 -1
  76. package/dist/transitions/slide/transition.d.ts.map +1 -1
  77. package/dist/transitions/strip/index.d.ts +3 -5
  78. package/dist/transitions/strip/index.d.ts.map +1 -1
  79. package/dist/transitions/utils.d.ts +3 -21
  80. package/dist/transitions/utils.d.ts.map +1 -1
  81. package/dist/transitions/zoom/index.d.ts +3 -4
  82. package/dist/transitions/zoom/index.d.ts.map +1 -1
  83. package/dist/transitions/zoom/provider/blur.d.ts.map +1 -1
  84. package/dist/transitions/zoom/transition.d.ts +6 -1
  85. package/dist/transitions/zoom/transition.d.ts.map +1 -1
  86. package/dist/transitions/zoom/types.d.ts +5 -0
  87. package/dist/transitions/zoom/types.d.ts.map +1 -1
  88. package/dist/transitions/zoom/zoom-element.d.ts +2 -2
  89. package/dist/transitions/zoom/zoom-element.d.ts.map +1 -1
  90. package/dist/types/index.d.ts +66 -10
  91. package/dist/types/index.d.ts.map +1 -1
  92. package/dist/utils/wait-paint.d.ts +8 -7
  93. package/dist/utils/wait-paint.d.ts.map +1 -1
  94. package/package.json +13 -14
  95. package/dist/multi-animation-1FueEz2Q.js +0 -367
  96. package/dist/multi-animation-qtH1IKNG.cjs +0 -1
  97. package/dist/ssgoi-transition/find-matching-transition.d.ts +0 -30
  98. package/dist/ssgoi-transition/find-matching-transition.d.ts.map +0 -1
  99. package/dist/ssgoi-transition/process-symmetric-transitions.d.ts +0 -7
  100. package/dist/ssgoi-transition/process-symmetric-transitions.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,272 +1,122 @@
1
- # SSGOI
1
+ # @ssgoi/core
2
2
 
3
- The framework-agnostic animation engine behind [SSGOI](https://ssgoi.dev) — native app-like page transitions for the web.
3
+ Framework-agnostic route transition engine for SSGOI.
4
4
 
5
- > Most apps should install a framework binding (`@ssgoi/react`, `@ssgoi/svelte`, `@ssgoi/vue`, `@ssgoi/solid`, `@ssgoi/angular`, `@ssgoi/qwik`), which depend on this package. Install `@ssgoi/core` directly only when building a custom integration.
5
+ [![SSGOI live showcase](https://ssgoi.dev/readme.png)](https://ssgoi.dev)
6
6
 
7
- try this: [ssgoi.dev](https://ssgoi.dev)
7
+ [Live demos](https://ssgoi.dev) · [Hero, Zoom, Film, and Sheet in motion](https://ssgoi.dev/blog/view-transition-api-limitations)
8
8
 
9
- ![SSGOI Demo](https://ssgoi.dev/ssgoi.gif)
10
-
11
- ## AI-Assisted Setup
12
-
13
- Using Claude, Cursor, ChatGPT, or another AI assistant? Point it at:
14
-
15
- ```
16
- https://ssgoi.dev/llms.txt
17
- ```
18
-
19
- It has the full setup guide, every transition, the API, and troubleshooting — everything an agent needs to wire SSGOI into your app.
20
-
21
- ## What is SSGOI?
22
-
23
- SSGOI brings native app-like page transitions to the web. Transform your static page navigations into smooth, delightful experiences that users love.
24
-
25
- ### ✨ Key Features
26
-
27
- - **🌍 Works Everywhere** - Unlike the browser's View Transition API, SSGOI works in all modern browsers (Chrome, Firefox, Safari)
28
- - **🚀 SSR Ready** - Perfect compatibility with Next.js, Nuxt, SvelteKit, SolidStart, Qwik City. No hydration issues, SEO-friendly
29
- - **🎯 Use Your Router** - Keep your existing routing. React Router, Next.js App Router, SvelteKit, Qwik City - all work seamlessly
30
- - **💾 State Persistence** - Remembers animation state during navigation, even with browser back/forward
31
- - **🎨 Framework Agnostic** - One consistent API for React, Svelte, Vue, Solid, Angular, and more
32
-
33
- ## Quick Start
34
-
35
- ### Installation
9
+ Most applications should install a framework package:
36
10
 
37
11
  ```bash
38
- # Pick the binding for your framework
39
12
  npm install @ssgoi/react
40
- # or @ssgoi/svelte, @ssgoi/vue, @ssgoi/solid, @ssgoi/angular, @ssgoi/qwik
41
- ```
42
-
43
- ### Add Transitions in 30 Seconds
44
-
45
- #### 1. Wrap your React app
46
-
47
- ```tsx
48
- import { Ssgoi } from "@ssgoi/react";
49
- import { fade } from "@ssgoi/react/view-transitions";
50
- import { SsgoiTransitionBoundary } from "./ssgoi-transition-boundary";
51
-
52
- const config = {
53
- transitions: [fade({ paths: ["/", "/about"] })],
54
- };
55
-
56
- export default function App() {
57
- return (
58
- <div className="relative z-0 min-h-dvh bg-white">
59
- {/* Layout shell above: positioned ancestor + stacking context for the OUT clone. */}
60
- <Ssgoi config={config}>
61
- {/* Routed content marker. Layout positioning belongs to the outer wrapper. */}
62
- <SsgoiTransitionBoundary className="min-h-full bg-white">
63
- {/* Your app */}
64
- </SsgoiTransitionBoundary>
65
- </Ssgoi>
66
- </div>
67
- );
68
- }
69
- ```
70
-
71
- #### 2. Keep React pages unmarked
72
-
73
- ```tsx
74
- export default function HomePage() {
75
- return (
76
- <main>
77
- <h1>Welcome</h1>
78
- {/* Page content */}
79
- </main>
80
- );
81
- }
13
+ # or @ssgoi/svelte, @ssgoi/vue, @ssgoi/solid, @ssgoi/qwik
82
14
  ```
83
15
 
84
- For React adapters, create one router-specific `SsgoiTransitionBoundary` utility
85
- in your layout. It reads the current pathname internally, sets the transition
86
- boundary key, and uses that pathname as a logical page id matched by config such
87
- as `/products/*`. Use `/products/**` when the parent path itself should match
88
- too.
89
-
90
- Next.js implementation:
91
-
92
- ```tsx
93
- "use client";
94
-
95
- import { type ElementType, type ReactNode } from "react";
96
- import { usePathname } from "next/navigation";
97
-
98
- export function SsgoiTransitionBoundary({
99
- children,
100
- as,
101
- className,
102
- }: {
103
- children: ReactNode;
104
- as?: ElementType;
105
- className?: string;
106
- }) {
107
- const pathname = usePathname();
108
- const Component = as ?? "div";
109
-
110
- return (
111
- <Component
112
- key={pathname}
113
- data-ssgoi-transition={pathname}
114
- className={className}
115
- >
116
- {children}
117
- </Component>
118
- );
119
- }
120
- ```
121
-
122
- React Router and TanStack Router use the same component body with their own
123
- pathname hook.
124
-
125
- For SvelteKit, Nuxt/Vue, Solid, Angular, and Qwik, mark each routed page boundary
126
- directly with `data-ssgoi-transition` instead of using a layout-level utility.
127
- The value can be a hard-coded logical id; it only has to match your config.
128
-
129
- **That's it!** Your configured pages now transition smoothly with a fade effect.
16
+ Agent setup guide: https://ssgoi.dev/llms.txt
130
17
 
131
- ## Advanced Transitions
18
+ ## Configuration
132
19
 
133
- ### Route-based Transitions
20
+ `SsgoiConfig` contains route matching and effects. Layout lifetime belongs to
21
+ framework-specific transition boundaries, not this config.
134
22
 
135
- Each transition factory returns a path-transition group. Drop the results straight into `config.transitions` — nested arrays are flattened automatically:
23
+ ```ts
24
+ import { drill, slide, zoom, type SsgoiConfig } from "@ssgoi/core";
136
25
 
137
- ```tsx
138
- import { fade, drill, zoom } from "@ssgoi/react/view-transitions";
139
-
140
- const config = {
26
+ const config: SsgoiConfig = {
27
+ preserveScroll: { exclude: ["/posts/*"] },
141
28
  transitions: [
142
- // Calm cross-fade between tabs
143
- fade({ paths: ["/home", "/about"] }),
144
-
145
- // iOS-style drill-in when entering details
146
- drill({ enter: "/products/*", exit: "/products" }),
147
-
148
- // Card-to-detail zoom (needs matching data-zoom-*-key)
149
- zoom({ paths: ["/gallery", "/photo/*"], type: "expand" }),
29
+ { on: "/posts/**", except: "/posts", transition: drill() },
30
+ { from: "/gallery", to: "/gallery/*", transition: zoom() },
31
+ {
32
+ ordered: ["/tabs/a", "/tabs/b", "/tabs/c"],
33
+ transition: slide(),
34
+ },
150
35
  ],
151
36
  };
152
37
  ```
153
38
 
154
- Transitions come in three shapes:
39
+ Rule forms:
155
40
 
156
- - **`{ paths }`** — symmetric: every pair animates with the same physics (`fade`, `hero`, `zoom`, `blind`, `film`, `rotate`, `strip`, `jaemin`)
157
- - **`{ enter, exit, type? }`** — directional: enter and exit get different physics (`drill`, `sheet`)
158
- - **`{ paths }`** — ordered: path order decides forward / back direction (`slide`, `scroll`, `axis`)
41
+ - `on`: route family. Entering is forward; leaving is backward.
42
+ - `from`/`to`: precise pair. Reverse matching is enabled by default.
43
+ - `ordered`: array order decides forward and backward.
44
+ - `priority`: higher values win before path specificity.
159
45
 
160
- ### Individual Element Animations
46
+ Path patterns:
161
47
 
162
- Animate specific elements during mount/unmount with `transition()`:
48
+ - `/posts`: exact.
49
+ - `/posts/*`: exactly one arbitrary segment.
50
+ - `/posts/**`: the parent and every descendant.
163
51
 
164
- ```tsx
165
- import { transition } from "@ssgoi/react";
166
- import { fade, slide } from "@ssgoi/react/transitions";
52
+ A bare `*` remains a compatibility alias for `/**`. Named single-segment forms
53
+ remain supported and rank above a single-segment `*` when rules overlap, but
54
+ their names are not captured or exposed.
167
55
 
168
- function Card() {
169
- return (
170
- <div
171
- ref={transition({
172
- key: "card",
173
- in: fade(),
174
- out: slide({ direction: "up" }),
175
- })}
176
- >
177
- <h2>Animated Card</h2>
178
- </div>
179
- );
180
- }
181
- ```
56
+ ## Boundary model
182
57
 
183
- ## Built-in Transitions
184
-
185
- ### Page Transitions (`@ssgoi/<framework>/view-transitions`)
186
-
187
- - `fade` - Calm cross-fade. Safe default for unrelated pages
188
- - `drill` - iOS-style hierarchical navigation (list → detail)
189
- - `slide` - Horizontal push for tabs / sequential flows
190
- - `scroll` - Vertical page scroll for onboarding / paginated views
191
- - `axis` - Material/Flutter shared-axis swap for sibling/tab routes
192
- - `sheet` - Bottom sheet that slides up (modal-like flows)
193
- - `hero` - Shared element transition (matching `data-hero-*-key`)
194
- - `zoom` - Card-to-detail expansion (matching `data-zoom-*-key`)
195
- - `strip` - 3D Y-axis perspective flip
196
- - `blind` - Window-blinds wipe reveal
197
- - `film` - Cinematic shrink + tile (gallery / lightbox)
198
- - `rotate` - Card flip between siblings
199
- - `jaemin` - Playful rotated zoom for special moments
200
-
201
- ### Element Transitions (`@ssgoi/<framework>/transitions`)
202
-
203
- For mount/unmount of individual elements (not whole pages):
204
-
205
- - `fade` - Fade in/out
206
- - `scale` - Scale in/out
207
- - `slide` - Slide (direction: up/down/left/right)
208
- - `rotate` - Rotate
209
- - `bounce` - Bounce
210
- - `blur` - Blur
211
- - `fly` - Fly (custom x, y position)
212
-
213
- ## Layout Requirements
214
-
215
- The outer element wrapping the SSGOI provider / `<Ssgoi>` needs
216
- `position: relative` and `z-index: 0`.
217
-
218
- When a page leaves, SSGOI clones it back into the DOM with `position: absolute`
219
- so it can animate out while the new page animates in. Without a positioned,
220
- stacking-context ancestor the clone jumps to the wrong place or falls behind the
221
- background. Add `overflow-x-clip` too if you use horizontal transitions
222
- (`slide`, `drill`). Keep these layout classes on the outer wrapper, not on the
223
- route boundary marker.
224
-
225
- ```tsx
226
- <div className="relative z-0 overflow-x-clip">
227
- <Ssgoi config={config}>{children}</Ssgoi>
228
- </div>
58
+ A framework adapter observes elements marked with:
59
+
60
+ ```html
61
+ <div data-ssgoi-transition="/posts/1">...</div>
229
62
  ```
230
63
 
231
- ## Why SSGOI?
64
+ The framework decides when that element is replaced. Nested boundaries follow
65
+ DOM lifetime:
232
66
 
233
- ### vs View Transition API
67
+ - Parent and child change together: the outer changed boundary owns the event.
68
+ - Parent remains mounted: the changed child owns the event.
234
69
 
235
- - ✅ Works in all browsers, not just Chrome
236
- - ✅ More animation options with spring physics
237
- - ✅ Better developer experience
70
+ This supports persistent layouts, inner tab transitions, and bottom navigation
71
+ with one SSGOI instance.
238
72
 
239
- ### vs Other Animation Libraries
73
+ ## Transition context
240
74
 
241
- - ✅ Built specifically for page transitions
242
- - ✅ SSR-first design
243
- - ✅ No router lock-in
244
- - ✅ Minimal bundle size
75
+ Custom effects receive semantic direction through `context`:
245
76
 
246
- ## How It Works
77
+ ```ts
78
+ import { defineTransition } from "@ssgoi/core";
247
79
 
248
- SSGOI orchestrates two simultaneous animations on every route change:
80
+ const effect = defineTransition({
81
+ prepare: ({ from, to, context }) => {
82
+ // Pre-paint setup.
83
+ return {};
84
+ },
85
+ animation: ({ from, to, context }) => {
86
+ // context.direction is "forward" or "backward".
87
+ return animation;
88
+ },
89
+ });
90
+ ```
249
91
 
250
- 1. **Route Change**: Your router changes the URL
251
- 2. **Exit (OUT)**: SSGOI clones the leaving page with `position: absolute` and animates it out
252
- 3. **Enter (IN)**: The new page mounts in place and animates in
253
- 4. **State Sync**: Animation state persists across navigation, including browser back/forward
92
+ ## Effect index
254
93
 
255
- All powered by a spring physics engine — springs are pre-computed into Web Animations API keyframes, so animations run at 60fps off the main thread.
94
+ - `fade`: unrelated pages.
95
+ - `drill`: list → detail hierarchy.
96
+ - `slide`: ordered tabs and steps.
97
+ - `axis`: sibling destinations.
98
+ - `sheet`: modal-like routes.
99
+ - `zoom`: card or image → detail.
100
+ - `hero`: shared elements plus page chrome.
101
+ - `scroll`: vertical sequences.
102
+ - `strip`, `film`, `rotate`, `blind`, `jaemin`: expressive transitions.
256
103
 
257
- ## Documentation
104
+ Effect references: https://ssgoi.dev/llms.txt#7-transition-index
258
105
 
259
- Visit [https://ssgoi.dev](https://ssgoi.dev) for:
106
+ ## Layout requirements
260
107
 
261
- - Detailed API reference
262
- - Interactive examples
263
- - Framework integration guides
264
- - Custom transition recipes
108
+ The shell around the framework root should provide:
265
109
 
266
- ## Contributing
110
+ ```css
111
+ .ssgoi-shell {
112
+ position: relative;
113
+ z-index: 0;
114
+ overflow-x: clip;
115
+ }
116
+ ```
267
117
 
268
- We welcome contributions! Please see our [contributing guide](https://github.com/meursyphus/ssgoi/blob/main/CONTRIBUTING.md) for details.
118
+ `overflow-x: clip` is needed for horizontal effects.
269
119
 
270
120
  ## License
271
121
 
272
- MIT © [MeurSyphus](https://github.com/meursyphus)
122
+ MIT
@@ -51,8 +51,8 @@ export declare abstract class Animation {
51
51
  * Reads the live simulation value, so it advances frame-by-frame while
52
52
  * playing. Useful for external inspection / debugging.
53
53
  *
54
- * NOT used by `MultiAnimation` stagger triggering — that uses the
55
- * pre-computed timeline via `findTimeForProgress` to avoid per-frame work.
54
+ * `MultiAnimation` uses this live value for sequence/stagger triggering so
55
+ * delayed WAAPI startup is never mistaken for elapsed animation time.
56
56
  */
57
57
  abstract get progress(): number;
58
58
  /**
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Do not let one delayed rendering opportunity consume an unbounded amount of
3
+ * animation time while startup is still being stabilized. A 30 Hz display is
4
+ * still a normal cadence, so only gaps larger than two nominal 60 Hz frames
5
+ * are treated as catch-up.
6
+ */
7
+ export declare const MAX_FRAME_DELTA: number;
8
+ export declare const STABLE_FRAME_THRESHOLD: number;
9
+ export type FrameTick = {
10
+ /** Frame time used by frame-paced animation drivers. */
11
+ delta: number;
12
+ /** Actual gap between rendering opportunities. */
13
+ rawDelta: number;
14
+ };
15
+ type FramePhase = "drive" | "observe";
16
+ type FrameCallback = (tick: FrameTick) => void;
17
+ /**
18
+ * One requestAnimationFrame loop shared by animation drivers and composition
19
+ * observers. Drivers always run first so observers see the pose that will be
20
+ * painted for the current rendering opportunity.
21
+ */
22
+ declare class FrameScheduler {
23
+ private drivers;
24
+ private observers;
25
+ private frameRequest;
26
+ private previousTimestamp;
27
+ subscribe(callback: FrameCallback, phase?: FramePhase): () => void;
28
+ private requestFrame;
29
+ private tick;
30
+ private runPhase;
31
+ private hasCallbacks;
32
+ private stopIfIdle;
33
+ }
34
+ export declare const frameScheduler: FrameScheduler;
35
+ export {};
36
+ //# sourceMappingURL=frame-scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-scheduler.d.ts","sourceRoot":"","sources":["../../src/lib/animation/frame-scheduler.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAY,CAAC;AACzC,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D,MAAM,MAAM,SAAS,GAAG;IACtB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,KAAK,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AACtC,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;AAE/C;;;;GAIG;AACH,cAAM,cAAc;IAClB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,iBAAiB,CAAuB;IAEhD,SAAS,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,GAAE,UAAoB,GAAG,MAAM,IAAI;IAW3E,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,IAAI,CAkBV;IAEF,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;CAWnB;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
@@ -29,7 +29,7 @@ export declare class MultiAnimation extends Animation {
29
29
  private startAt;
30
30
  private pendingComplete;
31
31
  private running;
32
- private pendingStartTimers;
32
+ private pendingStartObservers;
33
33
  constructor(children: Animation[], opts?: MultiAnimationOptions);
34
34
  play(): void;
35
35
  reverse(): void;
@@ -47,7 +47,8 @@ export declare class MultiAnimation extends Animation {
47
47
  set playbackRate(rate: number);
48
48
  private startRun;
49
49
  private scheduleStart;
50
- private clearPendingStartTimers;
50
+ private hasReachedThreshold;
51
+ private clearPendingStartObservers;
51
52
  private handleChildComplete;
52
53
  private handleFinished;
53
54
  findTimeForProgress(_threshold: number): number | null;
@@ -1 +1 @@
1
- {"version":3,"file":"multi-animation.d.ts","sourceRoot":"","sources":["../../src/lib/animation/multi-animation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,qBAAa,cAAe,SAAQ,SAAS;IAC3C,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,kBAAkB,CAAuC;gBAErD,QAAQ,EAAE,SAAS,EAAE,EAAE,IAAI,GAAE,qBAA0B;IAgBnE,IAAI,IAAI,IAAI;IAIZ,OAAO,IAAI,IAAI;IAIf,KAAK,IAAI,IAAI;IAMb,QAAQ,IAAI,IAAI;IAOhB,IAAI,QAAQ,IAAI,MAAM,CAKrB;IAED,OAAO,IAAI,IAAI,EAAE;IAIjB,WAAW,IAAI,QAAQ,EAAE;IAIzB,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI;IAO/B,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,IAAI,QAAQ,IAAI,OAAO,CAKtB;IACD,IAAI,UAAU,IAAI,OAAO,CAExB;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,EAG5B;IAID,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,cAAc;IAMtB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAOvD"}
1
+ {"version":3,"file":"multi-animation.d.ts","sourceRoot":"","sources":["../../src/lib/animation/multi-animation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,qBAAa,cAAe,SAAQ,SAAS;IAC3C,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,qBAAqB,CAAyB;gBAE1C,QAAQ,EAAE,SAAS,EAAE,EAAE,IAAI,GAAE,qBAA0B;IAgBnE,IAAI,IAAI,IAAI;IAIZ,OAAO,IAAI,IAAI;IAIf,KAAK,IAAI,IAAI;IAMb,QAAQ,IAAI,IAAI;IAOhB,IAAI,QAAQ,IAAI,MAAM,CAKrB;IAED,OAAO,IAAI,IAAI,EAAE;IAIjB,WAAW,IAAI,QAAQ,EAAE;IAIzB,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI;IAO/B,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,IAAI,QAAQ,IAAI,OAAO,CAKtB;IACD,IAAI,UAAU,IAAI,OAAO,CAExB;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,EAG5B;IAID,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,0BAA0B;IAKlC,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,cAAc;IAMtB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAOvD"}
@@ -19,9 +19,16 @@ export interface WebAnimationOptions {
19
19
  * Lifecycle:
20
20
  * 1. `play()` / `reverse()` calls `simulate()` from the current (position,
21
21
  * velocity) toward the target bound, producing a frame list.
22
- * 2. Frames are converted to WAAPI keyframes; `element.animate(...)` is armed
23
- * at 0 ms, waits for the browser's pending setup, then starts.
24
- * 3. While playing, `getPose()` interpolates the live position from frames
22
+ * 2. Frames are converted to WAAPI keyframes; `element.animate(...)` is held
23
+ * at 0 ms until the pending pause is acknowledged and the browser has had
24
+ * a rendering opportunity.
25
+ * 3. Startup is advanced by a shared frame clock until two rendering
26
+ * opportunities arrive without a long gap. Delayed mount work during
27
+ * this startup window therefore cannot be charged to the document
28
+ * timeline in one catch-up jump.
29
+ * 4. Playback is handed to native WAAPI once rendering is stable, preserving
30
+ * compositor playback for the remainder of the transition.
31
+ * 5. While playing, `getPose()` interpolates the live position from frames
25
32
  * using WAAPI's `currentTime`, so browser setup latency is not counted as
26
33
  * animation progress.
27
34
  *
@@ -42,6 +49,8 @@ export declare class WebAnimation extends Animation {
42
49
  private waitingForStart;
43
50
  private startReady;
44
51
  private pendingFirstFrame;
52
+ private stopStartupClock;
53
+ private startupStableFrames;
45
54
  private running;
46
55
  private paused;
47
56
  private settled;
@@ -74,7 +83,10 @@ export declare class WebAnimation extends Animation {
74
83
  private clearWaapi;
75
84
  private captureLiveState;
76
85
  private startWhenReady;
77
- private playPreparedWaapi;
86
+ private startFramePacedPlayback;
87
+ private advanceFramePacedStartup;
88
+ private handOffToWaapi;
89
+ private finishFramePacedRun;
78
90
  private applyStyleAt;
79
91
  }
80
92
  //# sourceMappingURL=web-animation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-animation.d.ts","sourceRoot":"","sources":["../../src/lib/animation/web-animation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAiB,MAAM,QAAQ,CAAC;AACzE,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,WAAW,CAAC;IAC7C,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAQD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,YAAa,SAAQ,SAAS;IACzC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,OAAO,CAAwC;IACvD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,EAAE,mBAAmB;IAYrC,IAAI,IAAI,IAAI;IAiBZ,OAAO,IAAI,IAAI;IAQf,KAAK,IAAI,IAAI;IAUb,QAAQ,IAAI,IAAI;IAWhB;;;;;;OAMG;IACH,WAAW,IAAI,IAAI;IAInB,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,UAAU,IAAI,OAAO,CAExB;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,IAAI,QAAQ,IAAI,MAAM,CAMrB;IAED,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAcrD,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,EAG5B;IAED,OAAO,IAAI,IAAI,EAAE;IAcjB,WAAW,IAAI,QAAQ,EAAE;IAczB,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAS9B,OAAO,CAAC,SAAS;IA8DjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,gBAAgB;YASV,cAAc;IAsB5B,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,YAAY;CAQrB"}
1
+ {"version":3,"file":"web-animation.d.ts","sourceRoot":"","sources":["../../src/lib/animation/web-animation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAiB,MAAM,QAAQ,CAAC;AACzE,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAUxC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,WAAW,CAAC;IAC7C,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAQD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,YAAa,SAAQ,SAAS;IACzC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,OAAO,CAAwC;IACvD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,EAAE,mBAAmB;IAYrC,IAAI,IAAI,IAAI;IAiBZ,OAAO,IAAI,IAAI;IAQf,KAAK,IAAI,IAAI;IAYb,QAAQ,IAAI,IAAI;IAWhB;;;;;;OAMG;IACH,WAAW,IAAI,IAAI;IAInB,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,UAAU,IAAI,OAAO,CAExB;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,IAAI,QAAQ,IAAI,MAAM,CAMrB;IAED,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAcrD,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,EAG5B;IAED,OAAO,IAAI,IAAI,EAAE;IAcjB,WAAW,IAAI,QAAQ,EAAE;IAczB,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAS9B,OAAO,CAAC,SAAS;IAiEjB,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,gBAAgB;YASV,cAAc;IAwB5B,OAAO,CAAC,uBAAuB;IA8B/B,OAAO,CAAC,wBAAwB;IAqChC,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,YAAY;CAQrB"}