egaki 0.6.0 → 0.7.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 +140 -9
- package/dist/cli/cache-utils.d.ts +33 -0
- package/dist/cli/cache-utils.d.ts.map +1 -0
- package/dist/cli/cache-utils.js +157 -0
- package/dist/cli/cached-generate.d.ts +105 -0
- package/dist/cli/cached-generate.d.ts.map +1 -0
- package/dist/cli/cached-generate.js +208 -0
- package/dist/cli/cached-generate.test.d.ts +11 -0
- package/dist/cli/cached-generate.test.d.ts.map +1 -0
- package/dist/cli/cached-generate.test.js +431 -0
- package/dist/cli/cartesia-provider.d.ts +16 -0
- package/dist/cli/cartesia-provider.d.ts.map +1 -0
- package/dist/cli/cartesia-provider.js +184 -0
- package/dist/cli/chatgpt-auth.d.ts.map +1 -0
- package/dist/cli/cli.d.ts +4 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/{cli.js → cli/cli.js} +626 -600
- package/dist/cli/clone-generate.d.ts +26 -0
- package/dist/cli/clone-generate.d.ts.map +1 -0
- package/dist/cli/clone-generate.js +148 -0
- package/dist/cli/credentials.d.ts.map +1 -0
- package/dist/{credentials.js → cli/credentials.js} +20 -0
- package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
- package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
- package/dist/cli/elevenlabs-speech-provider.js +199 -0
- package/dist/cli/generate.d.ts +140 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +604 -0
- package/dist/cli/generate.test.d.ts +2 -0
- package/dist/cli/generate.test.d.ts.map +1 -0
- package/dist/cli/generate.test.js +131 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +7 -0
- package/dist/{model-catalog.d.ts → cli/model-catalog.d.ts} +6 -0
- package/dist/cli/model-catalog.d.ts.map +1 -0
- package/dist/{model-catalog.js → cli/model-catalog.js} +714 -4
- package/dist/{models.d.ts → cli/models.d.ts} +12 -5
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/{models.js → cli/models.js} +58 -57
- package/dist/cli/open-browser.d.ts.map +1 -0
- package/dist/cli/openai-speech-provider.d.ts +3 -0
- package/dist/cli/openai-speech-provider.d.ts.map +1 -0
- package/dist/cli/openai-speech-provider.js +28 -0
- package/dist/cli/separation-generate.d.ts +34 -0
- package/dist/cli/separation-generate.d.ts.map +1 -0
- package/dist/cli/separation-generate.js +117 -0
- package/dist/cli/speech-catalog.d.ts +35 -0
- package/dist/cli/speech-catalog.d.ts.map +1 -0
- package/dist/cli/speech-catalog.js +195 -0
- package/dist/cli/speech-generate.d.ts +86 -0
- package/dist/cli/speech-generate.d.ts.map +1 -0
- package/dist/cli/speech-generate.js +156 -0
- package/dist/cli/speech-models.d.ts +8 -0
- package/dist/cli/speech-models.d.ts.map +1 -0
- package/dist/cli/speech-models.js +109 -0
- package/dist/cli/speech-provider.test.d.ts +2 -0
- package/dist/cli/speech-provider.test.d.ts.map +1 -0
- package/dist/cli/speech-provider.test.js +197 -0
- package/dist/cli/subscription.d.ts.map +1 -0
- package/dist/cli/transcription-catalog.d.ts +35 -0
- package/dist/cli/transcription-catalog.d.ts.map +1 -0
- package/dist/cli/transcription-catalog.js +192 -0
- package/dist/cli/transcription-generate.d.ts +62 -0
- package/dist/cli/transcription-generate.d.ts.map +1 -0
- package/dist/cli/transcription-generate.js +144 -0
- package/dist/cli/transcription-models.d.ts +9 -0
- package/dist/cli/transcription-models.d.ts.map +1 -0
- package/dist/cli/transcription-models.js +100 -0
- package/dist/cli/transcription-providers.d.ts +22 -0
- package/dist/cli/transcription-providers.d.ts.map +1 -0
- package/dist/cli/transcription-providers.js +290 -0
- package/dist/cli/video-model-catalog.d.ts.map +1 -0
- package/dist/cli/xai-auth.d.ts.map +1 -0
- package/dist/{xai-auth.js → cli/xai-auth.js} +1 -1
- package/dist/vite/angled-screen.d.ts +57 -0
- package/dist/vite/angled-screen.d.ts.map +1 -0
- package/dist/vite/angled-screen.js +115 -0
- package/dist/vite/app.d.ts +51 -0
- package/dist/vite/app.d.ts.map +1 -0
- package/dist/vite/app.js +150 -0
- package/dist/vite/bands-shader.d.ts +47 -0
- package/dist/vite/bands-shader.d.ts.map +1 -0
- package/dist/vite/bands-shader.js +267 -0
- package/dist/vite/code-block.d.ts +107 -0
- package/dist/vite/code-block.d.ts.map +1 -0
- package/dist/vite/code-block.js +641 -0
- package/dist/vite/components.d.ts +36 -0
- package/dist/vite/components.d.ts.map +1 -0
- package/dist/vite/components.js +113 -0
- package/dist/vite/dispersion-rings-shader.d.ts +44 -0
- package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
- package/dist/vite/dispersion-rings-shader.js +282 -0
- package/dist/vite/easing-curves.d.ts +129 -0
- package/dist/vite/easing-curves.d.ts.map +1 -0
- package/dist/vite/easing-curves.js +584 -0
- package/dist/vite/easing-curves.test.d.ts +2 -0
- package/dist/vite/easing-curves.test.d.ts.map +1 -0
- package/dist/vite/easing-curves.test.js +200 -0
- package/dist/vite/generated-media-client.d.ts +35 -0
- package/dist/vite/generated-media-client.d.ts.map +1 -0
- package/dist/vite/generated-media-client.js +76 -0
- package/dist/vite/keyframes.d.ts +129 -0
- package/dist/vite/keyframes.d.ts.map +1 -0
- package/dist/vite/keyframes.js +194 -0
- package/dist/vite/layout-editor.d.ts +45 -0
- package/dist/vite/layout-editor.d.ts.map +1 -0
- package/dist/vite/layout-editor.js +587 -0
- package/dist/vite/layout-transition.d.ts +136 -0
- package/dist/vite/layout-transition.d.ts.map +1 -0
- package/dist/vite/layout-transition.js +581 -0
- package/dist/vite/liquid-gradient-shader.d.ts +62 -0
- package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
- package/dist/vite/liquid-gradient-shader.js +413 -0
- package/dist/vite/mdx-client.d.ts +15 -0
- package/dist/vite/mdx-client.d.ts.map +1 -0
- package/dist/vite/mdx-client.js +265 -0
- package/dist/vite/mdx-parse.d.ts +102 -0
- package/dist/vite/mdx-parse.d.ts.map +1 -0
- package/dist/vite/mdx-parse.js +251 -0
- package/dist/vite/mdx-provided-components.d.ts +18 -0
- package/dist/vite/mdx-provided-components.d.ts.map +1 -0
- package/dist/vite/mdx-provided-components.js +14 -0
- package/dist/vite/mdx-video.d.ts +327 -0
- package/dist/vite/mdx-video.d.ts.map +1 -0
- package/dist/vite/mdx-video.js +596 -0
- package/dist/vite/mdx-video.test.d.ts +9 -0
- package/dist/vite/mdx-video.test.d.ts.map +1 -0
- package/dist/vite/mdx-video.test.js +1945 -0
- package/dist/vite/media-components.d.ts +45 -0
- package/dist/vite/media-components.d.ts.map +1 -0
- package/dist/vite/media-components.js +355 -0
- package/dist/vite/media-duration-store.d.ts +66 -0
- package/dist/vite/media-duration-store.d.ts.map +1 -0
- package/dist/vite/media-duration-store.js +204 -0
- package/dist/vite/player-page.d.ts +35 -0
- package/dist/vite/player-page.d.ts.map +1 -0
- package/dist/vite/player-page.js +720 -0
- package/dist/vite/render-client.d.ts +18 -0
- package/dist/vite/render-client.d.ts.map +1 -0
- package/dist/vite/render-client.js +67 -0
- package/dist/vite/sdk.d.ts +221 -0
- package/dist/vite/sdk.d.ts.map +1 -0
- package/dist/vite/sdk.js +355 -0
- package/dist/vite/server-components.d.ts +55 -0
- package/dist/vite/server-components.d.ts.map +1 -0
- package/dist/vite/server-components.js +156 -0
- package/dist/vite/server-mdx.d.ts +74 -0
- package/dist/vite/server-mdx.d.ts.map +1 -0
- package/dist/vite/server-mdx.js +259 -0
- package/dist/vite/shader-renderer.d.ts +48 -0
- package/dist/vite/shader-renderer.d.ts.map +1 -0
- package/dist/vite/shader-renderer.js +411 -0
- package/dist/vite/store-hooks.d.ts +12 -0
- package/dist/vite/store-hooks.d.ts.map +1 -0
- package/dist/vite/store-hooks.js +93 -0
- package/dist/vite/store.d.ts +75 -0
- package/dist/vite/store.d.ts.map +1 -0
- package/dist/vite/store.js +52 -0
- package/dist/vite/store.test.d.ts +6 -0
- package/dist/vite/store.test.d.ts.map +1 -0
- package/dist/vite/store.test.js +172 -0
- package/dist/vite/tweakpane-hook.d.ts +94 -0
- package/dist/vite/tweakpane-hook.d.ts.map +1 -0
- package/dist/vite/tweakpane-hook.js +450 -0
- package/dist/vite/vite-plugin.d.ts +28 -0
- package/dist/vite/vite-plugin.d.ts.map +1 -0
- package/dist/vite/vite-plugin.js +538 -0
- package/dist/vite/wave-gradient-shader.d.ts +41 -0
- package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
- package/dist/vite/wave-gradient-shader.js +207 -0
- package/package.json +101 -24
- package/skills/egaki/SKILL.md +162 -1
- package/src/cli/cache-utils.ts +169 -0
- package/src/cli/cached-generate.test.ts +531 -0
- package/src/cli/cached-generate.ts +348 -0
- package/src/cli/cartesia-provider.ts +249 -0
- package/src/{cli.ts → cli/cli.ts} +836 -884
- package/src/cli/clone-generate.ts +202 -0
- package/src/{credentials.ts → cli/credentials.ts} +20 -0
- package/src/cli/elevenlabs-speech-provider.ts +243 -0
- package/src/cli/generate.test.ts +166 -0
- package/src/cli/generate.ts +912 -0
- package/src/cli/main.ts +8 -0
- package/src/{model-catalog.ts → cli/model-catalog.ts} +787 -58
- package/src/{models.ts → cli/models.ts} +65 -86
- package/src/cli/openai-speech-provider.ts +34 -0
- package/src/cli/separation-generate.ts +187 -0
- package/src/cli/speech-catalog.ts +253 -0
- package/src/cli/speech-generate.ts +275 -0
- package/src/cli/speech-models.ts +146 -0
- package/src/cli/speech-provider.test.ts +226 -0
- package/src/cli/transcription-catalog.ts +250 -0
- package/src/cli/transcription-generate.ts +214 -0
- package/src/cli/transcription-models.ts +136 -0
- package/src/cli/transcription-providers.ts +427 -0
- package/src/{xai-auth.ts → cli/xai-auth.ts} +1 -1
- package/src/vite/angled-screen.tsx +214 -0
- package/src/vite/app.tsx +197 -0
- package/src/vite/bands-shader.tsx +319 -0
- package/src/vite/code-block.tsx +939 -0
- package/src/vite/components.tsx +278 -0
- package/src/vite/dispersion-rings-shader.tsx +331 -0
- package/src/vite/easing-curves.test.ts +232 -0
- package/src/vite/easing-curves.ts +743 -0
- package/src/vite/generated-media-client.tsx +121 -0
- package/src/vite/keyframes.tsx +347 -0
- package/src/vite/layout-editor.tsx +709 -0
- package/src/vite/layout-transition.tsx +706 -0
- package/src/vite/liquid-gradient-shader.tsx +474 -0
- package/src/vite/mdx-client.tsx +420 -0
- package/src/vite/mdx-parse.ts +343 -0
- package/src/vite/mdx-provided-components.ts +19 -0
- package/src/vite/mdx-video.test.tsx +2219 -0
- package/src/vite/mdx-video.tsx +976 -0
- package/src/vite/media-components.tsx +473 -0
- package/src/vite/media-duration-store.ts +225 -0
- package/src/vite/motion-timing.ts +194 -0
- package/src/vite/player-page.tsx +1107 -0
- package/src/vite/render-client.ts +84 -0
- package/src/vite/sdk.ts +598 -0
- package/src/vite/server-components.tsx +241 -0
- package/src/vite/server-mdx.ts +285 -0
- package/src/vite/shader-renderer.tsx +535 -0
- package/src/vite/store-hooks.ts +117 -0
- package/src/vite/store.test.ts +202 -0
- package/src/vite/store.ts +115 -0
- package/src/vite/styles.css +21 -0
- package/src/vite/tweakpane-hook.tsx +593 -0
- package/src/vite/virtual-modules.d.ts +30 -0
- package/src/vite/vite-plugin.ts +584 -0
- package/src/vite/wave-gradient-shader.tsx +253 -0
- package/README.md +0 -370
- package/dist/antigravity-auth.d.ts +0 -15
- package/dist/antigravity-auth.d.ts.map +0 -1
- package/dist/antigravity-auth.js +0 -544
- package/dist/antigravity-image.d.ts +0 -11
- package/dist/antigravity-image.d.ts.map +0 -1
- package/dist/antigravity-image.js +0 -285
- package/dist/chatgpt-auth.d.ts.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/credentials.d.ts.map +0 -1
- package/dist/gateway-model-candidates.generated.d.ts +0 -11
- package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
- package/dist/gateway-model-candidates.generated.js +0 -64
- package/dist/login.d.ts.map +0 -1
- package/dist/model-catalog.d.ts.map +0 -1
- package/dist/models.d.ts.map +0 -1
- package/dist/open-browser.d.ts.map +0 -1
- package/dist/subscription.d.ts.map +0 -1
- package/dist/video-model-catalog.d.ts.map +0 -1
- package/dist/xai-auth.d.ts.map +0 -1
- /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
- /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
- /package/dist/{credentials.d.ts → cli/credentials.d.ts} +0 -0
- /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
- /package/dist/{login.js → cli/login.js} +0 -0
- /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
- /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
- /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
- /package/dist/{subscription.js → cli/subscription.js} +0 -0
- /package/dist/{video-model-catalog.d.ts → cli/video-model-catalog.d.ts} +0 -0
- /package/dist/{video-model-catalog.js → cli/video-model-catalog.js} +0 -0
- /package/dist/{xai-auth.d.ts → cli/xai-auth.d.ts} +0 -0
- /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
- /package/src/{login.ts → cli/login.ts} +0 -0
- /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
- /package/src/{subscription.ts → cli/subscription.ts} +0 -0
- /package/src/{video-model-catalog.ts → cli/video-model-catalog.ts} +0 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Easing curve engine for spring/bounce/overshoot presets.
|
|
3
|
+
*
|
|
4
|
+
* Ported from Jitter's easing engine (jitter.video webpack bundle,
|
|
5
|
+
* module 78102). The presets were previously stored as hardcoded sample
|
|
6
|
+
* arrays extracted from Jitter; they are now generated from the same
|
|
7
|
+
* three primitives Jitter uses:
|
|
8
|
+
*
|
|
9
|
+
* 1. Polybezier paths: control points with handles, linearly interpolated
|
|
10
|
+
* between intensity configs (d3-interpolate semantics), each segment
|
|
11
|
+
* evaluated with an analytic (Cardano) cubic-bezier y(x) solver.
|
|
12
|
+
* 2. Spring physics (elasticSnap): semi-implicit Euler, step 0.005,
|
|
13
|
+
* settle epsilon 1e-10, timeline truncated at 34% of settle time.
|
|
14
|
+
* 3. Bounce physics: explicit Euler, step 1, gravity 9.8e-6, velocity
|
|
15
|
+
* flipped and scaled by bounceFactor when crossing position 100,
|
|
16
|
+
* capped at 16 bounces.
|
|
17
|
+
*
|
|
18
|
+
* Each `*Samples` export contains 51 evenly-spaced points (t=0 to t=1)
|
|
19
|
+
* per intensity level (0, 25, 50, 75, 100), rounded to 4 decimals exactly
|
|
20
|
+
* like Jitter does. The generated values are verified against the original
|
|
21
|
+
* extracted arrays in easing-curves.test.ts. Values can exceed the 0-1
|
|
22
|
+
* range for overshoot and bounce effects.
|
|
23
|
+
*
|
|
24
|
+
* Porting lessons (do not "simplify" these or the outputs change):
|
|
25
|
+
* - Lerp must be `a * (1 - t) + b * t` (d3-interpolate form), not
|
|
26
|
+
* `a + (b - a) * t`, to stay bit-identical with Jitter's output.
|
|
27
|
+
* - The intensity pair search keeps the LOWER key on distance ties
|
|
28
|
+
* (strict `<` in the reduce), so intensity 25 lerps configs 0..50.
|
|
29
|
+
* - Spring acceleration must keep Jitter's exact expression order:
|
|
30
|
+
* `(-tension * (pos - 100) + -friction * v) / mass`.
|
|
31
|
+
* - Rounding is `Math.round((x + Number.EPSILON) * 1e4) / 1e4`.
|
|
32
|
+
*/
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Cubic bezier y(x) solver — analytic Cardano roots
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
const identity = (e) => e;
|
|
37
|
+
/** Solve the cubic for the bezier parameter via Cardano's formula. */
|
|
38
|
+
function cardano(e, t, n, r, i) {
|
|
39
|
+
const { cbrt, sqrt, PI } = Math;
|
|
40
|
+
const o = t + n * e;
|
|
41
|
+
const a = o ** 2 + r;
|
|
42
|
+
if (a > 0) {
|
|
43
|
+
const root = sqrt(a);
|
|
44
|
+
return cbrt(o + root) + cbrt(o - root) - i;
|
|
45
|
+
}
|
|
46
|
+
const s = cbrt(sqrt(o * o - a));
|
|
47
|
+
const c = o ? Math.atan(sqrt(-a) / o) : -PI / 2;
|
|
48
|
+
const u = n < 0
|
|
49
|
+
? (o > 0 ? 2 * PI : PI) - c
|
|
50
|
+
: i < 0
|
|
51
|
+
? (o > 0 ? 2 * PI : -3 * PI) + c
|
|
52
|
+
: (o > 0 ? 0 : PI) + c;
|
|
53
|
+
return 2 * s * Math.cos(u / 3) - i;
|
|
54
|
+
}
|
|
55
|
+
/** Evaluate the cubic bezier polynomial at parameter e. */
|
|
56
|
+
const evalCubic = (e, t, n, r) => ((t * e + 3 * n) * e + r) * e;
|
|
57
|
+
/** Symbol key for attaching bezier control points to easing functions. */
|
|
58
|
+
export const BEZIER_POINTS = Symbol.for('egaki:bezierPoints');
|
|
59
|
+
/**
|
|
60
|
+
* cubic-bezier(x1, y1, x2, y2) as a y(x) function. x1/x2 must be in [0, 1];
|
|
61
|
+
* y values may exceed [0, 1] for overshoot.
|
|
62
|
+
*
|
|
63
|
+
* The returned function has a `[BEZIER_POINTS]` property with the original
|
|
64
|
+
* `[x1, y1, x2, y2]` tuple so the tweakpane bezier blade can show and edit
|
|
65
|
+
* the exact curve.
|
|
66
|
+
*/
|
|
67
|
+
export function cubicBezier(x1, y1, x2, y2) {
|
|
68
|
+
if (!(0 <= x1 && x1 <= 1 && 0 <= x2 && x2 <= 1)) {
|
|
69
|
+
throw new Error('Bezier x values must be in [0, 1] range');
|
|
70
|
+
}
|
|
71
|
+
if (x1 === y1 && x2 === y2) {
|
|
72
|
+
const fn = identity;
|
|
73
|
+
fn[BEZIER_POINTS] = [x1, y1, x2, y2];
|
|
74
|
+
return fn;
|
|
75
|
+
}
|
|
76
|
+
const i = 6 * (3 * x1 - 3 * x2 + 1);
|
|
77
|
+
const o = 6 * (x2 - 2 * x1);
|
|
78
|
+
const a = 3 * x1;
|
|
79
|
+
const s = i * i;
|
|
80
|
+
const c = o * o;
|
|
81
|
+
const u = o / i;
|
|
82
|
+
const l = (3 * o * a) / s - (c * o) / (s * i);
|
|
83
|
+
const d = (2 * a) / i - c / s;
|
|
84
|
+
const f = d * d * d;
|
|
85
|
+
const p = 3 / i;
|
|
86
|
+
const h = 3 * y1 - 3 * y2 + 1;
|
|
87
|
+
const m = y2 - 2 * y1;
|
|
88
|
+
const y = 3 * y1;
|
|
89
|
+
const solve = i ? cardano : identity;
|
|
90
|
+
const fn = ((e) => 0 === e || 1 === e ? e : evalCubic(solve(e, l, p, f, u), h, m, y));
|
|
91
|
+
fn[BEZIER_POINTS] = [x1, y1, x2, y2];
|
|
92
|
+
return fn;
|
|
93
|
+
}
|
|
94
|
+
function normalizeHandle(h) {
|
|
95
|
+
if (h === undefined)
|
|
96
|
+
return undefined;
|
|
97
|
+
return typeof h === 'number' ? { x: h, y: 0 } : h;
|
|
98
|
+
}
|
|
99
|
+
/** Scale a handle fraction by the x-distance to the neighbor anchor. */
|
|
100
|
+
function scaleHandle(dx, h) {
|
|
101
|
+
const n = normalizeHandle(h);
|
|
102
|
+
if (n === undefined)
|
|
103
|
+
return undefined;
|
|
104
|
+
// `+ 0` normalizes -0 (e.g. handle x of 0 scaled by a negative dx), like Jitter.
|
|
105
|
+
return [n.x * dx + 0, n.y * dx + 0];
|
|
106
|
+
}
|
|
107
|
+
/** Build a y(x) easing function from polybezier control points. */
|
|
108
|
+
export function polybezier(points) {
|
|
109
|
+
const pts = points.map((pt, n) => {
|
|
110
|
+
const out = { p: [pt.x, pt.y] };
|
|
111
|
+
const next = points[n + 1];
|
|
112
|
+
const prev = points[n - 1];
|
|
113
|
+
if (n !== 0 && pt.lower !== undefined) {
|
|
114
|
+
out.lower = scaleHandle(prev.x - pt.x, pt.lower);
|
|
115
|
+
}
|
|
116
|
+
if (n !== points.length - 1 && pt.upper !== undefined) {
|
|
117
|
+
out.upper = scaleHandle(next.x - pt.x, pt.upper);
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
});
|
|
121
|
+
// One bezier per segment; null when the segment is degenerate (dx or dy 0).
|
|
122
|
+
const segments = [];
|
|
123
|
+
{
|
|
124
|
+
let prev = pts[0];
|
|
125
|
+
for (let o = 1; o < pts.length; o++) {
|
|
126
|
+
const cur = pts[o];
|
|
127
|
+
const dx = cur.p[0] - prev.p[0];
|
|
128
|
+
const dy = cur.p[1] - prev.p[1];
|
|
129
|
+
const out = prev.upper || [0, 0];
|
|
130
|
+
const inc = cur.lower || [0, 0];
|
|
131
|
+
if (dx && dy) {
|
|
132
|
+
segments.push(cubicBezier(out[0] / dx, out[1] / dy, 1 + inc[0] / dx, 1 + inc[1] / dy));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
segments.push(null);
|
|
136
|
+
}
|
|
137
|
+
prev = cur;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return function (x) {
|
|
141
|
+
let before;
|
|
142
|
+
let point = pts[0];
|
|
143
|
+
let o = 0;
|
|
144
|
+
for (o = 0; o < pts.length; o++) {
|
|
145
|
+
point = pts[o];
|
|
146
|
+
if (x < point.p[0])
|
|
147
|
+
break;
|
|
148
|
+
if (x === point.p[0])
|
|
149
|
+
return point.p[1];
|
|
150
|
+
before = point;
|
|
151
|
+
}
|
|
152
|
+
const anchorX = point.p[0];
|
|
153
|
+
if (!before || x > anchorX) {
|
|
154
|
+
// Extrapolate beyond the endpoints along the boundary handle.
|
|
155
|
+
const handle = (x > anchorX && point.upper) || (x < anchorX && point.lower);
|
|
156
|
+
return (point.p[1] +
|
|
157
|
+
(handle && 0 !== handle[1] ? ((x - anchorX) * handle[1]) / handle[0] : 0));
|
|
158
|
+
}
|
|
159
|
+
const segment = segments[o - 1];
|
|
160
|
+
if (!segment)
|
|
161
|
+
return before.p[1];
|
|
162
|
+
const dx = point.p[0] - before.p[0];
|
|
163
|
+
const dy = point.p[1] - before.p[1];
|
|
164
|
+
return before.p[1] + dy * segment((x - before.p[0]) / dx);
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/** Pick the two configs bracketing `t` and the local interpolation factor. */
|
|
168
|
+
function findIntensityPair(configs, t) {
|
|
169
|
+
const keys = Object.keys(configs)
|
|
170
|
+
.map(Number)
|
|
171
|
+
.sort((a, b) => a - b);
|
|
172
|
+
if (keys.length < 2)
|
|
173
|
+
throw new Error('Too few items to find a pair.');
|
|
174
|
+
// On distance ties the reduce keeps the LOWER key (strict <), matching Jitter.
|
|
175
|
+
const nearest = keys.reduce((e, n) => (Math.abs(n - t) < Math.abs(e - t) ? n : e));
|
|
176
|
+
const o = keys.indexOf(nearest);
|
|
177
|
+
let pair;
|
|
178
|
+
if (nearest < t)
|
|
179
|
+
pair = [nearest, keys[o + 1]];
|
|
180
|
+
else if (nearest > t)
|
|
181
|
+
pair = [keys[o - 1], nearest];
|
|
182
|
+
else
|
|
183
|
+
pair = 0 === o ? [nearest, keys[o + 1]] : [keys[o - 1], nearest];
|
|
184
|
+
return {
|
|
185
|
+
adjustedIntensity: (t - pair[0]) / (pair[1] - pair[0]),
|
|
186
|
+
pair: [configs[pair[0]], configs[pair[1]]],
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/** d3-interpolate number form: a*(1-t) + b*t. Order matters for FP exactness. */
|
|
190
|
+
const lerpNumber = (a, b, t) => a * (1 - t) + b * t;
|
|
191
|
+
function lerpHandle(a, b, t) {
|
|
192
|
+
if (a === undefined || b === undefined)
|
|
193
|
+
return b;
|
|
194
|
+
return { x: lerpNumber(a.x, b.x, t), y: lerpNumber(a.y, b.y, t) };
|
|
195
|
+
}
|
|
196
|
+
function lerpControlPoints(a, b, t) {
|
|
197
|
+
return b.map((pb, i) => {
|
|
198
|
+
const pa = a[i];
|
|
199
|
+
return {
|
|
200
|
+
x: lerpNumber(pa.x, pb.x, t),
|
|
201
|
+
y: lerpNumber(pa.y, pb.y, t),
|
|
202
|
+
lower: lerpHandle(normalizeHandle(pa.lower), normalizeHandle(pb.lower), t),
|
|
203
|
+
upper: lerpHandle(normalizeHandle(pa.upper), normalizeHandle(pb.upper), t),
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
/** Polybezier preset parameterized by intensity. */
|
|
208
|
+
export function pathPreset(configs) {
|
|
209
|
+
return (intensity) => {
|
|
210
|
+
const { adjustedIntensity, pair } = findIntensityPair(configs, intensity);
|
|
211
|
+
return polybezier(lerpControlPoints(pair[0], pair[1], adjustedIntensity));
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Integrate a 1D physics simulation and return an easing function that maps
|
|
216
|
+
* t in [0, 1] onto the (possibly truncated) recorded timeline, normalized by
|
|
217
|
+
* the final position.
|
|
218
|
+
*/
|
|
219
|
+
function physicsEasing(config) {
|
|
220
|
+
const { integrationType = 'semi-implicit', getAcceleration, isFinished, applySideEffects, v0, step = 1, sliceIndexRatio = 1, } = config;
|
|
221
|
+
const state = { position: 0, velocity: v0 };
|
|
222
|
+
const timeline = [0];
|
|
223
|
+
const advance = (dt) => {
|
|
224
|
+
const a = getAcceleration(state.position, state.velocity);
|
|
225
|
+
if ('semi-implicit' === integrationType) {
|
|
226
|
+
state.velocity = state.velocity + a * dt;
|
|
227
|
+
state.position = state.position + state.velocity * dt;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
state.position = state.position + state.velocity * dt;
|
|
231
|
+
state.velocity = state.velocity + a * dt;
|
|
232
|
+
}
|
|
233
|
+
if (applySideEffects !== undefined) {
|
|
234
|
+
const next = applySideEffects(state, dt);
|
|
235
|
+
state.position = next.position;
|
|
236
|
+
state.velocity = next.velocity;
|
|
237
|
+
}
|
|
238
|
+
timeline.push(state.position);
|
|
239
|
+
};
|
|
240
|
+
let previous = { ...state };
|
|
241
|
+
for (advance(step); !isFinished(previous, state);) {
|
|
242
|
+
previous = { ...state };
|
|
243
|
+
advance(step);
|
|
244
|
+
}
|
|
245
|
+
const lastIndex = Math.floor((timeline.length - 1) * sliceIndexRatio);
|
|
246
|
+
const finalPosition = config.finalPosition ?? timeline[timeline.length - 1];
|
|
247
|
+
return (t) => {
|
|
248
|
+
const idx = t * lastIndex;
|
|
249
|
+
const lo = Math.floor(idx);
|
|
250
|
+
let position;
|
|
251
|
+
if (lo === timeline.length - 1)
|
|
252
|
+
position = timeline[lo];
|
|
253
|
+
else {
|
|
254
|
+
const a = timeline[lo];
|
|
255
|
+
position = a + (timeline[lo + 1] - a) * (idx - lo);
|
|
256
|
+
}
|
|
257
|
+
return position / finalPosition;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const SPRING_TARGET = 100;
|
|
261
|
+
const SPRING_EPSILON = 1e-10;
|
|
262
|
+
function springEasing(config) {
|
|
263
|
+
const { mass, tension, friction, v0 } = config;
|
|
264
|
+
return physicsEasing({
|
|
265
|
+
v0,
|
|
266
|
+
getAcceleration: (position, velocity) => (-tension * (position - SPRING_TARGET) + -friction * velocity) / mass,
|
|
267
|
+
isFinished: (previous, current) => Math.abs(current.velocity) < SPRING_EPSILON &&
|
|
268
|
+
Math.abs(current.position - SPRING_TARGET) < SPRING_EPSILON,
|
|
269
|
+
finalPosition: SPRING_TARGET,
|
|
270
|
+
step: 0.005,
|
|
271
|
+
sliceIndexRatio: 0.34,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function lerpSpringConfig(a, b, t) {
|
|
275
|
+
return {
|
|
276
|
+
mass: lerpNumber(a.mass, b.mass, t),
|
|
277
|
+
tension: lerpNumber(a.tension, b.tension, t),
|
|
278
|
+
friction: lerpNumber(a.friction, b.friction, t),
|
|
279
|
+
v0: lerpNumber(a.v0, b.v0, t),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/** Spring preset parameterized by intensity. */
|
|
283
|
+
export function springPreset(configs) {
|
|
284
|
+
return (intensity) => {
|
|
285
|
+
const { adjustedIntensity, pair } = findIntensityPair(configs, intensity);
|
|
286
|
+
return springEasing(lerpSpringConfig(pair[0], pair[1], adjustedIntensity));
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
const BOUNCE_TARGET = 100;
|
|
290
|
+
const BOUNCE_EPSILON = 1e-4;
|
|
291
|
+
const GRAVITY = 9.8 / 1e6;
|
|
292
|
+
function bounceEasing(config) {
|
|
293
|
+
const { mass, bounceFactor, friction, v0 } = config;
|
|
294
|
+
let bounces = 0;
|
|
295
|
+
return physicsEasing({
|
|
296
|
+
v0,
|
|
297
|
+
step: 1,
|
|
298
|
+
integrationType: 'explicit',
|
|
299
|
+
finalPosition: BOUNCE_TARGET,
|
|
300
|
+
getAcceleration: (position, velocity) => (GRAVITY * mass + -friction * velocity) / mass,
|
|
301
|
+
isFinished: (previous, current) => (Math.abs(current.velocity) < BOUNCE_EPSILON &&
|
|
302
|
+
Math.abs(current.position - BOUNCE_TARGET) < BOUNCE_EPSILON) ||
|
|
303
|
+
bounces > 15,
|
|
304
|
+
applySideEffects: (state, dt) => {
|
|
305
|
+
const { position, velocity } = state;
|
|
306
|
+
if (position < BOUNCE_TARGET)
|
|
307
|
+
return state;
|
|
308
|
+
// Time elapsed since crossing the floor within this step.
|
|
309
|
+
const overshootTime = dt - Math.abs(position - BOUNCE_TARGET) / Math.abs(velocity);
|
|
310
|
+
const bounceVelocity = -velocity * bounceFactor;
|
|
311
|
+
bounces += 1;
|
|
312
|
+
return {
|
|
313
|
+
position: BOUNCE_TARGET + overshootTime * bounceVelocity,
|
|
314
|
+
velocity: bounceVelocity,
|
|
315
|
+
};
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
function lerpBounceConfig(a, b, t) {
|
|
320
|
+
return {
|
|
321
|
+
mass: lerpNumber(a.mass, b.mass, t),
|
|
322
|
+
bounceFactor: lerpNumber(a.bounceFactor, b.bounceFactor, t),
|
|
323
|
+
friction: lerpNumber(a.friction, b.friction, t),
|
|
324
|
+
v0: lerpNumber(a.v0, b.v0, t),
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/** Bounce preset parameterized by intensity. */
|
|
328
|
+
export function bouncePreset(configs) {
|
|
329
|
+
return (intensity) => {
|
|
330
|
+
const { adjustedIntensity, pair } = findIntensityPair(configs, intensity);
|
|
331
|
+
return bounceEasing(lerpBounceConfig(pair[0], pair[1], adjustedIntensity));
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
/** Round to 4 decimals like Jitter; normalizes -0 to 0. */
|
|
335
|
+
function round4(value) {
|
|
336
|
+
const rounded = Math.round((value + Number.EPSILON) * 1e4) / 1e4;
|
|
337
|
+
return rounded === 0 ? 0 : rounded;
|
|
338
|
+
}
|
|
339
|
+
/** Sample a preset at 51 evenly spaced points for all 5 intensity levels. */
|
|
340
|
+
export function samplePreset(preset) {
|
|
341
|
+
const out = {};
|
|
342
|
+
for (const intensity of [0, 25, 50, 75, 100]) {
|
|
343
|
+
const easing = preset(intensity);
|
|
344
|
+
out[intensity] = Array.from({ length: 51 }, (_, i) => round4(easing(i / 50)));
|
|
345
|
+
}
|
|
346
|
+
return out;
|
|
347
|
+
}
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
// Jitter preset configs (verbatim from the bundle)
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
/** natural:throw:v1 — anticipate backward, fly past, settle */
|
|
352
|
+
export const naturalThrow = pathPreset({
|
|
353
|
+
0: [
|
|
354
|
+
{ x: 0, y: 0, upper: 0.6 },
|
|
355
|
+
{ x: 0.33, y: -0.1, lower: 0.5, upper: 0.5 },
|
|
356
|
+
{ x: 0.67, y: 1.2, lower: 0.2, upper: 0.2 },
|
|
357
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
358
|
+
],
|
|
359
|
+
50: [
|
|
360
|
+
{ x: 0, y: 0, upper: 0.7 },
|
|
361
|
+
{ x: 0.33, y: -0.2, lower: 0.8, upper: 0.8 },
|
|
362
|
+
{ x: 0.67, y: 1.3, lower: 0.1, upper: 0.1 },
|
|
363
|
+
{ x: 1, y: 1, lower: 0.8 },
|
|
364
|
+
],
|
|
365
|
+
100: [
|
|
366
|
+
{ x: 0, y: 0, upper: 0.8 },
|
|
367
|
+
{ x: 0.33, y: -0.4, lower: 0.9, upper: 0.9 },
|
|
368
|
+
{ x: 0.67, y: 1.5, lower: 0.05, upper: 0.05 },
|
|
369
|
+
{ x: 1, y: 1, lower: 0.9 },
|
|
370
|
+
],
|
|
371
|
+
});
|
|
372
|
+
/** slowdown:overshoot:v1 — decelerate with a single overshoot */
|
|
373
|
+
export const decelerateOvershoot = pathPreset({
|
|
374
|
+
0: [
|
|
375
|
+
{ x: 0, y: 0, upper: 0 },
|
|
376
|
+
{ x: 0.35, y: 1.1, lower: 0.8, upper: 0.2 },
|
|
377
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
378
|
+
],
|
|
379
|
+
50: [
|
|
380
|
+
{ x: 0, y: 0, upper: 0 },
|
|
381
|
+
{ x: 0.3, y: 1.3, lower: 0.8, upper: 0.2 },
|
|
382
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
383
|
+
],
|
|
384
|
+
100: [
|
|
385
|
+
{ x: 0, y: 0, upper: 0 },
|
|
386
|
+
{ x: 0.22, y: 1.5, lower: 1, upper: 0.2 },
|
|
387
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
388
|
+
],
|
|
389
|
+
});
|
|
390
|
+
/** slowdown:elasticOvershoot:v1 — decelerate with elastic overshoot */
|
|
391
|
+
export const decelerateElastic = pathPreset({
|
|
392
|
+
0: [
|
|
393
|
+
{ x: 0, y: 0, upper: 0 },
|
|
394
|
+
{ x: 0.5, y: 1.1, lower: 0.9, upper: 0.3 },
|
|
395
|
+
{ x: 1, y: 1, lower: 0.5 },
|
|
396
|
+
],
|
|
397
|
+
50: [
|
|
398
|
+
{ x: 0, y: 0, upper: 0 },
|
|
399
|
+
{ x: 0.5, y: 1.2, lower: 1, upper: 0.4 },
|
|
400
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
401
|
+
],
|
|
402
|
+
100: [
|
|
403
|
+
{ x: 0, y: 0, upper: { x: 0, y: 0.5 } },
|
|
404
|
+
{ x: 0.5, y: 1.5, lower: 1, upper: 0.7 },
|
|
405
|
+
{ x: 1, y: 1, lower: 0.8 },
|
|
406
|
+
],
|
|
407
|
+
});
|
|
408
|
+
/** accelerate:impulse:v1 — dip backward then accelerate away */
|
|
409
|
+
export const accelerateImpulse = pathPreset({
|
|
410
|
+
0: [
|
|
411
|
+
{ x: 0, y: 0, upper: 0.4 },
|
|
412
|
+
{ x: 0.4, y: -0.1, lower: 0.4, upper: 0.7 },
|
|
413
|
+
{ x: 1, y: 1, lower: 0 },
|
|
414
|
+
],
|
|
415
|
+
50: [
|
|
416
|
+
{ x: 0, y: 0, upper: 0.4 },
|
|
417
|
+
{ x: 0.5, y: -0.2, lower: 0.4, upper: 0.8 },
|
|
418
|
+
{ x: 1, y: 1, lower: 0 },
|
|
419
|
+
],
|
|
420
|
+
100: [
|
|
421
|
+
{ x: 0, y: 0, upper: 0.4 },
|
|
422
|
+
{ x: 0.63, y: -0.5, lower: 0.4, upper: 1 },
|
|
423
|
+
{ x: 1, y: 1, lower: 0 },
|
|
424
|
+
],
|
|
425
|
+
});
|
|
426
|
+
/** accelerate:elastic:v1 — elastic windup then accelerate away */
|
|
427
|
+
export const accelerateElastic = pathPreset({
|
|
428
|
+
0: [
|
|
429
|
+
{ x: 0, y: 0, upper: 0.6 },
|
|
430
|
+
{ x: 0.5, y: -0.1, lower: 0.5, upper: 1 },
|
|
431
|
+
{ x: 1, y: 1, lower: 0 },
|
|
432
|
+
],
|
|
433
|
+
50: [
|
|
434
|
+
{ x: 0, y: 0, upper: 0.7 },
|
|
435
|
+
{ x: 0.5, y: -0.2, lower: 0.6, upper: 1 },
|
|
436
|
+
{ x: 1, y: 1, lower: 0 },
|
|
437
|
+
],
|
|
438
|
+
100: [
|
|
439
|
+
{ x: 0, y: 0, upper: 0.8 },
|
|
440
|
+
{ x: 0.5, y: -0.5, lower: 0.9, upper: 1 },
|
|
441
|
+
{ x: 1, y: 1, lower: { x: 0, y: 0.5 } },
|
|
442
|
+
],
|
|
443
|
+
});
|
|
444
|
+
/** elastic:standard:v1 — spring snap with ringing oscillation */
|
|
445
|
+
export const elasticSnap = springPreset({
|
|
446
|
+
0: { mass: 1, tension: 80, friction: 12.522, v0: 0 },
|
|
447
|
+
50: { mass: 1, tension: 80, friction: 8.944, v0: 0 },
|
|
448
|
+
100: { mass: 1, tension: 80, friction: 4.472, v0: 0 },
|
|
449
|
+
});
|
|
450
|
+
/** bounce:standard:v1 — like a ball dropping */
|
|
451
|
+
export const bounce = bouncePreset({
|
|
452
|
+
0: { mass: 1, bounceFactor: 0.2, friction: 0, v0: 0 },
|
|
453
|
+
50: { mass: 1, bounceFactor: 0.5, friction: 0, v0: 0 },
|
|
454
|
+
100: { mass: 1, bounceFactor: 0.7, friction: 0, v0: 0 },
|
|
455
|
+
});
|
|
456
|
+
/** bounce:anticipate:v1 — pull back first, then bounce into place */
|
|
457
|
+
export const bounceAnticipate = bouncePreset({
|
|
458
|
+
0: { mass: 20, bounceFactor: 0.7, friction: 0.001, v0: -0.05 },
|
|
459
|
+
100: { mass: 2, bounceFactor: 0.5, friction: 0, v0: -0.05 },
|
|
460
|
+
});
|
|
461
|
+
/** bounce:throw:v1 — thrown with initial velocity, bounces on landing */
|
|
462
|
+
export const bounceThrow = bouncePreset({
|
|
463
|
+
0: { mass: 1, bounceFactor: 0.7, friction: 0, v0: 0.02 },
|
|
464
|
+
100: { mass: 1, bounceFactor: 0.3, friction: 0, v0: 0.1 },
|
|
465
|
+
});
|
|
466
|
+
/** impulse:standard:v1 — slow dip then gradual release */
|
|
467
|
+
export const impulseSlow = pathPreset({
|
|
468
|
+
0: [
|
|
469
|
+
{ x: 0, y: 0, upper: 0.3 },
|
|
470
|
+
{ x: 0.17, y: -0.05, lower: 0.25, upper: 0.25 },
|
|
471
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
472
|
+
],
|
|
473
|
+
50: [
|
|
474
|
+
{ x: 0, y: 0, upper: 0.35 },
|
|
475
|
+
{ x: 0.3, y: -0.2, lower: 0.25, upper: 0.25 },
|
|
476
|
+
{ x: 1, y: 1, lower: 0.8 },
|
|
477
|
+
],
|
|
478
|
+
100: [
|
|
479
|
+
{ x: 0, y: 0, upper: 0.5 },
|
|
480
|
+
{ x: 0.47, y: -1, lower: 0.25, upper: 0.25 },
|
|
481
|
+
{ x: 1, y: 1, lower: 1 },
|
|
482
|
+
],
|
|
483
|
+
});
|
|
484
|
+
/** impulseAndOvershoot:standard:v1 — dip backward, overshoot, settle */
|
|
485
|
+
export const impulseOvershoot = pathPreset({
|
|
486
|
+
0: [
|
|
487
|
+
{ x: 0, y: 0, upper: 0.35 },
|
|
488
|
+
{ x: 0.17, y: -0.1, lower: 0.35, upper: 0.4 },
|
|
489
|
+
{ x: 0.67, y: 1.05, lower: 0.65, upper: 0.25 },
|
|
490
|
+
{ x: 1, y: 1, lower: 0.6 },
|
|
491
|
+
],
|
|
492
|
+
50: [
|
|
493
|
+
{ x: 0, y: 0, upper: 0.35 },
|
|
494
|
+
{ x: 0.2, y: -0.2, lower: 0.35, upper: 0.45 },
|
|
495
|
+
{ x: 0.6, y: 1.1, lower: 0.75, upper: 0.25 },
|
|
496
|
+
{ x: 1, y: 1, lower: 0.6 },
|
|
497
|
+
],
|
|
498
|
+
100: [
|
|
499
|
+
{ x: 0, y: 0, upper: 0.35 },
|
|
500
|
+
{ x: 0.27, y: -1, lower: 0.3, upper: 0.6 },
|
|
501
|
+
{ x: 0.47, y: 1.5, lower: 0.9, upper: 0.2 },
|
|
502
|
+
{ x: 1, y: 1, lower: 0.6 },
|
|
503
|
+
],
|
|
504
|
+
});
|
|
505
|
+
/** overshoot:standard:v1 — overshoot then settle back */
|
|
506
|
+
export const overshoot = pathPreset({
|
|
507
|
+
0: [
|
|
508
|
+
{ x: 0, y: 0, upper: 0 },
|
|
509
|
+
{ x: 0.46, y: 1.05, lower: 0.8, upper: 0.2 },
|
|
510
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
511
|
+
],
|
|
512
|
+
50: [
|
|
513
|
+
{ x: 0, y: 0, upper: 0 },
|
|
514
|
+
{ x: 0.25, y: 1.2, lower: 0.8, upper: 0.2 },
|
|
515
|
+
{ x: 1, y: 1, lower: 0.75 },
|
|
516
|
+
],
|
|
517
|
+
100: [
|
|
518
|
+
{ x: 0, y: 0, upper: 0 },
|
|
519
|
+
{ x: 0.15, y: 2, lower: 0.8, upper: 0.1 },
|
|
520
|
+
{ x: 1, y: 1, lower: 0.8 },
|
|
521
|
+
],
|
|
522
|
+
});
|
|
523
|
+
/** overshoot:elastic:v1 — overshoot with elastic ringing */
|
|
524
|
+
export const overshootElastic = pathPreset({
|
|
525
|
+
0: [
|
|
526
|
+
{ x: 0, y: 0, upper: 0.5 },
|
|
527
|
+
{ x: 0.5, y: 1.1, lower: 0.6, upper: 0.4 },
|
|
528
|
+
{ x: 1, y: 1, lower: 0.5 },
|
|
529
|
+
],
|
|
530
|
+
50: [
|
|
531
|
+
{ x: 0, y: 0, upper: 0.7 },
|
|
532
|
+
{ x: 0.5, y: 1.2, lower: 0.8, upper: 0.6 },
|
|
533
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
534
|
+
],
|
|
535
|
+
100: [
|
|
536
|
+
{ x: 0, y: 0, upper: 0.8 },
|
|
537
|
+
{ x: 0.5, y: 1.5, lower: 0.9, upper: 0.7 },
|
|
538
|
+
{ x: 1, y: 1, lower: 0.8 },
|
|
539
|
+
],
|
|
540
|
+
});
|
|
541
|
+
/** overshoot:bouncy:v1 — overshoot with a bouncy settle */
|
|
542
|
+
export const overshootBouncy = pathPreset({
|
|
543
|
+
0: [
|
|
544
|
+
{ x: 0, y: 0, upper: 0.8 },
|
|
545
|
+
{ x: 0.5, y: 1.2, lower: 0.4, upper: 0.2 },
|
|
546
|
+
{ x: 1, y: 1, lower: 0.6 },
|
|
547
|
+
],
|
|
548
|
+
50: [
|
|
549
|
+
{ x: 0, y: 0, upper: 0.9 },
|
|
550
|
+
{ x: 0.5, y: 1.5, lower: 0.2, upper: 0.1 },
|
|
551
|
+
{ x: 1, y: 1, lower: 0.7 },
|
|
552
|
+
],
|
|
553
|
+
100: [
|
|
554
|
+
{ x: 0, y: 0, upper: 1 },
|
|
555
|
+
{ x: 0.5, y: 1.9, lower: 0.1, upper: 0.05 },
|
|
556
|
+
{ x: 1, y: 1, lower: 0.9 },
|
|
557
|
+
],
|
|
558
|
+
});
|
|
559
|
+
// ---------------------------------------------------------------------------
|
|
560
|
+
// Sampled curves — same data as the previously hardcoded arrays
|
|
561
|
+
// ---------------------------------------------------------------------------
|
|
562
|
+
export const naturalThrowSamples = samplePreset(naturalThrow);
|
|
563
|
+
export const decelerateOvershootSamples = samplePreset(decelerateOvershoot);
|
|
564
|
+
export const decelerateElasticSamples = samplePreset(decelerateElastic);
|
|
565
|
+
export const accelerateImpulseSamples = samplePreset(accelerateImpulse);
|
|
566
|
+
export const accelerateElasticSamples = samplePreset(accelerateElastic);
|
|
567
|
+
export const elasticSnapSamples = samplePreset(elasticSnap);
|
|
568
|
+
export const bounceSamples = samplePreset(bounce);
|
|
569
|
+
export const bounceAnticipateSamples = samplePreset(bounceAnticipate);
|
|
570
|
+
export const bounceThrowSamples = samplePreset(bounceThrow);
|
|
571
|
+
export const impulseSlowSamples = samplePreset(impulseSlow);
|
|
572
|
+
export const impulseOvershootSamples = samplePreset(impulseOvershoot);
|
|
573
|
+
export const overshootSamples = samplePreset(overshoot);
|
|
574
|
+
export const overshootElasticSamples = samplePreset(overshootElastic);
|
|
575
|
+
export const overshootBouncySamples = samplePreset(overshootBouncy);
|
|
576
|
+
/** Linearly interpolate a sampled curve at time t (0-1). */
|
|
577
|
+
export function lerpSamples(samples, t) {
|
|
578
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
579
|
+
const idx = clamped * (samples.length - 1);
|
|
580
|
+
const lo = Math.floor(idx);
|
|
581
|
+
const hi = Math.min(lo + 1, samples.length - 1);
|
|
582
|
+
const frac = idx - lo;
|
|
583
|
+
return samples[lo] * (1 - frac) + samples[hi] * frac;
|
|
584
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easing-curves.test.d.ts","sourceRoot":"","sources":["../../src/vite/easing-curves.test.ts"],"names":[],"mappings":""}
|