reframe-video 0.6.23 → 0.6.25
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/.claude-plugin/plugin.json +1 -1
- package/dist/bin.js +91 -66
- package/dist/browserEntry.js +67 -66
- package/dist/cli.js +83 -59
- package/dist/compile-api.js +83 -59
- package/dist/compile.js +83 -59
- package/dist/diff.js +83 -59
- package/dist/frame.js +83 -59
- package/dist/index.js +202 -178
- package/dist/labels.js +83 -59
- package/dist/trace-cli.js +32 -31
- package/package.json +1 -1
- package/skills/reframe/SKILL.md +6 -3
package/dist/compile-api.js
CHANGED
|
@@ -4,7 +4,67 @@ import { readFile } from "node:fs/promises";
|
|
|
4
4
|
import { dirname, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
|
|
7
|
+
// ../core/src/interpolate.ts
|
|
8
|
+
var BACK_C1 = 1.70158;
|
|
9
|
+
var BACK_C2 = BACK_C1 * 1.525;
|
|
10
|
+
var BACK_C3 = BACK_C1 + 1;
|
|
11
|
+
var ELASTIC_C4 = 2 * Math.PI / 3;
|
|
12
|
+
var ELASTIC_C5 = 2 * Math.PI / 4.5;
|
|
13
|
+
function springEase(stiffness, damping, velocity) {
|
|
14
|
+
const K = 5;
|
|
15
|
+
const zeta = Math.min(0.999, Math.max(0.05, damping / (2 * Math.sqrt(Math.max(1e-6, stiffness)))));
|
|
16
|
+
const wd = K / zeta * Math.sqrt(1 - zeta * zeta);
|
|
17
|
+
const coef = (K - velocity) / wd;
|
|
18
|
+
return (u) => {
|
|
19
|
+
if (u <= 0) return 0;
|
|
20
|
+
if (u >= 1) return 1;
|
|
21
|
+
return 1 - Math.exp(-K * u) * (Math.cos(wd * u) + coef * Math.sin(wd * u));
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function easeOutBounce(u) {
|
|
25
|
+
const n1 = 7.5625;
|
|
26
|
+
const d1 = 2.75;
|
|
27
|
+
if (u < 1 / d1) return n1 * u * u;
|
|
28
|
+
if (u < 2 / d1) return n1 * (u -= 1.5 / d1) * u + 0.75;
|
|
29
|
+
if (u < 2.5 / d1) return n1 * (u -= 2.25 / d1) * u + 0.9375;
|
|
30
|
+
return n1 * (u -= 2.625 / d1) * u + 0.984375;
|
|
31
|
+
}
|
|
32
|
+
var EASE_TABLE = {
|
|
33
|
+
linear: (u) => u,
|
|
34
|
+
easeInQuad: (u) => u * u,
|
|
35
|
+
easeOutQuad: (u) => 1 - (1 - u) * (1 - u),
|
|
36
|
+
easeInOutQuad: (u) => u < 0.5 ? 2 * u * u : 1 - (-2 * u + 2) ** 2 / 2,
|
|
37
|
+
easeInCubic: (u) => u ** 3,
|
|
38
|
+
easeOutCubic: (u) => 1 - (1 - u) ** 3,
|
|
39
|
+
easeInOutCubic: (u) => u < 0.5 ? 4 * u ** 3 : 1 - (-2 * u + 2) ** 3 / 2,
|
|
40
|
+
easeInQuart: (u) => u ** 4,
|
|
41
|
+
easeOutQuart: (u) => 1 - (1 - u) ** 4,
|
|
42
|
+
easeInOutQuart: (u) => u < 0.5 ? 8 * u ** 4 : 1 - (-2 * u + 2) ** 4 / 2,
|
|
43
|
+
easeInExpo: (u) => u === 0 ? 0 : 2 ** (10 * u - 10),
|
|
44
|
+
easeOutExpo: (u) => u === 1 ? 1 : 1 - 2 ** (-10 * u),
|
|
45
|
+
easeInOutExpo: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? 2 ** (20 * u - 10) / 2 : (2 - 2 ** (-20 * u + 10)) / 2,
|
|
46
|
+
// --- expressive eases (GSAP's signature feel) — standard Penner equations ---
|
|
47
|
+
// back: overshoots past the target then settles (pop / snap)
|
|
48
|
+
easeInBack: (u) => BACK_C3 * u ** 3 - BACK_C1 * u * u,
|
|
49
|
+
easeOutBack: (u) => 1 + BACK_C3 * (u - 1) ** 3 + BACK_C1 * (u - 1) ** 2,
|
|
50
|
+
easeInOutBack: (u) => u < 0.5 ? (2 * u) ** 2 * ((BACK_C2 + 1) * 2 * u - BACK_C2) / 2 : ((2 * u - 2) ** 2 * ((BACK_C2 + 1) * (2 * u - 2) + BACK_C2) + 2) / 2,
|
|
51
|
+
// elastic: rings around the target before settling (playful spring)
|
|
52
|
+
easeInElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : -(2 ** (10 * u - 10)) * Math.sin((u * 10 - 10.75) * ELASTIC_C4),
|
|
53
|
+
easeOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : 2 ** (-10 * u) * Math.sin((u * 10 - 0.75) * ELASTIC_C4) + 1,
|
|
54
|
+
easeInOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? -(2 ** (20 * u - 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5)) / 2 : 2 ** (-20 * u + 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5) / 2 + 1,
|
|
55
|
+
// bounce: drops and bounces to rest (lands without overshoot)
|
|
56
|
+
easeInBounce: (u) => 1 - easeOutBounce(1 - u),
|
|
57
|
+
easeOutBounce,
|
|
58
|
+
easeInOutBounce: (u) => u < 0.5 ? (1 - easeOutBounce(1 - 2 * u)) / 2 : (1 + easeOutBounce(2 * u - 1)) / 2,
|
|
59
|
+
// damped-spring presets (ζ from damping/(2√stiffness)): 0.5 / 0.30 / 0.90
|
|
60
|
+
spring: springEase(100, 10, 0),
|
|
61
|
+
springBouncy: springEase(180, 8, 0),
|
|
62
|
+
springStiff: springEase(210, 26, 0)
|
|
63
|
+
};
|
|
64
|
+
var EASE_NAMES = Object.keys(EASE_TABLE);
|
|
65
|
+
|
|
7
66
|
// ../core/src/validate.ts
|
|
67
|
+
var EASE_SET = new Set(EASE_NAMES);
|
|
8
68
|
var FX_PROPS = ["blur", "shadowColor", "shadowBlur", "shadowX", "shadowY", "blend"];
|
|
9
69
|
var BLEND_MODES = /* @__PURE__ */ new Set([
|
|
10
70
|
"normal",
|
|
@@ -136,6 +196,26 @@ function validateScene(ir) {
|
|
|
136
196
|
);
|
|
137
197
|
}
|
|
138
198
|
const labels = /* @__PURE__ */ new Set();
|
|
199
|
+
const checkEase = (path2, ease) => {
|
|
200
|
+
if (ease === void 0) return;
|
|
201
|
+
if (typeof ease === "string") {
|
|
202
|
+
if (!EASE_SET.has(ease)) {
|
|
203
|
+
problems.push(`${path2}: unknown ease "${ease}" \u2014 valid: ${EASE_NAMES.join(", ")} (note: there are no *Sine eases)`);
|
|
204
|
+
}
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (typeof ease === "object" && ease !== null) {
|
|
208
|
+
const o = ease;
|
|
209
|
+
if ("spring" in o) return;
|
|
210
|
+
if ("cubicBezier" in o) {
|
|
211
|
+
if (!Array.isArray(o.cubicBezier) || o.cubicBezier.length !== 4) {
|
|
212
|
+
problems.push(`${path2}: ease cubicBezier must be [x1, y1, x2, y2]`);
|
|
213
|
+
}
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
problems.push(`${path2}: invalid ease \u2014 use a name, { spring }, or { cubicBezier: [x1,y1,x2,y2] }`);
|
|
218
|
+
};
|
|
139
219
|
const checkTimeline = (tl, path2) => {
|
|
140
220
|
if ("label" in tl && tl.label !== void 0) {
|
|
141
221
|
if (labels.has(tl.label)) {
|
|
@@ -163,6 +243,7 @@ function validateScene(ir) {
|
|
|
163
243
|
if (tl.duration !== void 0 && tl.duration <= 0) {
|
|
164
244
|
problems.push(`${path2}: to("${tl.state}") duration must be > 0`);
|
|
165
245
|
}
|
|
246
|
+
checkEase(path2, tl.ease);
|
|
166
247
|
for (const id of tl.filter ?? []) {
|
|
167
248
|
if (!nodeById.has(id)) problems.push(`${path2}: filter contains unknown node "${id}"`);
|
|
168
249
|
}
|
|
@@ -172,6 +253,7 @@ function validateScene(ir) {
|
|
|
172
253
|
if (tl.duration !== void 0 && tl.duration <= 0) {
|
|
173
254
|
problems.push(`${path2}: tween duration must be > 0`);
|
|
174
255
|
}
|
|
256
|
+
checkEase(path2, tl.ease);
|
|
175
257
|
break;
|
|
176
258
|
case "motionPath": {
|
|
177
259
|
const node = nodeById.get(tl.target);
|
|
@@ -192,6 +274,7 @@ function validateScene(ir) {
|
|
|
192
274
|
if (tl.curviness !== void 0 && tl.curviness < 0) {
|
|
193
275
|
problems.push(`${path2}: motionPath "${tl.target}" curviness must be >= 0`);
|
|
194
276
|
}
|
|
277
|
+
checkEase(path2, tl.ease);
|
|
195
278
|
break;
|
|
196
279
|
}
|
|
197
280
|
case "wait":
|
|
@@ -318,65 +401,6 @@ function validateComposition(comp) {
|
|
|
318
401
|
// ../core/src/presets.ts
|
|
319
402
|
var SET = 1 / 120;
|
|
320
403
|
|
|
321
|
-
// ../core/src/interpolate.ts
|
|
322
|
-
var BACK_C1 = 1.70158;
|
|
323
|
-
var BACK_C2 = BACK_C1 * 1.525;
|
|
324
|
-
var BACK_C3 = BACK_C1 + 1;
|
|
325
|
-
var ELASTIC_C4 = 2 * Math.PI / 3;
|
|
326
|
-
var ELASTIC_C5 = 2 * Math.PI / 4.5;
|
|
327
|
-
function springEase(stiffness, damping, velocity) {
|
|
328
|
-
const K = 5;
|
|
329
|
-
const zeta = Math.min(0.999, Math.max(0.05, damping / (2 * Math.sqrt(Math.max(1e-6, stiffness)))));
|
|
330
|
-
const wd = K / zeta * Math.sqrt(1 - zeta * zeta);
|
|
331
|
-
const coef = (K - velocity) / wd;
|
|
332
|
-
return (u) => {
|
|
333
|
-
if (u <= 0) return 0;
|
|
334
|
-
if (u >= 1) return 1;
|
|
335
|
-
return 1 - Math.exp(-K * u) * (Math.cos(wd * u) + coef * Math.sin(wd * u));
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
function easeOutBounce(u) {
|
|
339
|
-
const n1 = 7.5625;
|
|
340
|
-
const d1 = 2.75;
|
|
341
|
-
if (u < 1 / d1) return n1 * u * u;
|
|
342
|
-
if (u < 2 / d1) return n1 * (u -= 1.5 / d1) * u + 0.75;
|
|
343
|
-
if (u < 2.5 / d1) return n1 * (u -= 2.25 / d1) * u + 0.9375;
|
|
344
|
-
return n1 * (u -= 2.625 / d1) * u + 0.984375;
|
|
345
|
-
}
|
|
346
|
-
var EASE_TABLE = {
|
|
347
|
-
linear: (u) => u,
|
|
348
|
-
easeInQuad: (u) => u * u,
|
|
349
|
-
easeOutQuad: (u) => 1 - (1 - u) * (1 - u),
|
|
350
|
-
easeInOutQuad: (u) => u < 0.5 ? 2 * u * u : 1 - (-2 * u + 2) ** 2 / 2,
|
|
351
|
-
easeInCubic: (u) => u ** 3,
|
|
352
|
-
easeOutCubic: (u) => 1 - (1 - u) ** 3,
|
|
353
|
-
easeInOutCubic: (u) => u < 0.5 ? 4 * u ** 3 : 1 - (-2 * u + 2) ** 3 / 2,
|
|
354
|
-
easeInQuart: (u) => u ** 4,
|
|
355
|
-
easeOutQuart: (u) => 1 - (1 - u) ** 4,
|
|
356
|
-
easeInOutQuart: (u) => u < 0.5 ? 8 * u ** 4 : 1 - (-2 * u + 2) ** 4 / 2,
|
|
357
|
-
easeInExpo: (u) => u === 0 ? 0 : 2 ** (10 * u - 10),
|
|
358
|
-
easeOutExpo: (u) => u === 1 ? 1 : 1 - 2 ** (-10 * u),
|
|
359
|
-
easeInOutExpo: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? 2 ** (20 * u - 10) / 2 : (2 - 2 ** (-20 * u + 10)) / 2,
|
|
360
|
-
// --- expressive eases (GSAP's signature feel) — standard Penner equations ---
|
|
361
|
-
// back: overshoots past the target then settles (pop / snap)
|
|
362
|
-
easeInBack: (u) => BACK_C3 * u ** 3 - BACK_C1 * u * u,
|
|
363
|
-
easeOutBack: (u) => 1 + BACK_C3 * (u - 1) ** 3 + BACK_C1 * (u - 1) ** 2,
|
|
364
|
-
easeInOutBack: (u) => u < 0.5 ? (2 * u) ** 2 * ((BACK_C2 + 1) * 2 * u - BACK_C2) / 2 : ((2 * u - 2) ** 2 * ((BACK_C2 + 1) * (2 * u - 2) + BACK_C2) + 2) / 2,
|
|
365
|
-
// elastic: rings around the target before settling (playful spring)
|
|
366
|
-
easeInElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : -(2 ** (10 * u - 10)) * Math.sin((u * 10 - 10.75) * ELASTIC_C4),
|
|
367
|
-
easeOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : 2 ** (-10 * u) * Math.sin((u * 10 - 0.75) * ELASTIC_C4) + 1,
|
|
368
|
-
easeInOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? -(2 ** (20 * u - 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5)) / 2 : 2 ** (-20 * u + 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5) / 2 + 1,
|
|
369
|
-
// bounce: drops and bounces to rest (lands without overshoot)
|
|
370
|
-
easeInBounce: (u) => 1 - easeOutBounce(1 - u),
|
|
371
|
-
easeOutBounce,
|
|
372
|
-
easeInOutBounce: (u) => u < 0.5 ? (1 - easeOutBounce(1 - 2 * u)) / 2 : (1 + easeOutBounce(2 * u - 1)) / 2,
|
|
373
|
-
// damped-spring presets (ζ from damping/(2√stiffness)): 0.5 / 0.30 / 0.90
|
|
374
|
-
spring: springEase(100, 10, 0),
|
|
375
|
-
springBouncy: springEase(180, 8, 0),
|
|
376
|
-
springStiff: springEase(210, 26, 0)
|
|
377
|
-
};
|
|
378
|
-
var EASE_NAMES = Object.keys(EASE_TABLE);
|
|
379
|
-
|
|
380
404
|
// ../core/src/evaluate.ts
|
|
381
405
|
var DEG = Math.PI / 180;
|
|
382
406
|
|
package/dist/compile.js
CHANGED
|
@@ -9,7 +9,67 @@ import { readFile } from "node:fs/promises";
|
|
|
9
9
|
import { dirname, resolve } from "node:path";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
11
|
|
|
12
|
+
// ../core/src/interpolate.ts
|
|
13
|
+
var BACK_C1 = 1.70158;
|
|
14
|
+
var BACK_C2 = BACK_C1 * 1.525;
|
|
15
|
+
var BACK_C3 = BACK_C1 + 1;
|
|
16
|
+
var ELASTIC_C4 = 2 * Math.PI / 3;
|
|
17
|
+
var ELASTIC_C5 = 2 * Math.PI / 4.5;
|
|
18
|
+
function springEase(stiffness, damping, velocity) {
|
|
19
|
+
const K = 5;
|
|
20
|
+
const zeta = Math.min(0.999, Math.max(0.05, damping / (2 * Math.sqrt(Math.max(1e-6, stiffness)))));
|
|
21
|
+
const wd = K / zeta * Math.sqrt(1 - zeta * zeta);
|
|
22
|
+
const coef = (K - velocity) / wd;
|
|
23
|
+
return (u) => {
|
|
24
|
+
if (u <= 0) return 0;
|
|
25
|
+
if (u >= 1) return 1;
|
|
26
|
+
return 1 - Math.exp(-K * u) * (Math.cos(wd * u) + coef * Math.sin(wd * u));
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function easeOutBounce(u) {
|
|
30
|
+
const n1 = 7.5625;
|
|
31
|
+
const d1 = 2.75;
|
|
32
|
+
if (u < 1 / d1) return n1 * u * u;
|
|
33
|
+
if (u < 2 / d1) return n1 * (u -= 1.5 / d1) * u + 0.75;
|
|
34
|
+
if (u < 2.5 / d1) return n1 * (u -= 2.25 / d1) * u + 0.9375;
|
|
35
|
+
return n1 * (u -= 2.625 / d1) * u + 0.984375;
|
|
36
|
+
}
|
|
37
|
+
var EASE_TABLE = {
|
|
38
|
+
linear: (u) => u,
|
|
39
|
+
easeInQuad: (u) => u * u,
|
|
40
|
+
easeOutQuad: (u) => 1 - (1 - u) * (1 - u),
|
|
41
|
+
easeInOutQuad: (u) => u < 0.5 ? 2 * u * u : 1 - (-2 * u + 2) ** 2 / 2,
|
|
42
|
+
easeInCubic: (u) => u ** 3,
|
|
43
|
+
easeOutCubic: (u) => 1 - (1 - u) ** 3,
|
|
44
|
+
easeInOutCubic: (u) => u < 0.5 ? 4 * u ** 3 : 1 - (-2 * u + 2) ** 3 / 2,
|
|
45
|
+
easeInQuart: (u) => u ** 4,
|
|
46
|
+
easeOutQuart: (u) => 1 - (1 - u) ** 4,
|
|
47
|
+
easeInOutQuart: (u) => u < 0.5 ? 8 * u ** 4 : 1 - (-2 * u + 2) ** 4 / 2,
|
|
48
|
+
easeInExpo: (u) => u === 0 ? 0 : 2 ** (10 * u - 10),
|
|
49
|
+
easeOutExpo: (u) => u === 1 ? 1 : 1 - 2 ** (-10 * u),
|
|
50
|
+
easeInOutExpo: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? 2 ** (20 * u - 10) / 2 : (2 - 2 ** (-20 * u + 10)) / 2,
|
|
51
|
+
// --- expressive eases (GSAP's signature feel) — standard Penner equations ---
|
|
52
|
+
// back: overshoots past the target then settles (pop / snap)
|
|
53
|
+
easeInBack: (u) => BACK_C3 * u ** 3 - BACK_C1 * u * u,
|
|
54
|
+
easeOutBack: (u) => 1 + BACK_C3 * (u - 1) ** 3 + BACK_C1 * (u - 1) ** 2,
|
|
55
|
+
easeInOutBack: (u) => u < 0.5 ? (2 * u) ** 2 * ((BACK_C2 + 1) * 2 * u - BACK_C2) / 2 : ((2 * u - 2) ** 2 * ((BACK_C2 + 1) * (2 * u - 2) + BACK_C2) + 2) / 2,
|
|
56
|
+
// elastic: rings around the target before settling (playful spring)
|
|
57
|
+
easeInElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : -(2 ** (10 * u - 10)) * Math.sin((u * 10 - 10.75) * ELASTIC_C4),
|
|
58
|
+
easeOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : 2 ** (-10 * u) * Math.sin((u * 10 - 0.75) * ELASTIC_C4) + 1,
|
|
59
|
+
easeInOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? -(2 ** (20 * u - 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5)) / 2 : 2 ** (-20 * u + 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5) / 2 + 1,
|
|
60
|
+
// bounce: drops and bounces to rest (lands without overshoot)
|
|
61
|
+
easeInBounce: (u) => 1 - easeOutBounce(1 - u),
|
|
62
|
+
easeOutBounce,
|
|
63
|
+
easeInOutBounce: (u) => u < 0.5 ? (1 - easeOutBounce(1 - 2 * u)) / 2 : (1 + easeOutBounce(2 * u - 1)) / 2,
|
|
64
|
+
// damped-spring presets (ζ from damping/(2√stiffness)): 0.5 / 0.30 / 0.90
|
|
65
|
+
spring: springEase(100, 10, 0),
|
|
66
|
+
springBouncy: springEase(180, 8, 0),
|
|
67
|
+
springStiff: springEase(210, 26, 0)
|
|
68
|
+
};
|
|
69
|
+
var EASE_NAMES = Object.keys(EASE_TABLE);
|
|
70
|
+
|
|
12
71
|
// ../core/src/validate.ts
|
|
72
|
+
var EASE_SET = new Set(EASE_NAMES);
|
|
13
73
|
var FX_PROPS = ["blur", "shadowColor", "shadowBlur", "shadowX", "shadowY", "blend"];
|
|
14
74
|
var BLEND_MODES = /* @__PURE__ */ new Set([
|
|
15
75
|
"normal",
|
|
@@ -141,6 +201,26 @@ function validateScene(ir) {
|
|
|
141
201
|
);
|
|
142
202
|
}
|
|
143
203
|
const labels = /* @__PURE__ */ new Set();
|
|
204
|
+
const checkEase = (path2, ease) => {
|
|
205
|
+
if (ease === void 0) return;
|
|
206
|
+
if (typeof ease === "string") {
|
|
207
|
+
if (!EASE_SET.has(ease)) {
|
|
208
|
+
problems.push(`${path2}: unknown ease "${ease}" \u2014 valid: ${EASE_NAMES.join(", ")} (note: there are no *Sine eases)`);
|
|
209
|
+
}
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (typeof ease === "object" && ease !== null) {
|
|
213
|
+
const o = ease;
|
|
214
|
+
if ("spring" in o) return;
|
|
215
|
+
if ("cubicBezier" in o) {
|
|
216
|
+
if (!Array.isArray(o.cubicBezier) || o.cubicBezier.length !== 4) {
|
|
217
|
+
problems.push(`${path2}: ease cubicBezier must be [x1, y1, x2, y2]`);
|
|
218
|
+
}
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
problems.push(`${path2}: invalid ease \u2014 use a name, { spring }, or { cubicBezier: [x1,y1,x2,y2] }`);
|
|
223
|
+
};
|
|
144
224
|
const checkTimeline = (tl, path2) => {
|
|
145
225
|
if ("label" in tl && tl.label !== void 0) {
|
|
146
226
|
if (labels.has(tl.label)) {
|
|
@@ -168,6 +248,7 @@ function validateScene(ir) {
|
|
|
168
248
|
if (tl.duration !== void 0 && tl.duration <= 0) {
|
|
169
249
|
problems.push(`${path2}: to("${tl.state}") duration must be > 0`);
|
|
170
250
|
}
|
|
251
|
+
checkEase(path2, tl.ease);
|
|
171
252
|
for (const id of tl.filter ?? []) {
|
|
172
253
|
if (!nodeById.has(id)) problems.push(`${path2}: filter contains unknown node "${id}"`);
|
|
173
254
|
}
|
|
@@ -177,6 +258,7 @@ function validateScene(ir) {
|
|
|
177
258
|
if (tl.duration !== void 0 && tl.duration <= 0) {
|
|
178
259
|
problems.push(`${path2}: tween duration must be > 0`);
|
|
179
260
|
}
|
|
261
|
+
checkEase(path2, tl.ease);
|
|
180
262
|
break;
|
|
181
263
|
case "motionPath": {
|
|
182
264
|
const node = nodeById.get(tl.target);
|
|
@@ -197,6 +279,7 @@ function validateScene(ir) {
|
|
|
197
279
|
if (tl.curviness !== void 0 && tl.curviness < 0) {
|
|
198
280
|
problems.push(`${path2}: motionPath "${tl.target}" curviness must be >= 0`);
|
|
199
281
|
}
|
|
282
|
+
checkEase(path2, tl.ease);
|
|
200
283
|
break;
|
|
201
284
|
}
|
|
202
285
|
case "wait":
|
|
@@ -293,65 +376,6 @@ function validateScene(ir) {
|
|
|
293
376
|
// ../core/src/presets.ts
|
|
294
377
|
var SET = 1 / 120;
|
|
295
378
|
|
|
296
|
-
// ../core/src/interpolate.ts
|
|
297
|
-
var BACK_C1 = 1.70158;
|
|
298
|
-
var BACK_C2 = BACK_C1 * 1.525;
|
|
299
|
-
var BACK_C3 = BACK_C1 + 1;
|
|
300
|
-
var ELASTIC_C4 = 2 * Math.PI / 3;
|
|
301
|
-
var ELASTIC_C5 = 2 * Math.PI / 4.5;
|
|
302
|
-
function springEase(stiffness, damping, velocity) {
|
|
303
|
-
const K = 5;
|
|
304
|
-
const zeta = Math.min(0.999, Math.max(0.05, damping / (2 * Math.sqrt(Math.max(1e-6, stiffness)))));
|
|
305
|
-
const wd = K / zeta * Math.sqrt(1 - zeta * zeta);
|
|
306
|
-
const coef = (K - velocity) / wd;
|
|
307
|
-
return (u) => {
|
|
308
|
-
if (u <= 0) return 0;
|
|
309
|
-
if (u >= 1) return 1;
|
|
310
|
-
return 1 - Math.exp(-K * u) * (Math.cos(wd * u) + coef * Math.sin(wd * u));
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
function easeOutBounce(u) {
|
|
314
|
-
const n1 = 7.5625;
|
|
315
|
-
const d1 = 2.75;
|
|
316
|
-
if (u < 1 / d1) return n1 * u * u;
|
|
317
|
-
if (u < 2 / d1) return n1 * (u -= 1.5 / d1) * u + 0.75;
|
|
318
|
-
if (u < 2.5 / d1) return n1 * (u -= 2.25 / d1) * u + 0.9375;
|
|
319
|
-
return n1 * (u -= 2.625 / d1) * u + 0.984375;
|
|
320
|
-
}
|
|
321
|
-
var EASE_TABLE = {
|
|
322
|
-
linear: (u) => u,
|
|
323
|
-
easeInQuad: (u) => u * u,
|
|
324
|
-
easeOutQuad: (u) => 1 - (1 - u) * (1 - u),
|
|
325
|
-
easeInOutQuad: (u) => u < 0.5 ? 2 * u * u : 1 - (-2 * u + 2) ** 2 / 2,
|
|
326
|
-
easeInCubic: (u) => u ** 3,
|
|
327
|
-
easeOutCubic: (u) => 1 - (1 - u) ** 3,
|
|
328
|
-
easeInOutCubic: (u) => u < 0.5 ? 4 * u ** 3 : 1 - (-2 * u + 2) ** 3 / 2,
|
|
329
|
-
easeInQuart: (u) => u ** 4,
|
|
330
|
-
easeOutQuart: (u) => 1 - (1 - u) ** 4,
|
|
331
|
-
easeInOutQuart: (u) => u < 0.5 ? 8 * u ** 4 : 1 - (-2 * u + 2) ** 4 / 2,
|
|
332
|
-
easeInExpo: (u) => u === 0 ? 0 : 2 ** (10 * u - 10),
|
|
333
|
-
easeOutExpo: (u) => u === 1 ? 1 : 1 - 2 ** (-10 * u),
|
|
334
|
-
easeInOutExpo: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? 2 ** (20 * u - 10) / 2 : (2 - 2 ** (-20 * u + 10)) / 2,
|
|
335
|
-
// --- expressive eases (GSAP's signature feel) — standard Penner equations ---
|
|
336
|
-
// back: overshoots past the target then settles (pop / snap)
|
|
337
|
-
easeInBack: (u) => BACK_C3 * u ** 3 - BACK_C1 * u * u,
|
|
338
|
-
easeOutBack: (u) => 1 + BACK_C3 * (u - 1) ** 3 + BACK_C1 * (u - 1) ** 2,
|
|
339
|
-
easeInOutBack: (u) => u < 0.5 ? (2 * u) ** 2 * ((BACK_C2 + 1) * 2 * u - BACK_C2) / 2 : ((2 * u - 2) ** 2 * ((BACK_C2 + 1) * (2 * u - 2) + BACK_C2) + 2) / 2,
|
|
340
|
-
// elastic: rings around the target before settling (playful spring)
|
|
341
|
-
easeInElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : -(2 ** (10 * u - 10)) * Math.sin((u * 10 - 10.75) * ELASTIC_C4),
|
|
342
|
-
easeOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : 2 ** (-10 * u) * Math.sin((u * 10 - 0.75) * ELASTIC_C4) + 1,
|
|
343
|
-
easeInOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? -(2 ** (20 * u - 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5)) / 2 : 2 ** (-20 * u + 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5) / 2 + 1,
|
|
344
|
-
// bounce: drops and bounces to rest (lands without overshoot)
|
|
345
|
-
easeInBounce: (u) => 1 - easeOutBounce(1 - u),
|
|
346
|
-
easeOutBounce,
|
|
347
|
-
easeInOutBounce: (u) => u < 0.5 ? (1 - easeOutBounce(1 - 2 * u)) / 2 : (1 + easeOutBounce(2 * u - 1)) / 2,
|
|
348
|
-
// damped-spring presets (ζ from damping/(2√stiffness)): 0.5 / 0.30 / 0.90
|
|
349
|
-
spring: springEase(100, 10, 0),
|
|
350
|
-
springBouncy: springEase(180, 8, 0),
|
|
351
|
-
springStiff: springEase(210, 26, 0)
|
|
352
|
-
};
|
|
353
|
-
var EASE_NAMES = Object.keys(EASE_TABLE);
|
|
354
|
-
|
|
355
379
|
// ../core/src/evaluate.ts
|
|
356
380
|
var DEG = Math.PI / 180;
|
|
357
381
|
|
package/dist/diff.js
CHANGED
|
@@ -337,7 +337,67 @@ function compileScene(ir) {
|
|
|
337
337
|
};
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
+
// ../core/src/interpolate.ts
|
|
341
|
+
var BACK_C1 = 1.70158;
|
|
342
|
+
var BACK_C2 = BACK_C1 * 1.525;
|
|
343
|
+
var BACK_C3 = BACK_C1 + 1;
|
|
344
|
+
var ELASTIC_C4 = 2 * Math.PI / 3;
|
|
345
|
+
var ELASTIC_C5 = 2 * Math.PI / 4.5;
|
|
346
|
+
function springEase(stiffness, damping, velocity) {
|
|
347
|
+
const K = 5;
|
|
348
|
+
const zeta = Math.min(0.999, Math.max(0.05, damping / (2 * Math.sqrt(Math.max(1e-6, stiffness)))));
|
|
349
|
+
const wd = K / zeta * Math.sqrt(1 - zeta * zeta);
|
|
350
|
+
const coef = (K - velocity) / wd;
|
|
351
|
+
return (u) => {
|
|
352
|
+
if (u <= 0) return 0;
|
|
353
|
+
if (u >= 1) return 1;
|
|
354
|
+
return 1 - Math.exp(-K * u) * (Math.cos(wd * u) + coef * Math.sin(wd * u));
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
function easeOutBounce(u) {
|
|
358
|
+
const n1 = 7.5625;
|
|
359
|
+
const d1 = 2.75;
|
|
360
|
+
if (u < 1 / d1) return n1 * u * u;
|
|
361
|
+
if (u < 2 / d1) return n1 * (u -= 1.5 / d1) * u + 0.75;
|
|
362
|
+
if (u < 2.5 / d1) return n1 * (u -= 2.25 / d1) * u + 0.9375;
|
|
363
|
+
return n1 * (u -= 2.625 / d1) * u + 0.984375;
|
|
364
|
+
}
|
|
365
|
+
var EASE_TABLE = {
|
|
366
|
+
linear: (u) => u,
|
|
367
|
+
easeInQuad: (u) => u * u,
|
|
368
|
+
easeOutQuad: (u) => 1 - (1 - u) * (1 - u),
|
|
369
|
+
easeInOutQuad: (u) => u < 0.5 ? 2 * u * u : 1 - (-2 * u + 2) ** 2 / 2,
|
|
370
|
+
easeInCubic: (u) => u ** 3,
|
|
371
|
+
easeOutCubic: (u) => 1 - (1 - u) ** 3,
|
|
372
|
+
easeInOutCubic: (u) => u < 0.5 ? 4 * u ** 3 : 1 - (-2 * u + 2) ** 3 / 2,
|
|
373
|
+
easeInQuart: (u) => u ** 4,
|
|
374
|
+
easeOutQuart: (u) => 1 - (1 - u) ** 4,
|
|
375
|
+
easeInOutQuart: (u) => u < 0.5 ? 8 * u ** 4 : 1 - (-2 * u + 2) ** 4 / 2,
|
|
376
|
+
easeInExpo: (u) => u === 0 ? 0 : 2 ** (10 * u - 10),
|
|
377
|
+
easeOutExpo: (u) => u === 1 ? 1 : 1 - 2 ** (-10 * u),
|
|
378
|
+
easeInOutExpo: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? 2 ** (20 * u - 10) / 2 : (2 - 2 ** (-20 * u + 10)) / 2,
|
|
379
|
+
// --- expressive eases (GSAP's signature feel) — standard Penner equations ---
|
|
380
|
+
// back: overshoots past the target then settles (pop / snap)
|
|
381
|
+
easeInBack: (u) => BACK_C3 * u ** 3 - BACK_C1 * u * u,
|
|
382
|
+
easeOutBack: (u) => 1 + BACK_C3 * (u - 1) ** 3 + BACK_C1 * (u - 1) ** 2,
|
|
383
|
+
easeInOutBack: (u) => u < 0.5 ? (2 * u) ** 2 * ((BACK_C2 + 1) * 2 * u - BACK_C2) / 2 : ((2 * u - 2) ** 2 * ((BACK_C2 + 1) * (2 * u - 2) + BACK_C2) + 2) / 2,
|
|
384
|
+
// elastic: rings around the target before settling (playful spring)
|
|
385
|
+
easeInElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : -(2 ** (10 * u - 10)) * Math.sin((u * 10 - 10.75) * ELASTIC_C4),
|
|
386
|
+
easeOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : 2 ** (-10 * u) * Math.sin((u * 10 - 0.75) * ELASTIC_C4) + 1,
|
|
387
|
+
easeInOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? -(2 ** (20 * u - 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5)) / 2 : 2 ** (-20 * u + 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5) / 2 + 1,
|
|
388
|
+
// bounce: drops and bounces to rest (lands without overshoot)
|
|
389
|
+
easeInBounce: (u) => 1 - easeOutBounce(1 - u),
|
|
390
|
+
easeOutBounce,
|
|
391
|
+
easeInOutBounce: (u) => u < 0.5 ? (1 - easeOutBounce(1 - 2 * u)) / 2 : (1 + easeOutBounce(2 * u - 1)) / 2,
|
|
392
|
+
// damped-spring presets (ζ from damping/(2√stiffness)): 0.5 / 0.30 / 0.90
|
|
393
|
+
spring: springEase(100, 10, 0),
|
|
394
|
+
springBouncy: springEase(180, 8, 0),
|
|
395
|
+
springStiff: springEase(210, 26, 0)
|
|
396
|
+
};
|
|
397
|
+
var EASE_NAMES = Object.keys(EASE_TABLE);
|
|
398
|
+
|
|
340
399
|
// ../core/src/validate.ts
|
|
400
|
+
var EASE_SET = new Set(EASE_NAMES);
|
|
341
401
|
var FX_PROPS = ["blur", "shadowColor", "shadowBlur", "shadowX", "shadowY", "blend"];
|
|
342
402
|
var BLEND_MODES = /* @__PURE__ */ new Set([
|
|
343
403
|
"normal",
|
|
@@ -469,6 +529,26 @@ function validateScene(ir) {
|
|
|
469
529
|
);
|
|
470
530
|
}
|
|
471
531
|
const labels = /* @__PURE__ */ new Set();
|
|
532
|
+
const checkEase = (path2, ease) => {
|
|
533
|
+
if (ease === void 0) return;
|
|
534
|
+
if (typeof ease === "string") {
|
|
535
|
+
if (!EASE_SET.has(ease)) {
|
|
536
|
+
problems.push(`${path2}: unknown ease "${ease}" \u2014 valid: ${EASE_NAMES.join(", ")} (note: there are no *Sine eases)`);
|
|
537
|
+
}
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
if (typeof ease === "object" && ease !== null) {
|
|
541
|
+
const o = ease;
|
|
542
|
+
if ("spring" in o) return;
|
|
543
|
+
if ("cubicBezier" in o) {
|
|
544
|
+
if (!Array.isArray(o.cubicBezier) || o.cubicBezier.length !== 4) {
|
|
545
|
+
problems.push(`${path2}: ease cubicBezier must be [x1, y1, x2, y2]`);
|
|
546
|
+
}
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
problems.push(`${path2}: invalid ease \u2014 use a name, { spring }, or { cubicBezier: [x1,y1,x2,y2] }`);
|
|
551
|
+
};
|
|
472
552
|
const checkTimeline = (tl, path2) => {
|
|
473
553
|
if ("label" in tl && tl.label !== void 0) {
|
|
474
554
|
if (labels.has(tl.label)) {
|
|
@@ -496,6 +576,7 @@ function validateScene(ir) {
|
|
|
496
576
|
if (tl.duration !== void 0 && tl.duration <= 0) {
|
|
497
577
|
problems.push(`${path2}: to("${tl.state}") duration must be > 0`);
|
|
498
578
|
}
|
|
579
|
+
checkEase(path2, tl.ease);
|
|
499
580
|
for (const id of tl.filter ?? []) {
|
|
500
581
|
if (!nodeById.has(id)) problems.push(`${path2}: filter contains unknown node "${id}"`);
|
|
501
582
|
}
|
|
@@ -505,6 +586,7 @@ function validateScene(ir) {
|
|
|
505
586
|
if (tl.duration !== void 0 && tl.duration <= 0) {
|
|
506
587
|
problems.push(`${path2}: tween duration must be > 0`);
|
|
507
588
|
}
|
|
589
|
+
checkEase(path2, tl.ease);
|
|
508
590
|
break;
|
|
509
591
|
case "motionPath": {
|
|
510
592
|
const node = nodeById.get(tl.target);
|
|
@@ -525,6 +607,7 @@ function validateScene(ir) {
|
|
|
525
607
|
if (tl.curviness !== void 0 && tl.curviness < 0) {
|
|
526
608
|
problems.push(`${path2}: motionPath "${tl.target}" curviness must be >= 0`);
|
|
527
609
|
}
|
|
610
|
+
checkEase(path2, tl.ease);
|
|
528
611
|
break;
|
|
529
612
|
}
|
|
530
613
|
case "wait":
|
|
@@ -651,65 +734,6 @@ function validateComposition(comp) {
|
|
|
651
734
|
// ../core/src/presets.ts
|
|
652
735
|
var SET = 1 / 120;
|
|
653
736
|
|
|
654
|
-
// ../core/src/interpolate.ts
|
|
655
|
-
var BACK_C1 = 1.70158;
|
|
656
|
-
var BACK_C2 = BACK_C1 * 1.525;
|
|
657
|
-
var BACK_C3 = BACK_C1 + 1;
|
|
658
|
-
var ELASTIC_C4 = 2 * Math.PI / 3;
|
|
659
|
-
var ELASTIC_C5 = 2 * Math.PI / 4.5;
|
|
660
|
-
function springEase(stiffness, damping, velocity) {
|
|
661
|
-
const K = 5;
|
|
662
|
-
const zeta = Math.min(0.999, Math.max(0.05, damping / (2 * Math.sqrt(Math.max(1e-6, stiffness)))));
|
|
663
|
-
const wd = K / zeta * Math.sqrt(1 - zeta * zeta);
|
|
664
|
-
const coef = (K - velocity) / wd;
|
|
665
|
-
return (u) => {
|
|
666
|
-
if (u <= 0) return 0;
|
|
667
|
-
if (u >= 1) return 1;
|
|
668
|
-
return 1 - Math.exp(-K * u) * (Math.cos(wd * u) + coef * Math.sin(wd * u));
|
|
669
|
-
};
|
|
670
|
-
}
|
|
671
|
-
function easeOutBounce(u) {
|
|
672
|
-
const n1 = 7.5625;
|
|
673
|
-
const d1 = 2.75;
|
|
674
|
-
if (u < 1 / d1) return n1 * u * u;
|
|
675
|
-
if (u < 2 / d1) return n1 * (u -= 1.5 / d1) * u + 0.75;
|
|
676
|
-
if (u < 2.5 / d1) return n1 * (u -= 2.25 / d1) * u + 0.9375;
|
|
677
|
-
return n1 * (u -= 2.625 / d1) * u + 0.984375;
|
|
678
|
-
}
|
|
679
|
-
var EASE_TABLE = {
|
|
680
|
-
linear: (u) => u,
|
|
681
|
-
easeInQuad: (u) => u * u,
|
|
682
|
-
easeOutQuad: (u) => 1 - (1 - u) * (1 - u),
|
|
683
|
-
easeInOutQuad: (u) => u < 0.5 ? 2 * u * u : 1 - (-2 * u + 2) ** 2 / 2,
|
|
684
|
-
easeInCubic: (u) => u ** 3,
|
|
685
|
-
easeOutCubic: (u) => 1 - (1 - u) ** 3,
|
|
686
|
-
easeInOutCubic: (u) => u < 0.5 ? 4 * u ** 3 : 1 - (-2 * u + 2) ** 3 / 2,
|
|
687
|
-
easeInQuart: (u) => u ** 4,
|
|
688
|
-
easeOutQuart: (u) => 1 - (1 - u) ** 4,
|
|
689
|
-
easeInOutQuart: (u) => u < 0.5 ? 8 * u ** 4 : 1 - (-2 * u + 2) ** 4 / 2,
|
|
690
|
-
easeInExpo: (u) => u === 0 ? 0 : 2 ** (10 * u - 10),
|
|
691
|
-
easeOutExpo: (u) => u === 1 ? 1 : 1 - 2 ** (-10 * u),
|
|
692
|
-
easeInOutExpo: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? 2 ** (20 * u - 10) / 2 : (2 - 2 ** (-20 * u + 10)) / 2,
|
|
693
|
-
// --- expressive eases (GSAP's signature feel) — standard Penner equations ---
|
|
694
|
-
// back: overshoots past the target then settles (pop / snap)
|
|
695
|
-
easeInBack: (u) => BACK_C3 * u ** 3 - BACK_C1 * u * u,
|
|
696
|
-
easeOutBack: (u) => 1 + BACK_C3 * (u - 1) ** 3 + BACK_C1 * (u - 1) ** 2,
|
|
697
|
-
easeInOutBack: (u) => u < 0.5 ? (2 * u) ** 2 * ((BACK_C2 + 1) * 2 * u - BACK_C2) / 2 : ((2 * u - 2) ** 2 * ((BACK_C2 + 1) * (2 * u - 2) + BACK_C2) + 2) / 2,
|
|
698
|
-
// elastic: rings around the target before settling (playful spring)
|
|
699
|
-
easeInElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : -(2 ** (10 * u - 10)) * Math.sin((u * 10 - 10.75) * ELASTIC_C4),
|
|
700
|
-
easeOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : 2 ** (-10 * u) * Math.sin((u * 10 - 0.75) * ELASTIC_C4) + 1,
|
|
701
|
-
easeInOutElastic: (u) => u === 0 ? 0 : u === 1 ? 1 : u < 0.5 ? -(2 ** (20 * u - 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5)) / 2 : 2 ** (-20 * u + 10) * Math.sin((20 * u - 11.125) * ELASTIC_C5) / 2 + 1,
|
|
702
|
-
// bounce: drops and bounces to rest (lands without overshoot)
|
|
703
|
-
easeInBounce: (u) => 1 - easeOutBounce(1 - u),
|
|
704
|
-
easeOutBounce,
|
|
705
|
-
easeInOutBounce: (u) => u < 0.5 ? (1 - easeOutBounce(1 - 2 * u)) / 2 : (1 + easeOutBounce(2 * u - 1)) / 2,
|
|
706
|
-
// damped-spring presets (ζ from damping/(2√stiffness)): 0.5 / 0.30 / 0.90
|
|
707
|
-
spring: springEase(100, 10, 0),
|
|
708
|
-
springBouncy: springEase(180, 8, 0),
|
|
709
|
-
springStiff: springEase(210, 26, 0)
|
|
710
|
-
};
|
|
711
|
-
var EASE_NAMES = Object.keys(EASE_TABLE);
|
|
712
|
-
|
|
713
737
|
// ../core/src/evaluate.ts
|
|
714
738
|
var DEG = Math.PI / 180;
|
|
715
739
|
|