@pixodesk/svg-animator-web 1.0.15 → 1.0.16
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/dist/index.cjs +2906 -1454
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2375 -337
- package/dist/index.d.ts +2375 -337
- package/dist/index.js +2889 -1454
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.umd.js +2889 -1454
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __pow = Math.pow;
|
|
8
7
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
8
|
var __spreadValues = (a, b) => {
|
|
10
9
|
for (var prop in b || (b = {}))
|
|
@@ -34,29 +33,29 @@ var __objRest = (source, exclude) => {
|
|
|
34
33
|
// src/effects/transformParts.ts
|
|
35
34
|
function partsRecord(part, value, origin) {
|
|
36
35
|
const rec = {};
|
|
37
|
-
if (part === "translate") rec.translate = value;
|
|
38
|
-
else if (part === "rotate") rec.rotate = value;
|
|
36
|
+
if (part === "translate" /* Translate */) rec.translate = value;
|
|
37
|
+
else if (part === "rotate" /* Rotate */) rec.rotate = value;
|
|
39
38
|
else rec.scale = value;
|
|
40
|
-
if (origin && part !== "translate") rec.origin = origin;
|
|
39
|
+
if (origin && part !== "translate" /* Translate */) rec.origin = origin;
|
|
41
40
|
return rec;
|
|
42
41
|
}
|
|
43
42
|
function readAnimatable(raw) {
|
|
44
|
-
if (raw === void 0) return { kind: "absent" };
|
|
45
|
-
if (Array.isArray(raw)) return { kind: "static"
|
|
43
|
+
if (raw === void 0) return { kind: "absent" /* Absent */ };
|
|
44
|
+
if (Array.isArray(raw)) return { kind: "static" /* Static */, value: raw };
|
|
46
45
|
if (typeof raw === "object") {
|
|
47
46
|
const obj = raw;
|
|
48
47
|
if (obj.keyframes) {
|
|
49
|
-
return { kind: "animated"
|
|
48
|
+
return { kind: "animated" /* Animated */, keyframes: obj.keyframes, autoOrient: obj.autoOrient };
|
|
50
49
|
}
|
|
51
|
-
if (obj.value !== void 0) return { kind: "static"
|
|
50
|
+
if (obj.value !== void 0) return { kind: "static" /* Static */, value: obj.value };
|
|
52
51
|
}
|
|
53
|
-
return { kind: "static"
|
|
52
|
+
return { kind: "static" /* Static */, value: raw };
|
|
54
53
|
}
|
|
55
54
|
function readStaticOrigin(raw, ctx) {
|
|
56
55
|
var _a;
|
|
57
56
|
const o = readAnimatable(raw);
|
|
58
|
-
if (o.kind === "absent") return void 0;
|
|
59
|
-
if (o.kind === "static") return o.value;
|
|
57
|
+
if (o.kind === "absent" /* Absent */) return void 0;
|
|
58
|
+
if (o.kind === "static" /* Static */) return o.value;
|
|
60
59
|
ctx.warnings.push("transformation.origin: animated origin approximated by its first keyframe");
|
|
61
60
|
return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
|
|
62
61
|
}
|
|
@@ -74,15 +73,15 @@ function applyTransformationEffect(node, fx, ctx) {
|
|
|
74
73
|
if (!fx) return node;
|
|
75
74
|
delete node.transform;
|
|
76
75
|
let n = node;
|
|
77
|
-
n = wrapTransformPart(n, "skew"
|
|
76
|
+
n = wrapTransformPart(n, "skew" /* Skew */, fx.skew, ctx);
|
|
78
77
|
n = wrapOrigin(
|
|
79
78
|
n,
|
|
80
79
|
fx.origin,
|
|
81
80
|
/*invert=*/
|
|
82
81
|
true
|
|
83
82
|
);
|
|
84
|
-
n = wrapTransformPart(n, "scale"
|
|
85
|
-
n = wrapTransformPart(n, "rotate"
|
|
83
|
+
n = wrapTransformPart(n, "scale" /* Scale */, normalizeScale(fx.scale), ctx);
|
|
84
|
+
n = wrapTransformPart(n, "rotate" /* Rotate */, fx.rotate, ctx);
|
|
86
85
|
n = wrapOrigin(
|
|
87
86
|
n,
|
|
88
87
|
fx.origin,
|
|
@@ -96,7 +95,7 @@ function applyTransformationEffect(node, fx, ctx) {
|
|
|
96
95
|
/*invert=*/
|
|
97
96
|
true
|
|
98
97
|
);
|
|
99
|
-
n = wrapTransformPart(n, "translate"
|
|
98
|
+
n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
|
|
100
99
|
n = wrapOrigin(
|
|
101
100
|
n,
|
|
102
101
|
fx.origin,
|
|
@@ -104,7 +103,7 @@ function applyTransformationEffect(node, fx, ctx) {
|
|
|
104
103
|
false
|
|
105
104
|
);
|
|
106
105
|
} else {
|
|
107
|
-
n = wrapTransformPart(n, "translate"
|
|
106
|
+
n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
|
|
108
107
|
}
|
|
109
108
|
return n;
|
|
110
109
|
}
|
|
@@ -121,19 +120,19 @@ function normalizeScale(raw) {
|
|
|
121
120
|
}
|
|
122
121
|
function wrapTransformPart(inner, part, raw, ctx) {
|
|
123
122
|
if (raw === void 0) return inner;
|
|
124
|
-
if (part === "skew") {
|
|
123
|
+
if (part === "skew" /* Skew */) {
|
|
125
124
|
const skew = readAnimatable(raw);
|
|
126
|
-
if (skew.kind !== "static") {
|
|
125
|
+
if (skew.kind !== "static" /* Static */) {
|
|
127
126
|
ctx.warnings.push("transformation.skew: only static skew is supported");
|
|
128
127
|
return inner;
|
|
129
128
|
}
|
|
130
129
|
return { type: "g", transform: "skewX(" + skew.value[0] + ")skewY(" + skew.value[1] + ")", children: [inner] };
|
|
131
130
|
}
|
|
132
131
|
const v = readAnimatable(raw);
|
|
133
|
-
if (v.kind === "static") {
|
|
132
|
+
if (v.kind === "static" /* Static */) {
|
|
134
133
|
return { type: "g", transform: { value: partsRecord(part, v.value, void 0) }, children: [inner] };
|
|
135
134
|
}
|
|
136
|
-
if (v.kind === "animated") {
|
|
135
|
+
if (v.kind === "animated" /* Animated */) {
|
|
137
136
|
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
|
|
138
137
|
if (v.autoOrient) animTr.autoOrient = true;
|
|
139
138
|
return {
|
|
@@ -148,12 +147,12 @@ function wrapOrigin(inner, raw, invert) {
|
|
|
148
147
|
if (raw === void 0) return inner;
|
|
149
148
|
const v = readAnimatable(raw);
|
|
150
149
|
const sign = (value) => invert ? [-value[0], -value[1]] : value;
|
|
151
|
-
if (v.kind === "absent") return inner;
|
|
152
|
-
if (v.kind === "static") {
|
|
150
|
+
if (v.kind === "absent" /* Absent */) return inner;
|
|
151
|
+
if (v.kind === "static" /* Static */) {
|
|
153
152
|
if (v.value[0] === 0 && v.value[1] === 0) return inner;
|
|
154
153
|
return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
|
|
155
154
|
}
|
|
156
|
-
if (v.kind === "animated") {
|
|
155
|
+
if (v.kind === "animated" /* Animated */) {
|
|
157
156
|
return {
|
|
158
157
|
type: "g",
|
|
159
158
|
animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) } },
|
|
@@ -192,7 +191,7 @@ function splitForContentRef(node, transformation, originalId, innerId, ctx) {
|
|
|
192
191
|
return outerWrapper;
|
|
193
192
|
}
|
|
194
193
|
function liftBodyTranslate(node, transformation) {
|
|
195
|
-
var _a;
|
|
194
|
+
var _a, _b, _c;
|
|
196
195
|
const out = {};
|
|
197
196
|
let didLiftAnimate = false;
|
|
198
197
|
const animTr = (_a = node.animate) == null ? void 0 : _a.transform;
|
|
@@ -243,6 +242,7 @@ function liftBodyTranslate(node, transformation) {
|
|
|
243
242
|
}
|
|
244
243
|
const transformationHasTranslate = (transformation == null ? void 0 : transformation.translate) !== void 0;
|
|
245
244
|
const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
|
|
245
|
+
const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter(((_b = node.animate) == null ? void 0 : _b.transform) || void 0) || didLiftAnimate && needsOriginOnOuter(((_c = out.animate) == null ? void 0 : _c.transform) || void 0);
|
|
246
246
|
if (typeof node.transform === "string") {
|
|
247
247
|
const split = splitTransformString(node.transform);
|
|
248
248
|
if (stripBodyTranslateOnly) {
|
|
@@ -251,6 +251,8 @@ function liftBodyTranslate(node, transformation) {
|
|
|
251
251
|
else delete node.transform;
|
|
252
252
|
} else if (isPureTranslateBody(node.transform)) {
|
|
253
253
|
delete node.transform;
|
|
254
|
+
} else if (liftedAnimateIsAutoOriented && isSingleMatrixBody(node.transform)) {
|
|
255
|
+
delete node.transform;
|
|
254
256
|
}
|
|
255
257
|
} else if (split.translate) {
|
|
256
258
|
out.transform = split.translate;
|
|
@@ -260,6 +262,17 @@ function liftBodyTranslate(node, transformation) {
|
|
|
260
262
|
}
|
|
261
263
|
return out;
|
|
262
264
|
}
|
|
265
|
+
function isSingleMatrixBody(s) {
|
|
266
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
267
|
+
let count = 0;
|
|
268
|
+
let isMatrix = false;
|
|
269
|
+
let m;
|
|
270
|
+
while (m = re.exec(s)) {
|
|
271
|
+
count++;
|
|
272
|
+
if (m[1] === "matrix") isMatrix = true;
|
|
273
|
+
}
|
|
274
|
+
return count === 1 && isMatrix;
|
|
275
|
+
}
|
|
263
276
|
function isPureTranslateBody(s) {
|
|
264
277
|
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
265
278
|
const ops = [];
|
|
@@ -342,294 +355,6 @@ function needsOriginOnOuter(translateAnim) {
|
|
|
342
355
|
return false;
|
|
343
356
|
}
|
|
344
357
|
|
|
345
|
-
// src/effects/util.ts
|
|
346
|
-
function genId(ctx, prefix) {
|
|
347
|
-
return "_lw_" + prefix + "_" + ctx.nextId++;
|
|
348
|
-
}
|
|
349
|
-
function indexById(node, map) {
|
|
350
|
-
var _a;
|
|
351
|
-
if (typeof node.id === "string") map.set(node.id, node);
|
|
352
|
-
(_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
|
|
353
|
-
}
|
|
354
|
-
function spliceDefs(root, defs) {
|
|
355
|
-
if (!defs.length) return;
|
|
356
|
-
const existing = root.children || (root.children = []);
|
|
357
|
-
existing.unshift({ type: "defs", children: defs });
|
|
358
|
-
}
|
|
359
|
-
function clone(value) {
|
|
360
|
-
if (value === null || typeof value !== "object") return value;
|
|
361
|
-
if (Array.isArray(value)) return value.map(clone);
|
|
362
|
-
const out = {};
|
|
363
|
-
for (const k of Object.keys(value)) out[k] = clone(value[k]);
|
|
364
|
-
return out;
|
|
365
|
-
}
|
|
366
|
-
function regenerateIdsInClone(root, ctx) {
|
|
367
|
-
const oldToNew = /* @__PURE__ */ new Map();
|
|
368
|
-
const walkAssign = (n) => {
|
|
369
|
-
var _a;
|
|
370
|
-
if (typeof n.id === "string") {
|
|
371
|
-
const newId = genId(ctx, "retimed");
|
|
372
|
-
oldToNew.set(n.id, newId);
|
|
373
|
-
n.id = newId;
|
|
374
|
-
}
|
|
375
|
-
(_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
|
|
376
|
-
};
|
|
377
|
-
walkAssign(root);
|
|
378
|
-
const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
|
|
379
|
-
const newId = oldToNew.get(oldId);
|
|
380
|
-
return newId ? "url(#" + newId + ")" : m;
|
|
381
|
-
});
|
|
382
|
-
const walkRewrite = (n) => {
|
|
383
|
-
var _a;
|
|
384
|
-
if (typeof n.href === "string" && n.href.startsWith("#")) {
|
|
385
|
-
const newId = oldToNew.get(n.href.slice(1));
|
|
386
|
-
if (newId) n.href = "#" + newId;
|
|
387
|
-
}
|
|
388
|
-
for (const k of Object.keys(n)) {
|
|
389
|
-
if (k === "children" || k === "effects" || k === "meta" || k === "href" || k === "id") continue;
|
|
390
|
-
const v = n[k];
|
|
391
|
-
if (typeof v === "string" && v.indexOf("url(#") !== -1) n[k] = rewriteUrl(v);
|
|
392
|
-
}
|
|
393
|
-
(_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
|
|
394
|
-
};
|
|
395
|
-
walkRewrite(root);
|
|
396
|
-
return oldToNew;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// src/effects/maskedByEffect.ts
|
|
400
|
-
function applyMaskedByEffect(node, fx, transformation, ctx) {
|
|
401
|
-
if (!fx) return node;
|
|
402
|
-
if (!fx.href) {
|
|
403
|
-
ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
|
|
404
|
-
return node;
|
|
405
|
-
}
|
|
406
|
-
const maskId = genId(ctx, "mask");
|
|
407
|
-
let content = { type: "use", href: "#" + fx.href };
|
|
408
|
-
content = wrapInverseTransform(content, transformation, ctx);
|
|
409
|
-
const mask = { type: "mask", id: maskId, children: [content] };
|
|
410
|
-
if (fx.maskType) mask.maskType = fx.maskType;
|
|
411
|
-
if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
|
|
412
|
-
if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
|
|
413
|
-
ctx.defs.push(mask);
|
|
414
|
-
node.mask = "url(#" + maskId + ")";
|
|
415
|
-
return node;
|
|
416
|
-
}
|
|
417
|
-
function wrapInverseTransform(inner, fx, ctx) {
|
|
418
|
-
if (!fx) return inner;
|
|
419
|
-
const origin = readStaticOrigin(fx.origin, ctx);
|
|
420
|
-
let n = inner;
|
|
421
|
-
n = wrapInversePart(n, "translate", fx.translate, void 0, ctx);
|
|
422
|
-
n = wrapInversePart(n, "rotate", fx.rotate, origin, ctx);
|
|
423
|
-
n = wrapInversePart(n, "scale", fx.scale, origin, ctx);
|
|
424
|
-
return n;
|
|
425
|
-
}
|
|
426
|
-
function wrapInversePart(inner, part, raw, origin, ctx) {
|
|
427
|
-
if (raw === void 0) return inner;
|
|
428
|
-
const v = readAnimatable(raw);
|
|
429
|
-
if (v.kind === "static") {
|
|
430
|
-
return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
|
|
431
|
-
}
|
|
432
|
-
if (v.kind === "animated") {
|
|
433
|
-
return {
|
|
434
|
-
type: "g",
|
|
435
|
-
animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) } },
|
|
436
|
-
children: [inner]
|
|
437
|
-
};
|
|
438
|
-
}
|
|
439
|
-
return inner;
|
|
440
|
-
}
|
|
441
|
-
function invertPartValue(part, value) {
|
|
442
|
-
if (part === "translate") return [-value[0], -value[1]];
|
|
443
|
-
if (part === "rotate") return -value;
|
|
444
|
-
return [1 / value[0], 1 / value[1]];
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// src/effects/refEffect.ts
|
|
448
|
-
var CONTENT_SUBREF = "content";
|
|
449
|
-
function applyRefAndTransformationEffect(node, ref, transformation, ctx) {
|
|
450
|
-
if (ref) {
|
|
451
|
-
const baseId = ref.baseId;
|
|
452
|
-
if (!baseId) {
|
|
453
|
-
ctx.errors.push("ref: missing baseId");
|
|
454
|
-
} else {
|
|
455
|
-
const targetId = ref.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
|
|
456
|
-
node.href = "#" + targetId;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
return applyTransformationEffect(node, transformation, ctx);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// src/effects/repeaterEffect.ts
|
|
463
|
-
function applyRepeaterEffect(node, fx, ctx) {
|
|
464
|
-
var _a, _b;
|
|
465
|
-
if (!fx) return node;
|
|
466
|
-
const copies = (_a = fx.copies) != null ? _a : 1;
|
|
467
|
-
if (copies < 1) {
|
|
468
|
-
ctx.errors.push("repeater.copies invalid: " + fx.copies);
|
|
469
|
-
return node;
|
|
470
|
-
}
|
|
471
|
-
const sharedTransform = node.transform;
|
|
472
|
-
const sharedAnimTransform = (_b = node.animate) == null ? void 0 : _b.transform;
|
|
473
|
-
const base = clone(node);
|
|
474
|
-
delete base.transform;
|
|
475
|
-
if (base.animate) {
|
|
476
|
-
delete base.animate.transform;
|
|
477
|
-
if (Object.keys(base.animate).length === 0) delete base.animate;
|
|
478
|
-
}
|
|
479
|
-
const children = [base];
|
|
480
|
-
for (let i = 1; i < copies; i++) {
|
|
481
|
-
const copy = clone(base);
|
|
482
|
-
copy.transform = { value: perCopyParts(fx, i) };
|
|
483
|
-
children.push(copy);
|
|
484
|
-
}
|
|
485
|
-
const wrapper = { type: "g", children };
|
|
486
|
-
if (sharedTransform !== void 0) wrapper.transform = sharedTransform;
|
|
487
|
-
if (sharedAnimTransform !== void 0) wrapper.animate = { transform: sharedAnimTransform };
|
|
488
|
-
return wrapper;
|
|
489
|
-
}
|
|
490
|
-
function perCopyParts(fx, i) {
|
|
491
|
-
const parts = {};
|
|
492
|
-
if (fx.translate) parts.translate = [fx.translate[0] * i, fx.translate[1] * i];
|
|
493
|
-
if (fx.rotate !== void 0) parts.rotate = fx.rotate * i;
|
|
494
|
-
if (fx.scale) parts.scale = [__pow(fx.scale[0] / 100, i), __pow(fx.scale[1] / 100, i)];
|
|
495
|
-
if (fx.origin) parts.origin = [fx.origin[0] * i, fx.origin[1] * i];
|
|
496
|
-
return parts;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
// src/effects/retimeEffect.ts
|
|
500
|
-
var RETIME_AS_SYMBOL = true;
|
|
501
|
-
function applyRetimeEffect(node, retime, ctx) {
|
|
502
|
-
var _a, _b, _c, _d;
|
|
503
|
-
if (!retime) return node;
|
|
504
|
-
const baseId = retime.baseId;
|
|
505
|
-
if (!baseId) {
|
|
506
|
-
ctx.errors.push("retime: missing baseId");
|
|
507
|
-
return node;
|
|
508
|
-
}
|
|
509
|
-
const target = ctx.idMap.get(baseId);
|
|
510
|
-
if (!target) {
|
|
511
|
-
ctx.warnings.push('retime: target "' + baseId + '" not found');
|
|
512
|
-
return node;
|
|
513
|
-
}
|
|
514
|
-
const start = (_a = retime.start) != null ? _a : 0;
|
|
515
|
-
const stretch = (_b = retime.stretch) != null ? _b : 1;
|
|
516
|
-
if (RETIME_AS_SYMBOL) {
|
|
517
|
-
const symbolClone = clone(target);
|
|
518
|
-
regenerateIdsInClone(symbolClone, ctx);
|
|
519
|
-
const cloneId = genId(ctx, "retime");
|
|
520
|
-
symbolClone.id = cloneId;
|
|
521
|
-
remapKeyframeTimes(symbolClone, start, stretch);
|
|
522
|
-
ctx.defs.push(symbolClone);
|
|
523
|
-
node.href = "#" + cloneId;
|
|
524
|
-
return node;
|
|
525
|
-
}
|
|
526
|
-
const sourceNodes = target.type === "symbol" ? target.children || [] : [target];
|
|
527
|
-
const content = sourceNodes.map((child) => {
|
|
528
|
-
const c = clone(child);
|
|
529
|
-
regenerateIdsInClone(c, ctx);
|
|
530
|
-
remapKeyframeTimes(c, start, stretch);
|
|
531
|
-
return c;
|
|
532
|
-
});
|
|
533
|
-
const g = __spreadProps(__spreadValues({}, node), { type: "g", children: content });
|
|
534
|
-
delete g.href;
|
|
535
|
-
const x = Number((_c = node.x) != null ? _c : 0), y = Number((_d = node.y) != null ? _d : 0);
|
|
536
|
-
if (x || y) {
|
|
537
|
-
const offset = "translate(" + x + "," + y + ")";
|
|
538
|
-
g.transform = typeof g.transform === "string" ? offset + g.transform : offset;
|
|
539
|
-
delete g.x;
|
|
540
|
-
delete g.y;
|
|
541
|
-
}
|
|
542
|
-
return g;
|
|
543
|
-
}
|
|
544
|
-
function remapKeyframeTimes(node, start, stretch) {
|
|
545
|
-
var _a;
|
|
546
|
-
const remap2 = (kfs) => {
|
|
547
|
-
for (const kf of kfs) if (typeof kf.time === "number") kf.time = start + kf.time * stretch;
|
|
548
|
-
};
|
|
549
|
-
if (node.transform && typeof node.transform === "object" && Array.isArray(node.transform.keyframes)) {
|
|
550
|
-
remap2(node.transform.keyframes);
|
|
551
|
-
}
|
|
552
|
-
if (node.animate && typeof node.animate === "object") {
|
|
553
|
-
for (const prop of Object.keys(node.animate)) {
|
|
554
|
-
const anim = node.animate[prop];
|
|
555
|
-
if (anim && Array.isArray(anim.keyframes)) remap2(anim.keyframes);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
(_a = node.children) == null ? void 0 : _a.forEach((child) => remapKeyframeTimes(child, start, stretch));
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// src/effects/trimPathEffect.ts
|
|
562
|
-
function applyTrimPathEffect(node, trimPath, isCombinedShape) {
|
|
563
|
-
var _a;
|
|
564
|
-
if (!trimPath && !isCombinedShape) return node;
|
|
565
|
-
const d = (_a = node.d) != null ? _a : rectToPathD(node);
|
|
566
|
-
if (d === void 0) return node;
|
|
567
|
-
const g = __spreadProps(__spreadValues({}, node), { type: "g" });
|
|
568
|
-
delete g.d;
|
|
569
|
-
const meta = g.meta = __spreadValues({}, g.meta || {});
|
|
570
|
-
const effects = meta.effects = __spreadValues({}, meta.effects || {});
|
|
571
|
-
if (trimPath) effects.trimPath = trimPath;
|
|
572
|
-
effects.isCombinedShape = true;
|
|
573
|
-
g.children = [{ type: "path", d }];
|
|
574
|
-
return g;
|
|
575
|
-
}
|
|
576
|
-
function rectToPathD(node) {
|
|
577
|
-
var _a, _b, _c, _d;
|
|
578
|
-
if (node.type !== "rect") return void 0;
|
|
579
|
-
const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
|
|
580
|
-
const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
|
|
581
|
-
return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// src/effects/PlayerEffectsUtil.ts
|
|
585
|
-
function applyPlayerEffects(root) {
|
|
586
|
-
const ctx = {
|
|
587
|
-
defs: [],
|
|
588
|
-
warnings: [],
|
|
589
|
-
errors: [],
|
|
590
|
-
idMap: /* @__PURE__ */ new Map(),
|
|
591
|
-
nextId: 0,
|
|
592
|
-
contentRefInnerIds: /* @__PURE__ */ new Map()
|
|
593
|
-
};
|
|
594
|
-
const working = clone(root);
|
|
595
|
-
indexById(working, ctx.idMap);
|
|
596
|
-
identifyContentRefTargets(working, ctx, () => genId(ctx, "inner"));
|
|
597
|
-
const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);
|
|
598
|
-
const out = applyPlayerEffects_retime(afterPass1, ctx);
|
|
599
|
-
spliceDefs(out, ctx.defs);
|
|
600
|
-
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
601
|
-
}
|
|
602
|
-
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
603
|
-
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
604
|
-
const fx = node.effects;
|
|
605
|
-
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
606
|
-
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
607
|
-
if (!fx && !innerIdForContentRef) return node;
|
|
608
|
-
const { transformation, repeater, maskedBy, trimPath, retime, ref } = fx != null ? fx : {};
|
|
609
|
-
const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
|
|
610
|
-
if (fx) delete node.effects;
|
|
611
|
-
let n = node;
|
|
612
|
-
n = applyTrimPathEffect(n, trimPath, isCombinedShape);
|
|
613
|
-
n = applyRepeaterEffect(n, repeater, ctx);
|
|
614
|
-
n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
|
|
615
|
-
if (innerIdForContentRef) {
|
|
616
|
-
n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
|
|
617
|
-
} else {
|
|
618
|
-
n = applyRefAndTransformationEffect(n, ref, transformation, ctx);
|
|
619
|
-
}
|
|
620
|
-
if (retime) node.effects = { retime };
|
|
621
|
-
if (originalId) ctx.idMap.set(originalId, n);
|
|
622
|
-
return n;
|
|
623
|
-
}
|
|
624
|
-
function applyPlayerEffects_retime(node, ctx) {
|
|
625
|
-
var _a;
|
|
626
|
-
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_retime(child, ctx));
|
|
627
|
-
const retime = (_a = node.effects) == null ? void 0 : _a.retime;
|
|
628
|
-
if (!retime) return node;
|
|
629
|
-
delete node.effects;
|
|
630
|
-
return applyRetimeEffect(node, retime, ctx);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
358
|
// src/PxSchema.ts
|
|
634
359
|
function pathStr(path) {
|
|
635
360
|
if (!path.length) return ".";
|
|
@@ -1089,6 +814,15 @@ var px = {
|
|
|
1089
814
|
// src/PxAnimatorTypes.ts
|
|
1090
815
|
var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
|
|
1091
816
|
var PX_ANIM_ATTR_NAME = "_px_animator";
|
|
817
|
+
var PxAnimatorMode = {
|
|
818
|
+
auto: "auto",
|
|
819
|
+
webapi: "webapi",
|
|
820
|
+
frames: "frames"
|
|
821
|
+
};
|
|
822
|
+
var PxAnimatorEngine = {
|
|
823
|
+
webapi: PxAnimatorMode.webapi,
|
|
824
|
+
frames: PxAnimatorMode.frames
|
|
825
|
+
};
|
|
1092
826
|
var TEXT_ATTR = "text";
|
|
1093
827
|
var TEXT_CONTENT_ATTR = "textContent";
|
|
1094
828
|
var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
|
|
@@ -1171,7 +905,7 @@ var PxDefsSchema = implementsInterface()(px.object({
|
|
|
1171
905
|
styles: px.record(px.any()).optional()
|
|
1172
906
|
}));
|
|
1173
907
|
var PxAnimatorConfigSchema = implementsInterface()(px.object({
|
|
1174
|
-
mode: px.enum([
|
|
908
|
+
mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
|
|
1175
909
|
duration: px.number().optional(),
|
|
1176
910
|
delay: px.number().optional(),
|
|
1177
911
|
iterations: px.union([px.number(), px.literal("infinite")]).optional(),
|
|
@@ -1210,47 +944,96 @@ var PxAnimatableVec2Schema = px.union([
|
|
|
1210
944
|
autoOrient: px.boolean().optional()
|
|
1211
945
|
})
|
|
1212
946
|
]);
|
|
1213
|
-
var PxTransformationEffectSchema = px.object({
|
|
947
|
+
var PxTransformationEffectSchema = implementsInterface()(px.object({
|
|
1214
948
|
translate: PxAnimatableVec2Schema.optional(),
|
|
1215
949
|
rotate: PxAnimatableNumberSchema.optional(),
|
|
1216
950
|
scale: PxAnimatableVec2Schema.optional(),
|
|
1217
951
|
skew: PxAnimatableVec2Schema.optional(),
|
|
1218
952
|
origin: PxAnimatableVec2Schema.optional()
|
|
1219
|
-
});
|
|
1220
|
-
var PxRepeaterEffectSchema = px.object({
|
|
953
|
+
}));
|
|
954
|
+
var PxRepeaterEffectSchema = implementsInterface()(px.object({
|
|
1221
955
|
copies: px.number().optional(),
|
|
1222
|
-
translate:
|
|
1223
|
-
rotate:
|
|
1224
|
-
scale:
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
var PxMaskedByEffectSchema = px.object({
|
|
956
|
+
translate: PxAnimatableVec2Schema.optional(),
|
|
957
|
+
rotate: PxAnimatableNumberSchema.optional(),
|
|
958
|
+
scale: PxAnimatableVec2Schema.optional(),
|
|
959
|
+
origin: PxAnimatableVec2Schema.optional()
|
|
960
|
+
}));
|
|
961
|
+
var PxMaskedByEffectSchema = implementsInterface()(px.object({
|
|
1229
962
|
href: px.string().optional(),
|
|
1230
963
|
maskType: px.string().optional(),
|
|
1231
964
|
maskUnits: px.string().optional(),
|
|
1232
965
|
maskContentUnits: px.string().optional()
|
|
1233
|
-
});
|
|
1234
|
-
var PxTrimPathEffectSchema = px.
|
|
1235
|
-
|
|
966
|
+
}));
|
|
967
|
+
var PxTrimPathEffectSchema = implementsInterface()(px.object({
|
|
968
|
+
offset: PxAnimatableNumberSchema.optional(),
|
|
969
|
+
range: PxAnimatableVec2Schema.optional(),
|
|
970
|
+
trimAllAsOne: px.boolean().optional()
|
|
971
|
+
}));
|
|
972
|
+
var PxRetimeEffectSchema = implementsInterface()(px.object({
|
|
1236
973
|
baseId: px.string().optional(),
|
|
1237
974
|
start: px.number().optional(),
|
|
1238
975
|
stretch: px.number().optional(),
|
|
1239
976
|
timeCrop: px.tuple([px.number(), px.number()]).optional()
|
|
1240
|
-
});
|
|
1241
|
-
var PxRefEffectSchema = px.object({
|
|
977
|
+
}));
|
|
978
|
+
var PxRefEffectSchema = implementsInterface()(px.object({
|
|
1242
979
|
baseId: px.string().optional(),
|
|
1243
980
|
type: px.string().optional()
|
|
1244
|
-
});
|
|
1245
|
-
var
|
|
981
|
+
}));
|
|
982
|
+
var PxGradientUnits = {
|
|
983
|
+
userSpaceOnUse: "userSpaceOnUse",
|
|
984
|
+
objectBoundingBox: "objectBoundingBox"
|
|
985
|
+
};
|
|
986
|
+
var PxGradientSpreadMethod = {
|
|
987
|
+
pad: "pad",
|
|
988
|
+
reflect: "reflect",
|
|
989
|
+
repeat: "repeat"
|
|
990
|
+
};
|
|
991
|
+
var PxGradientType = {
|
|
992
|
+
linear: "linear",
|
|
993
|
+
radial: "radial"
|
|
994
|
+
};
|
|
995
|
+
var PxGradientStopSchema = implementsInterface()(px.object({
|
|
996
|
+
offset: px.number(),
|
|
997
|
+
color: px.string()
|
|
998
|
+
}));
|
|
999
|
+
var PxAnimatableGradientStopsSchema = px.union([
|
|
1000
|
+
px.array(PxGradientStopSchema),
|
|
1001
|
+
px.object({ value: px.array(PxGradientStopSchema) }),
|
|
1002
|
+
px.object({ keyframes: px.array(PxKeyframeSchema) })
|
|
1003
|
+
]);
|
|
1004
|
+
var PxFillGradientEffectSchema = implementsInterface()(px.object({
|
|
1005
|
+
type: px.enum([PxGradientType.linear, PxGradientType.radial]),
|
|
1006
|
+
p1: px.tuple([px.number(), px.number()]).optional(),
|
|
1007
|
+
p2: px.tuple([px.number(), px.number()]).optional(),
|
|
1008
|
+
c: px.tuple([px.number(), px.number()]).optional(),
|
|
1009
|
+
r: px.number().optional(),
|
|
1010
|
+
fp: px.tuple([px.number(), px.number()]).optional(),
|
|
1011
|
+
stops: PxAnimatableGradientStopsSchema.optional(),
|
|
1012
|
+
gradientUnits: px.string().optional(),
|
|
1013
|
+
spreadMethod: px.string().optional(),
|
|
1014
|
+
gradientTransform: px.string().optional()
|
|
1015
|
+
}));
|
|
1016
|
+
var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
|
|
1017
|
+
var PxTextAlongPathEffectSchema = implementsInterface()(px.object({
|
|
1018
|
+
href: px.string(),
|
|
1019
|
+
lengthAdjust: px.string().optional(),
|
|
1020
|
+
method: px.string().optional(),
|
|
1021
|
+
spacing: px.string().optional(),
|
|
1022
|
+
startOffset: PxAnimatableNumberSchema.optional(),
|
|
1023
|
+
textLength: PxAnimatableNumberSchema.optional()
|
|
1024
|
+
}));
|
|
1025
|
+
var PxEffectsSchema = implementsInterface()(px.object({
|
|
1246
1026
|
transformation: PxTransformationEffectSchema.optional(),
|
|
1247
1027
|
repeater: PxRepeaterEffectSchema.optional(),
|
|
1248
1028
|
maskedBy: PxMaskedByEffectSchema.optional(),
|
|
1249
1029
|
trimPath: PxTrimPathEffectSchema.optional(),
|
|
1250
1030
|
retime: PxRetimeEffectSchema.optional(),
|
|
1251
1031
|
isCombinedShape: px.boolean().optional(),
|
|
1252
|
-
ref: PxRefEffectSchema.optional()
|
|
1253
|
-
|
|
1032
|
+
ref: PxRefEffectSchema.optional(),
|
|
1033
|
+
fillGradient: PxFillGradientEffectSchema.optional(),
|
|
1034
|
+
strokeGradient: PxStrokeGradientEffectSchema.optional(),
|
|
1035
|
+
textAlongPath: PxTextAlongPathEffectSchema.optional()
|
|
1036
|
+
}));
|
|
1254
1037
|
function validateNodeEffects(root, opts) {
|
|
1255
1038
|
const warnings = [];
|
|
1256
1039
|
const walk = (node, path) => {
|
|
@@ -1276,7 +1059,10 @@ var PxNodeBase = px.openObject({
|
|
|
1276
1059
|
// Consumed and removed by `applyPlayerEffects` before any other normalisation
|
|
1277
1060
|
// (see `createAnimatorImpl`), so downstream code never sees it.
|
|
1278
1061
|
effects: PxEffectsSchema.optional(),
|
|
1279
|
-
|
|
1062
|
+
// `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
|
|
1063
|
+
// string ref / array of refs / inline definition / mixed array; mirrors
|
|
1064
|
+
// `animator.animate` map values and what `processNode` resolves at runtime.
|
|
1065
|
+
animate: PxElementAnimationSchema.optional(),
|
|
1280
1066
|
style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
|
|
1281
1067
|
}, PxAttrValueSchema);
|
|
1282
1068
|
var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBase._shape), {
|
|
@@ -1329,784 +1115,1586 @@ function getChildren(doc) {
|
|
|
1329
1115
|
return doc == null ? void 0 : doc.children;
|
|
1330
1116
|
}
|
|
1331
1117
|
|
|
1332
|
-
// src/
|
|
1333
|
-
function
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
const
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
const
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
const isLine = prevO[0] === prevV[0] && prevO[1] === prevV[1] && (currI[0] === currV[0] && currI[1] === currV[1]);
|
|
1349
|
-
if (isLine) {
|
|
1350
|
-
d.push("L" + currV[0] + "," + currV[1]);
|
|
1351
|
-
} else {
|
|
1352
|
-
d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
|
|
1118
|
+
// src/PxNodeCloneUtil.ts
|
|
1119
|
+
function deepClonePxNode(value) {
|
|
1120
|
+
if (value === null || typeof value !== "object") return value;
|
|
1121
|
+
if (Array.isArray(value)) return value.map(deepClonePxNode);
|
|
1122
|
+
const out = {};
|
|
1123
|
+
for (const k of Object.keys(value)) out[k] = deepClonePxNode(value[k]);
|
|
1124
|
+
return out;
|
|
1125
|
+
}
|
|
1126
|
+
function regenerateIdsAndRewriteRefs(root, genId3) {
|
|
1127
|
+
const oldToNew = /* @__PURE__ */ new Map();
|
|
1128
|
+
const walkAssign = (n) => {
|
|
1129
|
+
var _a;
|
|
1130
|
+
if (typeof n.id === "string") {
|
|
1131
|
+
const newId = genId3();
|
|
1132
|
+
oldToNew.set(n.id, newId);
|
|
1133
|
+
n.id = newId;
|
|
1353
1134
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
const
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1135
|
+
(_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
|
|
1136
|
+
};
|
|
1137
|
+
walkAssign(root);
|
|
1138
|
+
const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
|
|
1139
|
+
const newId = oldToNew.get(oldId);
|
|
1140
|
+
return newId ? "url(#" + newId + ")" : m;
|
|
1141
|
+
});
|
|
1142
|
+
const walkRewrite = (n) => {
|
|
1143
|
+
var _a;
|
|
1144
|
+
if (typeof n.href === "string" && n.href.startsWith("#")) {
|
|
1145
|
+
const newId = oldToNew.get(n.href.slice(1));
|
|
1146
|
+
if (newId) n.href = "#" + newId;
|
|
1363
1147
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1148
|
+
for (const k of Object.keys(n)) {
|
|
1149
|
+
if (k === "children" || k === "effects" || k === "meta" || k === "animate" || k === "href" || k === "id") continue;
|
|
1150
|
+
const v = n[k];
|
|
1151
|
+
if (typeof v === "string" && v.indexOf("url(#") !== -1) {
|
|
1152
|
+
n[k] = rewriteUrl(v);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
(_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
|
|
1156
|
+
};
|
|
1157
|
+
walkRewrite(root);
|
|
1158
|
+
return oldToNew;
|
|
1367
1159
|
}
|
|
1368
|
-
function
|
|
1369
|
-
|
|
1160
|
+
function toFiniteNum(v) {
|
|
1161
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? parseFloat(v) : NaN;
|
|
1162
|
+
return Number.isFinite(n) ? n : 0;
|
|
1370
1163
|
}
|
|
1371
|
-
function
|
|
1372
|
-
|
|
1373
|
-
const
|
|
1374
|
-
|
|
1375
|
-
|
|
1164
|
+
function applyUseOffsetToG(gNode) {
|
|
1165
|
+
var _a;
|
|
1166
|
+
const x = toFiniteNum(gNode.x);
|
|
1167
|
+
const y = toFiniteNum(gNode.y);
|
|
1168
|
+
delete gNode.x;
|
|
1169
|
+
delete gNode.y;
|
|
1170
|
+
if (!x && !y) return gNode;
|
|
1171
|
+
const offset = "translate(" + x + "," + y + ")";
|
|
1172
|
+
const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
|
|
1173
|
+
if (carriesTransform) {
|
|
1174
|
+
const inner = { type: "g", transform: offset, children: (_a = gNode.children) != null ? _a : [] };
|
|
1175
|
+
gNode.children = [inner];
|
|
1176
|
+
} else {
|
|
1177
|
+
gNode.transform = offset;
|
|
1376
1178
|
}
|
|
1377
|
-
return
|
|
1179
|
+
return gNode;
|
|
1378
1180
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
interpolateNum(a[2] || 0, b[2] || 0, t),
|
|
1384
|
-
interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
|
|
1385
|
-
];
|
|
1181
|
+
|
|
1182
|
+
// src/effects/util.ts
|
|
1183
|
+
function genId(ctx, prefix) {
|
|
1184
|
+
return "_lw_" + prefix + "_" + ctx.nextId++;
|
|
1386
1185
|
}
|
|
1387
|
-
function
|
|
1388
|
-
|
|
1389
|
-
const res = [];
|
|
1390
|
-
for (let i = 0; i < count; i++) {
|
|
1391
|
-
res.push(interpolateBezier(paths1[i], paths2[i], progress));
|
|
1392
|
-
}
|
|
1393
|
-
return res;
|
|
1186
|
+
function stripHash(href) {
|
|
1187
|
+
return typeof href === "string" ? href.replace(/^#/, "") : void 0;
|
|
1394
1188
|
}
|
|
1395
|
-
function
|
|
1396
|
-
var _a
|
|
1397
|
-
if (
|
|
1398
|
-
|
|
1399
|
-
const len = Math.min(path1.v.length, path2.v.length);
|
|
1400
|
-
const v = [];
|
|
1401
|
-
const i = [];
|
|
1402
|
-
const o = [];
|
|
1403
|
-
for (let idx = 0; idx < len; idx++) {
|
|
1404
|
-
const v1 = path1.v[idx];
|
|
1405
|
-
const v2 = path2.v[idx];
|
|
1406
|
-
v.push(interpolateVec(v1, v2, t));
|
|
1407
|
-
const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
|
|
1408
|
-
const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
|
|
1409
|
-
i.push(interpolateVec(i1, i2, t));
|
|
1410
|
-
const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
|
|
1411
|
-
const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
|
|
1412
|
-
o.push(interpolateVec(o1, o2, t));
|
|
1413
|
-
}
|
|
1414
|
-
return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
|
|
1189
|
+
function indexById(node, map) {
|
|
1190
|
+
var _a;
|
|
1191
|
+
if (typeof node.id === "string") map.set(node.id, node);
|
|
1192
|
+
(_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
|
|
1415
1193
|
}
|
|
1416
|
-
function
|
|
1417
|
-
if (
|
|
1418
|
-
const
|
|
1419
|
-
|
|
1194
|
+
function spliceDefs(root, defs) {
|
|
1195
|
+
if (!defs.length) return;
|
|
1196
|
+
const existing = root.children || (root.children = []);
|
|
1197
|
+
existing.unshift({ type: "defs", children: defs });
|
|
1420
1198
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1199
|
+
var clone = deepClonePxNode;
|
|
1200
|
+
function regenerateIdsInClone(root, ctx) {
|
|
1201
|
+
return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// src/effects/gradientEffect.ts
|
|
1205
|
+
function applyFillGradientEffect(node, fx, ctx) {
|
|
1206
|
+
return applyGradient(node, fx, ctx, "fill");
|
|
1207
|
+
}
|
|
1208
|
+
function applyStrokeGradientEffect(node, fx, ctx) {
|
|
1209
|
+
return applyGradient(node, fx, ctx, "stroke");
|
|
1210
|
+
}
|
|
1211
|
+
function applyGradient(node, fx, ctx, attr) {
|
|
1212
|
+
if (!fx) return node;
|
|
1213
|
+
const id = genId(ctx, "grad");
|
|
1214
|
+
const def = synthesiseGradientDef(fx, id, ctx);
|
|
1215
|
+
ctx.defs.push(def);
|
|
1216
|
+
node[attr] = "url(#" + id + ")";
|
|
1217
|
+
return node;
|
|
1218
|
+
}
|
|
1219
|
+
function synthesiseGradientDef(fx, id, ctx) {
|
|
1220
|
+
const out = {
|
|
1221
|
+
type: fx.type === PxGradientType.radial ? "radialGradient" : "linearGradient",
|
|
1222
|
+
id
|
|
1223
|
+
};
|
|
1224
|
+
if (fx.type === PxGradientType.linear) {
|
|
1225
|
+
if (fx.p1) {
|
|
1226
|
+
out.x1 = String(fx.p1[0]);
|
|
1227
|
+
out.y1 = String(fx.p1[1]);
|
|
1228
|
+
}
|
|
1229
|
+
if (fx.p2) {
|
|
1230
|
+
out.x2 = String(fx.p2[0]);
|
|
1231
|
+
out.y2 = String(fx.p2[1]);
|
|
1232
|
+
}
|
|
1233
|
+
} else {
|
|
1234
|
+
if (fx.c) {
|
|
1235
|
+
out.cx = String(fx.c[0]);
|
|
1236
|
+
out.cy = String(fx.c[1]);
|
|
1237
|
+
}
|
|
1238
|
+
if (fx.r !== void 0) out.r = String(fx.r);
|
|
1239
|
+
if (fx.fp) {
|
|
1240
|
+
out.fx = String(fx.fp[0]);
|
|
1241
|
+
out.fy = String(fx.fp[1]);
|
|
1242
|
+
}
|
|
1432
1243
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1244
|
+
if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
|
|
1245
|
+
if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
|
|
1246
|
+
if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
|
|
1247
|
+
out.children = buildStopChildren(fx.stops, ctx);
|
|
1248
|
+
return out;
|
|
1249
|
+
}
|
|
1250
|
+
function buildStopChildren(stops, ctx) {
|
|
1251
|
+
var _a, _b, _c, _d;
|
|
1252
|
+
if (!stops) return [];
|
|
1253
|
+
if (Array.isArray(stops)) return stops.map(staticStopNode);
|
|
1254
|
+
if (typeof stops === "object" && Array.isArray(stops.value)) {
|
|
1255
|
+
return stops.value.map(staticStopNode);
|
|
1256
|
+
}
|
|
1257
|
+
const animBlock = stops;
|
|
1258
|
+
const kfs = animBlock.keyframes;
|
|
1259
|
+
if (!Array.isArray(kfs) || !kfs.length) return [];
|
|
1260
|
+
let stopCount = 0;
|
|
1261
|
+
for (const kf of kfs) {
|
|
1262
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
1263
|
+
if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
|
|
1442
1264
|
}
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
t2 = (t1 + t0) / 2;
|
|
1265
|
+
if (!stopCount) return [];
|
|
1266
|
+
const firstKfValue = (_b = kfs[0].value) != null ? _b : kfs[0].v;
|
|
1267
|
+
const baselineStops = [];
|
|
1268
|
+
for (let i = 0; i < stopCount; i++) {
|
|
1269
|
+
const s = (_d = (_c = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _c : prevDefinedStop(kfs, 0, i)) != null ? _d : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
|
|
1270
|
+
baselineStops.push({ offset: s.offset, color: s.color });
|
|
1450
1271
|
}
|
|
1451
|
-
return
|
|
1272
|
+
return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx));
|
|
1452
1273
|
}
|
|
1453
|
-
function
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
function sampleCurveY(t) {
|
|
1459
|
-
return ((ay * t + by) * t + cy) * t;
|
|
1460
|
-
}
|
|
1461
|
-
return function(x) {
|
|
1462
|
-
return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
|
|
1274
|
+
function staticStopNode(s) {
|
|
1275
|
+
return {
|
|
1276
|
+
type: "stop",
|
|
1277
|
+
offset: formatOffset(s.offset),
|
|
1278
|
+
stopColor: s.color
|
|
1463
1279
|
};
|
|
1464
1280
|
}
|
|
1465
|
-
function
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
const
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1281
|
+
function animatedStopNode(baseline, kfs, stopIdx, _ctx) {
|
|
1282
|
+
var _a, _b, _c, _d, _e;
|
|
1283
|
+
const colorKfs = [];
|
|
1284
|
+
const offsetKfs = [];
|
|
1285
|
+
let offsetVaries = false;
|
|
1286
|
+
for (const kf of kfs) {
|
|
1287
|
+
const t = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
|
|
1288
|
+
const arr = (_c = kf.value) != null ? _c : kf.v;
|
|
1289
|
+
const sliced = (_d = arr == null ? void 0 : arr[stopIdx]) != null ? _d : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
|
|
1290
|
+
if (!sliced) continue;
|
|
1291
|
+
const easing = (_e = kf.easing) != null ? _e : kf.e;
|
|
1292
|
+
const colorOut = { time: t, value: sliced.color };
|
|
1293
|
+
if (easing !== void 0) colorOut.easing = easing;
|
|
1294
|
+
colorKfs.push(colorOut);
|
|
1295
|
+
const offsetOut = { time: t, value: sliced.offset };
|
|
1296
|
+
if (easing !== void 0) offsetOut.easing = easing;
|
|
1297
|
+
offsetKfs.push(offsetOut);
|
|
1298
|
+
if (sliced.offset !== baseline.offset) offsetVaries = true;
|
|
1299
|
+
}
|
|
1300
|
+
const stop = {
|
|
1301
|
+
type: "stop",
|
|
1302
|
+
offset: formatOffset(baseline.offset),
|
|
1303
|
+
stopColor: baseline.color
|
|
1478
1304
|
};
|
|
1305
|
+
const animate = {};
|
|
1306
|
+
if (colorKfs.length) animate.stopColor = { keyframes: colorKfs };
|
|
1307
|
+
if (offsetVaries && offsetKfs.length) animate.offset = { keyframes: offsetKfs };
|
|
1308
|
+
if (Object.keys(animate).length) stop.animate = animate;
|
|
1309
|
+
return stop;
|
|
1479
1310
|
}
|
|
1480
|
-
function
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
const t = solveCubicBezierX(x1, x2, xFraction);
|
|
1486
|
-
const p0 = [0, 0];
|
|
1487
|
-
const p1 = [x1, y1];
|
|
1488
|
-
const p2 = [x2, y2];
|
|
1489
|
-
const p3 = [1, 1];
|
|
1490
|
-
const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
|
|
1491
|
-
const sx = left[3][0];
|
|
1492
|
-
const sy = left[3][1];
|
|
1493
|
-
let leftEasing;
|
|
1494
|
-
if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
|
|
1495
|
-
leftEasing = [
|
|
1496
|
-
left[1][0] / sx,
|
|
1497
|
-
left[1][1] / sy,
|
|
1498
|
-
left[2][0] / sx,
|
|
1499
|
-
left[2][1] / sy
|
|
1500
|
-
];
|
|
1311
|
+
function prevDefinedStop(kfs, fromIdx, stopIdx) {
|
|
1312
|
+
var _a, _b;
|
|
1313
|
+
for (let i = fromIdx; i >= 0; i--) {
|
|
1314
|
+
const arr = (_a = kfs[i].value) != null ? _a : kfs[i].v;
|
|
1315
|
+
if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
|
|
1501
1316
|
}
|
|
1502
|
-
let
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
|
|
1506
|
-
rightEasing = [
|
|
1507
|
-
(right[1][0] - sx) / rx,
|
|
1508
|
-
(right[1][1] - sy) / ry,
|
|
1509
|
-
(right[2][0] - sx) / rx,
|
|
1510
|
-
(right[2][1] - sy) / ry
|
|
1511
|
-
];
|
|
1317
|
+
for (let i = fromIdx + 1; i < kfs.length; i++) {
|
|
1318
|
+
const arr = (_b = kfs[i].value) != null ? _b : kfs[i].v;
|
|
1319
|
+
if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
|
|
1512
1320
|
}
|
|
1513
|
-
return
|
|
1321
|
+
return void 0;
|
|
1514
1322
|
}
|
|
1515
|
-
function
|
|
1516
|
-
|
|
1517
|
-
return
|
|
1323
|
+
function formatOffset(o) {
|
|
1324
|
+
const pct = Math.round(o * 1e3) / 10;
|
|
1325
|
+
return pct + "%";
|
|
1518
1326
|
}
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1327
|
+
|
|
1328
|
+
// src/effects/maskedByEffect.ts
|
|
1329
|
+
function applyMaskedByEffect(node, fx, transformation, ctx) {
|
|
1330
|
+
if (!fx) return node;
|
|
1331
|
+
if (!fx.href) {
|
|
1332
|
+
ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
|
|
1333
|
+
return node;
|
|
1334
|
+
}
|
|
1335
|
+
const maskId = genId(ctx, "mask");
|
|
1336
|
+
let content = { type: "use", href: "#" + fx.href };
|
|
1337
|
+
if (transformation) {
|
|
1338
|
+
content = wrapInverseTransform(content, transformation, ctx);
|
|
1339
|
+
} else if (hasAnimateTransform(node)) {
|
|
1340
|
+
content = wrapInverseAnimatedBodyTransform(content, node, ctx);
|
|
1341
|
+
} else {
|
|
1342
|
+
const bodyStatic = readTransformationFromBody(node);
|
|
1343
|
+
if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
|
|
1344
|
+
}
|
|
1345
|
+
const includeTargetOwn = transformation === void 0 && !nodeHasBodyTransform(node);
|
|
1346
|
+
content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);
|
|
1347
|
+
const mask = { type: "mask", id: maskId, children: [content] };
|
|
1348
|
+
if (fx.maskType) mask.maskType = fx.maskType;
|
|
1349
|
+
if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
|
|
1350
|
+
if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
|
|
1351
|
+
ctx.defs.push(mask);
|
|
1352
|
+
node.mask = "url(#" + maskId + ")";
|
|
1353
|
+
return node;
|
|
1524
1354
|
}
|
|
1525
|
-
function
|
|
1526
|
-
|
|
1527
|
-
const
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1355
|
+
function wrapInverseTransform(inner, fx, ctx) {
|
|
1356
|
+
if (!fx) return inner;
|
|
1357
|
+
const origin = readStaticOrigin(fx.origin, ctx);
|
|
1358
|
+
let n = inner;
|
|
1359
|
+
n = wrapInversePart(n, "translate" /* Translate */, fx.translate, void 0, ctx);
|
|
1360
|
+
n = wrapInversePart(n, "rotate" /* Rotate */, fx.rotate, origin, ctx);
|
|
1361
|
+
n = wrapInversePart(n, "scale" /* Scale */, fx.scale, origin, ctx);
|
|
1362
|
+
return n;
|
|
1531
1363
|
}
|
|
1532
|
-
function
|
|
1533
|
-
|
|
1534
|
-
const
|
|
1535
|
-
const
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
|
|
1539
|
-
const result = [
|
|
1540
|
-
parseInt(r, 16) / 255,
|
|
1541
|
-
parseInt(g, 16) / 255,
|
|
1542
|
-
parseInt(b, 16) / 255
|
|
1543
|
-
];
|
|
1544
|
-
if (a !== null) {
|
|
1545
|
-
result.push(parseInt(a, 16) / 255);
|
|
1364
|
+
function wrapInversePart(inner, part, raw, origin, ctx) {
|
|
1365
|
+
if (raw === void 0) return inner;
|
|
1366
|
+
const normalisedRaw = part === "scale" /* Scale */ && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
|
|
1367
|
+
const v = readAnimatable(normalisedRaw);
|
|
1368
|
+
if (v.kind === "static" /* Static */) {
|
|
1369
|
+
return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
|
|
1546
1370
|
}
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
if (s.startsWith("#")) {
|
|
1554
|
-
return parseHex(s);
|
|
1555
|
-
} else if (s.startsWith("rgb")) {
|
|
1556
|
-
return parseRgba(s);
|
|
1557
|
-
} else {
|
|
1558
|
-
console.warn("Unsupported color format: " + s);
|
|
1371
|
+
if (v.kind === "animated" /* Animated */) {
|
|
1372
|
+
return {
|
|
1373
|
+
type: "g",
|
|
1374
|
+
animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) } },
|
|
1375
|
+
children: [inner]
|
|
1376
|
+
};
|
|
1559
1377
|
}
|
|
1560
|
-
return
|
|
1561
|
-
}
|
|
1562
|
-
var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
|
|
1563
|
-
var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
|
|
1564
|
-
var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
1565
|
-
function composeTransformParts(parts, opts) {
|
|
1566
|
-
var _a;
|
|
1567
|
-
if (!parts) return "";
|
|
1568
|
-
const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
|
|
1569
|
-
const segs = [];
|
|
1570
|
-
const t = parts.translate;
|
|
1571
|
-
const o = parts.origin;
|
|
1572
|
-
const r = parts.rotate;
|
|
1573
|
-
const s = parts.scale;
|
|
1574
|
-
const tu = withUnits ? "px" : "";
|
|
1575
|
-
const ru = withUnits ? "deg" : "";
|
|
1576
|
-
if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
|
|
1577
|
-
if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
|
|
1578
|
-
if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
|
|
1579
|
-
if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
|
|
1580
|
-
if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
|
|
1581
|
-
return segs.join("");
|
|
1582
|
-
}
|
|
1583
|
-
var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
1584
|
-
var DEFAULT_DURATION_MS = 1e3;
|
|
1585
|
-
function kebabToCamelCaseWord(kebab) {
|
|
1586
|
-
return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
|
|
1587
|
-
}
|
|
1588
|
-
function isCamelCaseWord(word) {
|
|
1589
|
-
return !word.includes("-") && /[a-z][A-Z]/.test(word);
|
|
1590
|
-
}
|
|
1591
|
-
var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
|
|
1592
|
-
// Transform/positioning
|
|
1593
|
-
"viewBox",
|
|
1594
|
-
"preserveAspectRatio",
|
|
1595
|
-
// Gradient
|
|
1596
|
-
"gradientUnits",
|
|
1597
|
-
"gradientTransform",
|
|
1598
|
-
"spreadMethod",
|
|
1599
|
-
// Pattern
|
|
1600
|
-
"patternUnits",
|
|
1601
|
-
"patternContentUnits",
|
|
1602
|
-
"patternTransform",
|
|
1603
|
-
// Clipping/masking
|
|
1604
|
-
"clipPathUnits",
|
|
1605
|
-
"maskUnits",
|
|
1606
|
-
"maskContentUnits",
|
|
1607
|
-
// Text
|
|
1608
|
-
"textLength",
|
|
1609
|
-
"lengthAdjust",
|
|
1610
|
-
"startOffset",
|
|
1611
|
-
// Filter
|
|
1612
|
-
"filterUnits",
|
|
1613
|
-
"primitiveUnits",
|
|
1614
|
-
"stdDeviation",
|
|
1615
|
-
"baseFrequency",
|
|
1616
|
-
"numOctaves",
|
|
1617
|
-
"surfaceScale",
|
|
1618
|
-
"diffuseConstant",
|
|
1619
|
-
"specularConstant",
|
|
1620
|
-
"specularExponent",
|
|
1621
|
-
"kernelMatrix",
|
|
1622
|
-
"kernelUnitLength",
|
|
1623
|
-
"edgeMode",
|
|
1624
|
-
"preserveAlpha",
|
|
1625
|
-
"targetX",
|
|
1626
|
-
"targetY"
|
|
1627
|
-
// // Animation
|
|
1628
|
-
// 'attributeName',
|
|
1629
|
-
// 'attributeType',
|
|
1630
|
-
// 'calcMode',
|
|
1631
|
-
// 'keyTimes',
|
|
1632
|
-
// 'keySplines',
|
|
1633
|
-
// 'repeatCount',
|
|
1634
|
-
// 'repeatDur'
|
|
1635
|
-
]);
|
|
1636
|
-
function camelCaseToKebabWordIfNeeded(camel) {
|
|
1637
|
-
return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1638
|
-
}
|
|
1639
|
-
function clamp(value, min, max) {
|
|
1640
|
-
return Math.max(min, Math.min(value, max));
|
|
1378
|
+
return inner;
|
|
1641
1379
|
}
|
|
1642
|
-
function
|
|
1643
|
-
if (
|
|
1644
|
-
if (
|
|
1645
|
-
|
|
1646
|
-
const u2 = u * u;
|
|
1647
|
-
const u3 = u2 * u;
|
|
1648
|
-
const t2 = t * t;
|
|
1649
|
-
const t3 = t2 * t;
|
|
1650
|
-
const w0 = u3;
|
|
1651
|
-
const w1 = 3 * t * u2;
|
|
1652
|
-
const w2 = 3 * t2 * u;
|
|
1653
|
-
const w3 = t3;
|
|
1654
|
-
return [
|
|
1655
|
-
w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
|
|
1656
|
-
w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
|
|
1657
|
-
];
|
|
1380
|
+
function invertPartValue(part, value) {
|
|
1381
|
+
if (part === "translate" /* Translate */) return [-value[0], -value[1]];
|
|
1382
|
+
if (part === "rotate" /* Rotate */) return -value;
|
|
1383
|
+
return [1 / value[0], 1 / value[1]];
|
|
1658
1384
|
}
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
const
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1385
|
+
function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
|
|
1386
|
+
var _a;
|
|
1387
|
+
const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
1388
|
+
const animTr = animate == null ? void 0 : animate.transform;
|
|
1389
|
+
const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
|
|
1390
|
+
if (!kfs || !kfs.length) return inner;
|
|
1391
|
+
const translateKfs = [];
|
|
1392
|
+
const rotateKfs = [];
|
|
1393
|
+
const scaleKfs = [];
|
|
1394
|
+
for (const kf of kfs) {
|
|
1395
|
+
const v = ((_a = kf.value) != null ? _a : kf.v) || {};
|
|
1396
|
+
const baseKf = keyframeWith(kf, void 0);
|
|
1397
|
+
if (Array.isArray(v.translate)) {
|
|
1398
|
+
translateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
|
|
1399
|
+
}
|
|
1400
|
+
if (typeof v.rotate === "number") {
|
|
1401
|
+
const rec = { rotate: -v.rotate };
|
|
1402
|
+
if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
|
|
1403
|
+
rotateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
1404
|
+
}
|
|
1405
|
+
if (Array.isArray(v.scale)) {
|
|
1406
|
+
const rec = { scale: [1 / v.scale[0], 1 / v.scale[1]] };
|
|
1407
|
+
if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
|
|
1408
|
+
scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
1409
|
+
}
|
|
1665
1410
|
}
|
|
1666
|
-
|
|
1411
|
+
let n = inner;
|
|
1412
|
+
if (translateKfs.length) n = { type: "g", animate: { transform: { keyframes: translateKfs } }, children: [n] };
|
|
1413
|
+
if (rotateKfs.length) n = { type: "g", animate: { transform: { keyframes: rotateKfs } }, children: [n] };
|
|
1414
|
+
if (scaleKfs.length) n = { type: "g", animate: { transform: { keyframes: scaleKfs } }, children: [n] };
|
|
1415
|
+
return n;
|
|
1667
1416
|
}
|
|
1668
|
-
function
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
const c = 3 * t * t;
|
|
1673
|
-
return [
|
|
1674
|
-
a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
|
|
1675
|
-
a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
|
|
1676
|
-
];
|
|
1417
|
+
function nodeHasBodyTransform(node) {
|
|
1418
|
+
if (typeof node.transform === "string") return true;
|
|
1419
|
+
if (node.transform && typeof node.transform === "object") return true;
|
|
1420
|
+
return hasAnimateTransform(node);
|
|
1677
1421
|
}
|
|
1678
|
-
function
|
|
1679
|
-
const
|
|
1680
|
-
|
|
1681
|
-
const ds = new Float64Array(n);
|
|
1682
|
-
let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
|
|
1683
|
-
ts[0] = 0;
|
|
1684
|
-
ds[0] = 0;
|
|
1685
|
-
let cum = 0;
|
|
1686
|
-
for (let i = 1; i < n; i++) {
|
|
1687
|
-
const t = i / steps;
|
|
1688
|
-
const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
|
|
1689
|
-
const dx = cur[0] - prev[0];
|
|
1690
|
-
const dy = cur[1] - prev[1];
|
|
1691
|
-
cum += Math.sqrt(dx * dx + dy * dy);
|
|
1692
|
-
ts[i] = t;
|
|
1693
|
-
ds[i] = cum;
|
|
1694
|
-
prev = cur;
|
|
1695
|
-
}
|
|
1696
|
-
return { ts, ds };
|
|
1422
|
+
function hasAnimateTransform(node) {
|
|
1423
|
+
const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
1424
|
+
return !!(animate && animate.transform);
|
|
1697
1425
|
}
|
|
1698
|
-
function
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
else hi = mid;
|
|
1426
|
+
function readTransformationFromBody(node) {
|
|
1427
|
+
if (typeof node.transform === "string") {
|
|
1428
|
+
const parts = parseTransformStringToParts(node.transform);
|
|
1429
|
+
if (!parts) return void 0;
|
|
1430
|
+
const out = {};
|
|
1431
|
+
if (parts.translate) out.translate = parts.translate;
|
|
1432
|
+
if (parts.rotate !== void 0) out.rotate = parts.rotate;
|
|
1433
|
+
if (parts.scale) out.scale = { value: parts.scale };
|
|
1434
|
+
if (parts.origin) out.origin = parts.origin;
|
|
1435
|
+
return Object.keys(out).length ? out : void 0;
|
|
1709
1436
|
}
|
|
1710
|
-
|
|
1711
|
-
const dCur = ds[hi];
|
|
1712
|
-
const span = dCur - dPrev;
|
|
1713
|
-
const frac = span > 0 ? (distance - dPrev) / span : 0;
|
|
1714
|
-
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
1437
|
+
return void 0;
|
|
1715
1438
|
}
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
"
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
"filter",
|
|
1756
|
-
// url(#filterId)
|
|
1757
|
-
"clipPath",
|
|
1758
|
-
// clip-path="url(#clipPathId)"
|
|
1759
|
-
"mask",
|
|
1760
|
-
// url(#maskId)
|
|
1761
|
-
"markerStart",
|
|
1762
|
-
// marker-start="url(#markerId)"
|
|
1763
|
-
"markerMid",
|
|
1764
|
-
// marker-mid="url(#markerId)"
|
|
1765
|
-
"markerEnd"
|
|
1766
|
-
// marker-end="url(#markerId)"
|
|
1767
|
-
// 'fill', // url(#gradientId) or url(#patternId)
|
|
1768
|
-
// 'stroke', // url(#gradientId) or url(#patternId)
|
|
1769
|
-
// Don't allow 'cursor', can use external SVG, // url(cursor.svg)
|
|
1770
|
-
];
|
|
1771
|
-
var ALLOWED_RESOURCE_ATTRIBUTES_SET = new Set(ALLOWED_RESOURCE_ATTRIBUTES);
|
|
1772
|
-
var ALLOWED_ATTRIBUTES = [
|
|
1773
|
-
"href",
|
|
1774
|
-
"src",
|
|
1775
|
-
// Presentation
|
|
1776
|
-
"fill",
|
|
1777
|
-
"fillOpacity",
|
|
1778
|
-
"fillRule",
|
|
1779
|
-
"stroke",
|
|
1780
|
-
"strokeWidth",
|
|
1781
|
-
"strokeOpacity",
|
|
1782
|
-
"strokeLinecap",
|
|
1783
|
-
"strokeLinejoin",
|
|
1784
|
-
"strokeMiterlimit",
|
|
1785
|
-
"strokeDasharray",
|
|
1786
|
-
"strokeDashoffset",
|
|
1787
|
-
"opacity",
|
|
1788
|
-
"transform",
|
|
1789
|
-
// Geometry
|
|
1790
|
-
"x",
|
|
1791
|
-
"y",
|
|
1792
|
-
"cx",
|
|
1793
|
-
"cy",
|
|
1794
|
-
"r",
|
|
1795
|
-
"rx",
|
|
1796
|
-
"ry",
|
|
1797
|
-
"width",
|
|
1798
|
-
"height",
|
|
1799
|
-
"d",
|
|
1800
|
-
"x1",
|
|
1801
|
-
"y1",
|
|
1802
|
-
"x2",
|
|
1803
|
-
"y2",
|
|
1804
|
-
"points",
|
|
1805
|
-
"dx",
|
|
1806
|
-
"dy",
|
|
1807
|
-
// Font
|
|
1808
|
-
"fontSize",
|
|
1809
|
-
"fontFamily",
|
|
1810
|
-
"fontWeight",
|
|
1811
|
-
"fontStyle",
|
|
1812
|
-
// Text
|
|
1813
|
-
"textAnchor",
|
|
1814
|
-
"letterSpacing",
|
|
1815
|
-
"wordSpacing",
|
|
1816
|
-
"space",
|
|
1817
|
-
"xml:space",
|
|
1818
|
-
"textDecoration",
|
|
1819
|
-
"textTransform",
|
|
1820
|
-
"whiteSpace",
|
|
1821
|
-
"white-space",
|
|
1822
|
-
"dominantBaseline",
|
|
1823
|
-
"alignmentBaseline",
|
|
1824
|
-
"rotate",
|
|
1825
|
-
// per-glyph rotation array, currently not supported
|
|
1826
|
-
// Structure
|
|
1827
|
-
"id",
|
|
1828
|
-
"class",
|
|
1829
|
-
"viewBox",
|
|
1830
|
-
"preserveAspectRatio",
|
|
1831
|
-
// Gradient/Pattern
|
|
1832
|
-
"offset",
|
|
1833
|
-
"stopColor",
|
|
1834
|
-
"stopOpacity",
|
|
1835
|
-
"gradientTransform",
|
|
1836
|
-
// Clippath/Mask
|
|
1837
|
-
"clipPath",
|
|
1838
|
-
"mask",
|
|
1839
|
-
// Motion path
|
|
1840
|
-
"offsetPath",
|
|
1841
|
-
"offsetDistance",
|
|
1842
|
-
"offsetRotate",
|
|
1843
|
-
"offsetAnchor",
|
|
1844
|
-
"offsetPosition",
|
|
1845
|
-
// Text path
|
|
1846
|
-
"startOffset",
|
|
1847
|
-
"textLength",
|
|
1848
|
-
"lengthAdjust",
|
|
1849
|
-
// Filter
|
|
1850
|
-
"filter",
|
|
1851
|
-
"stdDeviation",
|
|
1852
|
-
"in",
|
|
1853
|
-
"in2",
|
|
1854
|
-
"result",
|
|
1855
|
-
"mode",
|
|
1856
|
-
...ALLOWED_RESOURCE_ATTRIBUTES
|
|
1857
|
-
];
|
|
1858
|
-
var ALLOWED_ATTRIBUTES_LOW_SET = new Set(ALLOWED_ATTRIBUTES.map((str) => str.toLowerCase()));
|
|
1859
|
-
function sanitiseAttributeValue(name, value) {
|
|
1860
|
-
const nameLower = name.toLowerCase();
|
|
1861
|
-
if (!ALLOWED_ATTRIBUTES_LOW_SET.has(nameLower)) {
|
|
1862
|
-
console.warn("Attribute not in whitelist: ", nameLower);
|
|
1863
|
-
return void 0;
|
|
1864
|
-
}
|
|
1865
|
-
if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopColor") {
|
|
1866
|
-
const str = String(value);
|
|
1867
|
-
if (str.includes("url(") && !/^url\(#[^)]+\)$/.test(str)) {
|
|
1868
|
-
console.warn('Attribute "' + nameLower + '" blocked: url() references must be internal url(#id), got:', value);
|
|
1869
|
-
return void 0;
|
|
1439
|
+
function parseTransformStringToParts(s) {
|
|
1440
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
1441
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
1442
|
+
let m;
|
|
1443
|
+
const ops = [];
|
|
1444
|
+
while ((m = re.exec(s)) !== null) {
|
|
1445
|
+
const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
|
|
1446
|
+
ops.push({ name: m[1], args });
|
|
1447
|
+
}
|
|
1448
|
+
if (!ops.length) return void 0;
|
|
1449
|
+
const last = ops[ops.length - 1];
|
|
1450
|
+
if (last.name === "translate") {
|
|
1451
|
+
for (let j = ops.length - 2; j >= 0; j--) {
|
|
1452
|
+
const cand = ops[j];
|
|
1453
|
+
if (cand.name !== "translate") continue;
|
|
1454
|
+
const ox = (_a = cand.args[0]) != null ? _a : 0;
|
|
1455
|
+
const oy = (_b = cand.args[1]) != null ? _b : 0;
|
|
1456
|
+
const lx = (_c = last.args[0]) != null ? _c : 0;
|
|
1457
|
+
const ly = (_d = last.args[1]) != null ? _d : 0;
|
|
1458
|
+
if (lx !== -ox || ly !== -oy) continue;
|
|
1459
|
+
const out2 = {};
|
|
1460
|
+
out2.origin = [ox, oy];
|
|
1461
|
+
for (let k = 0; k < j; k++) {
|
|
1462
|
+
if (ops[k].name === "translate") {
|
|
1463
|
+
const tx = (_e = ops[k].args[0]) != null ? _e : 0;
|
|
1464
|
+
const ty = (_f = ops[k].args[1]) != null ? _f : 0;
|
|
1465
|
+
out2.translate = out2.translate ? [out2.translate[0] + tx, out2.translate[1] + ty] : [tx, ty];
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
for (let k = j + 1; k < ops.length - 1; k++) {
|
|
1469
|
+
const op = ops[k];
|
|
1470
|
+
if (op.name === "rotate") out2.rotate = ((_g = out2.rotate) != null ? _g : 0) + ((_h = op.args[0]) != null ? _h : 0);
|
|
1471
|
+
else if (op.name === "scale") {
|
|
1472
|
+
const sx = (_i = op.args[0]) != null ? _i : 1;
|
|
1473
|
+
const sy = op.args.length > 1 ? op.args[1] : sx;
|
|
1474
|
+
out2.scale = out2.scale ? [out2.scale[0] * sx, out2.scale[1] * sy] : [sx, sy];
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
return out2;
|
|
1870
1478
|
}
|
|
1871
|
-
return value;
|
|
1872
1479
|
}
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1480
|
+
let translate;
|
|
1481
|
+
let rotate;
|
|
1482
|
+
let scale;
|
|
1483
|
+
for (const op of ops) {
|
|
1484
|
+
if (op.name === "translate") {
|
|
1485
|
+
const dx = (_j = op.args[0]) != null ? _j : 0;
|
|
1486
|
+
const dy = (_k = op.args[1]) != null ? _k : 0;
|
|
1487
|
+
translate = translate ? [translate[0] + dx, translate[1] + dy] : [dx, dy];
|
|
1488
|
+
} else if (op.name === "rotate") {
|
|
1489
|
+
rotate = (rotate != null ? rotate : 0) + ((_l = op.args[0]) != null ? _l : 0);
|
|
1490
|
+
} else if (op.name === "scale") {
|
|
1491
|
+
const sx = (_m = op.args[0]) != null ? _m : 1;
|
|
1492
|
+
const sy = op.args.length > 1 ? op.args[1] : sx;
|
|
1493
|
+
scale = scale ? [scale[0] * sx, scale[1] * sy] : [sx, sy];
|
|
1880
1494
|
}
|
|
1881
|
-
return void 0;
|
|
1882
|
-
}
|
|
1883
|
-
return value;
|
|
1884
|
-
}
|
|
1885
|
-
function createElement(tagName, normalisedProps, style, children, textContent) {
|
|
1886
|
-
if (!ALLOWED_SVG_TAGS_LOWER_CASE.has(tagName.toLowerCase())) {
|
|
1887
|
-
console.warn("Attribute not in whitelist: ", tagName);
|
|
1888
|
-
return null;
|
|
1889
1495
|
}
|
|
1890
|
-
const
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1496
|
+
const out = {};
|
|
1497
|
+
if (translate) out.translate = translate;
|
|
1498
|
+
if (rotate !== void 0) out.rotate = rotate;
|
|
1499
|
+
if (scale) out.scale = scale;
|
|
1500
|
+
return Object.keys(out).length ? out : void 0;
|
|
1501
|
+
}
|
|
1502
|
+
function wrapAncestorChainCompensation(inner, maskedNode, sourceId, ctx, includeTargetOwn) {
|
|
1503
|
+
const sourceNode = ctx.idMap.get(sourceId);
|
|
1504
|
+
const targetAncestors = ctx.maskAncestorChains.get(maskedNode) || [];
|
|
1505
|
+
const targetOwn = includeTargetOwn ? extractTranslateOnly(maskedNode, ctx) : void 0;
|
|
1506
|
+
const targetChain = targetOwn ? [...targetAncestors, targetOwn] : targetAncestors;
|
|
1507
|
+
const sourceChain = sourceNode && ctx.maskAncestorChains.get(sourceNode) || [];
|
|
1508
|
+
if (!targetChain.length && !sourceChain.length) return inner;
|
|
1509
|
+
const times = /* @__PURE__ */ new Set();
|
|
1510
|
+
for (const a of targetChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
|
|
1511
|
+
for (const a of sourceChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
|
|
1512
|
+
const animated = times.size > 0;
|
|
1513
|
+
if (!animated) {
|
|
1514
|
+
const tgt = sumStaticTranslate(targetChain);
|
|
1515
|
+
const src = sumStaticTranslate(sourceChain);
|
|
1516
|
+
const dx = src[0] - tgt[0];
|
|
1517
|
+
const dy = src[1] - tgt[1];
|
|
1518
|
+
if (dx === 0 && dy === 0) return inner;
|
|
1519
|
+
return { type: "g", transform: "translate(" + dx + "," + dy + ")", children: [inner] };
|
|
1520
|
+
}
|
|
1521
|
+
const sortedTimes = Array.from(times).sort((a, b) => a - b);
|
|
1522
|
+
const keyframes = sortedTimes.map((t) => {
|
|
1523
|
+
const tgt = sumTranslateAt(targetChain, t);
|
|
1524
|
+
const src = sumTranslateAt(sourceChain, t);
|
|
1525
|
+
return { time: t, value: { translate: [src[0] - tgt[0], src[1] - tgt[1]] } };
|
|
1526
|
+
});
|
|
1527
|
+
return { type: "g", animate: { transform: { keyframes } }, children: [inner] };
|
|
1528
|
+
}
|
|
1529
|
+
function sumStaticTranslate(chain) {
|
|
1530
|
+
let x = 0, y = 0;
|
|
1531
|
+
for (const a of chain) {
|
|
1532
|
+
if (a.translate) {
|
|
1533
|
+
x += a.translate[0];
|
|
1534
|
+
y += a.translate[1];
|
|
1535
|
+
}
|
|
1896
1536
|
}
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1537
|
+
return [x, y];
|
|
1538
|
+
}
|
|
1539
|
+
function sumTranslateAt(chain, t) {
|
|
1540
|
+
let x = 0, y = 0;
|
|
1541
|
+
for (const a of chain) {
|
|
1542
|
+
if (a.translateKeyframes && a.translateKeyframes.length) {
|
|
1543
|
+
const v = interpKfs(a.translateKeyframes, t);
|
|
1544
|
+
x += v[0];
|
|
1545
|
+
y += v[1];
|
|
1546
|
+
} else if (a.translate) {
|
|
1547
|
+
x += a.translate[0];
|
|
1548
|
+
y += a.translate[1];
|
|
1900
1549
|
}
|
|
1901
1550
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1551
|
+
return [x, y];
|
|
1552
|
+
}
|
|
1553
|
+
function interpKfs(kfs, t) {
|
|
1554
|
+
if (t <= kfs[0].time) return kfs[0].value;
|
|
1555
|
+
if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
|
|
1556
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
1557
|
+
if (t <= kfs[i].time) {
|
|
1558
|
+
const prev = kfs[i - 1];
|
|
1559
|
+
const cur = kfs[i];
|
|
1560
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
1561
|
+
return [prev.value[0] + (cur.value[0] - prev.value[0]) * a, prev.value[1] + (cur.value[1] - prev.value[1]) * a];
|
|
1905
1562
|
}
|
|
1906
1563
|
}
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1564
|
+
return kfs[kfs.length - 1].value;
|
|
1565
|
+
}
|
|
1566
|
+
function collectMaskAncestorChains(root, ctx) {
|
|
1567
|
+
const interestingNodes = /* @__PURE__ */ new Set();
|
|
1568
|
+
const collectInterestingNodes = (n) => {
|
|
1569
|
+
var _a, _b;
|
|
1570
|
+
const href = (_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.href;
|
|
1571
|
+
if (typeof href === "string") {
|
|
1572
|
+
interestingNodes.add(n);
|
|
1573
|
+
const sourceNode = ctx.idMap.get(href);
|
|
1574
|
+
if (sourceNode) interestingNodes.add(sourceNode);
|
|
1575
|
+
}
|
|
1576
|
+
if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
|
|
1577
|
+
};
|
|
1578
|
+
collectInterestingNodes(root);
|
|
1579
|
+
if (interestingNodes.size === 0) return;
|
|
1580
|
+
const walk = (node, chain) => {
|
|
1581
|
+
if (interestingNodes.has(node)) ctx.maskAncestorChains.set(node, chain);
|
|
1582
|
+
if (Array.isArray(node.children)) {
|
|
1583
|
+
const own = extractTranslateOnly(node, ctx);
|
|
1584
|
+
const next = own ? [...chain, own] : chain;
|
|
1585
|
+
for (const ch of node.children) walk(ch, next);
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1588
|
+
walk(root, []);
|
|
1917
1589
|
}
|
|
1918
|
-
function
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1590
|
+
function extractTranslateOnly(node, ctx) {
|
|
1591
|
+
var _a, _b, _c;
|
|
1592
|
+
const tr = node.transform;
|
|
1593
|
+
const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
|
|
1594
|
+
if (tr === void 0 && !animateBlock) return void 0;
|
|
1595
|
+
const out = {};
|
|
1596
|
+
if (typeof tr === "string") {
|
|
1597
|
+
const parts = parseTranslateOnlyFromString(tr, ctx);
|
|
1598
|
+
if (parts) out.translate = parts;
|
|
1599
|
+
} else if (tr && typeof tr === "object") {
|
|
1600
|
+
const value = tr.value;
|
|
1601
|
+
if (value && typeof value === "object" && Array.isArray(value.translate)) {
|
|
1602
|
+
out.translate = [value.translate[0] || 0, value.translate[1] || 0];
|
|
1603
|
+
}
|
|
1604
|
+
if (value && (value.rotate !== void 0 || value.scale !== void 0 || value.skew !== void 0)) {
|
|
1605
|
+
ctx.warnings.push("maskedBy ancestor: non-translate transform parts ignored (rotate/scale not yet supported)");
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
if (animateBlock && Array.isArray(animateBlock.keyframes)) {
|
|
1609
|
+
const kfs = animateBlock.keyframes;
|
|
1610
|
+
const translateKfs = [];
|
|
1611
|
+
for (const kf of kfs) {
|
|
1612
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
1613
|
+
const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
|
|
1614
|
+
if (v && typeof v === "object" && Array.isArray(v.translate)) {
|
|
1615
|
+
translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
|
|
1616
|
+
if (v.rotate !== void 0 || v.scale !== void 0 || v.skew !== void 0) {
|
|
1617
|
+
ctx.warnings.push("maskedBy ancestor: animated non-translate parts ignored");
|
|
1618
|
+
}
|
|
1932
1619
|
}
|
|
1933
|
-
if (key === "rotate") value = value + "deg";
|
|
1934
|
-
propsCopy["transform"] = key + "(" + value + ")";
|
|
1935
|
-
} else if (value !== void 0 && value !== null) {
|
|
1936
|
-
propsCopy[key] = String(value);
|
|
1937
1620
|
}
|
|
1621
|
+
if (translateKfs.length) out.translateKeyframes = translateKfs;
|
|
1938
1622
|
}
|
|
1939
|
-
return
|
|
1623
|
+
return out.translate || out.translateKeyframes ? out : void 0;
|
|
1940
1624
|
}
|
|
1941
|
-
function
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
let
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1625
|
+
function parseTranslateOnlyFromString(s, ctx) {
|
|
1626
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
1627
|
+
let m;
|
|
1628
|
+
let x = 0, y = 0;
|
|
1629
|
+
let seen = false;
|
|
1630
|
+
let droppedNonTranslate = false;
|
|
1631
|
+
while ((m = re.exec(s)) !== null) {
|
|
1632
|
+
const name = m[1];
|
|
1633
|
+
const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
|
|
1634
|
+
if (name === "translate") {
|
|
1635
|
+
x += args[0] || 0;
|
|
1636
|
+
y += args[1] || 0;
|
|
1637
|
+
seen = true;
|
|
1638
|
+
} else {
|
|
1639
|
+
droppedNonTranslate = true;
|
|
1954
1640
|
}
|
|
1955
1641
|
}
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
getNormalizedProps(props),
|
|
1959
|
-
resolvedStyle,
|
|
1960
|
-
childElements,
|
|
1961
|
-
props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
|
|
1962
|
-
);
|
|
1642
|
+
if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
|
|
1643
|
+
return seen ? [x, y] : void 0;
|
|
1963
1644
|
}
|
|
1964
1645
|
|
|
1965
|
-
// src/
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1646
|
+
// src/effects/refEffect.ts
|
|
1647
|
+
var CONTENT_SUBREF = "content";
|
|
1648
|
+
function applyRefAndTransformationEffect(node, ref, transformation, ctx) {
|
|
1649
|
+
if (ref) {
|
|
1650
|
+
const baseId = ref.baseId;
|
|
1651
|
+
if (!baseId) {
|
|
1652
|
+
ctx.errors.push("ref: missing baseId");
|
|
1653
|
+
} else {
|
|
1654
|
+
const targetId = ref.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
|
|
1655
|
+
node.href = "#" + targetId;
|
|
1656
|
+
}
|
|
1972
1657
|
}
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1658
|
+
return applyTransformationEffect(node, transformation, ctx);
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
// src/effects/repeaterEffect.ts
|
|
1662
|
+
function applyRepeaterEffect(node, fx, ctx) {
|
|
1663
|
+
var _a, _b;
|
|
1664
|
+
if (!fx) return node;
|
|
1665
|
+
const copies = (_a = fx.copies) != null ? _a : 1;
|
|
1666
|
+
if (copies < 1) {
|
|
1667
|
+
ctx.errors.push("repeater.copies invalid: " + fx.copies);
|
|
1668
|
+
return node;
|
|
1669
|
+
}
|
|
1670
|
+
const sharedTransform = node.transform;
|
|
1671
|
+
const sharedAnimTransform = (_b = node.animate) == null ? void 0 : _b.transform;
|
|
1672
|
+
const base = clone(node);
|
|
1673
|
+
delete base.transform;
|
|
1674
|
+
if (base.animate) {
|
|
1675
|
+
delete base.animate.transform;
|
|
1676
|
+
if (Object.keys(base.animate).length === 0) delete base.animate;
|
|
1677
|
+
}
|
|
1678
|
+
const children = [base];
|
|
1679
|
+
for (let i = 1; i < copies; i++) {
|
|
1680
|
+
const baseClone = clone(base);
|
|
1681
|
+
const synthFx = synthesisePerCopyFx(fx, i);
|
|
1682
|
+
const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;
|
|
1683
|
+
children.push(wrapped);
|
|
1684
|
+
}
|
|
1685
|
+
const wrapper = { type: "g", children };
|
|
1686
|
+
if (sharedTransform !== void 0) wrapper.transform = sharedTransform;
|
|
1687
|
+
if (sharedAnimTransform !== void 0) wrapper.animate = { transform: sharedAnimTransform };
|
|
1688
|
+
return wrapper;
|
|
1689
|
+
}
|
|
1690
|
+
function synthesisePerCopyFx(fx, i) {
|
|
1691
|
+
const out = {};
|
|
1692
|
+
if (fx.translate !== void 0) {
|
|
1693
|
+
out.translate = mapAnimatableVec2(fx.translate, (v) => [v[0] * i, v[1] * i]);
|
|
1694
|
+
}
|
|
1695
|
+
if (fx.rotate !== void 0) {
|
|
1696
|
+
out.rotate = mapAnimatableNumber(fx.rotate, (v) => v * i);
|
|
1697
|
+
}
|
|
1698
|
+
if (fx.scale !== void 0) {
|
|
1699
|
+
out.scale = synthesiseScale(fx.scale, i);
|
|
1700
|
+
}
|
|
1701
|
+
if (fx.origin !== void 0) {
|
|
1702
|
+
out.origin = fx.origin;
|
|
1703
|
+
}
|
|
1704
|
+
return Object.keys(out).length ? out : void 0;
|
|
1705
|
+
}
|
|
1706
|
+
function mapAnimatableVec2(raw, fn) {
|
|
1707
|
+
if (Array.isArray(raw)) return fn(raw);
|
|
1708
|
+
if (raw && typeof raw === "object") {
|
|
1709
|
+
const obj = raw;
|
|
1710
|
+
if (Array.isArray(obj.keyframes)) {
|
|
1711
|
+
return __spreadProps(__spreadValues({}, obj), {
|
|
1712
|
+
keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
|
|
1713
|
+
});
|
|
1990
1714
|
}
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
case "load": {
|
|
1994
|
-
const startHandler = () => start();
|
|
1995
|
-
if (document.readyState === "complete") {
|
|
1996
|
-
startHandler();
|
|
1997
|
-
} else {
|
|
1998
|
-
window.addEventListener("load", startHandler, { once: true });
|
|
1999
|
-
}
|
|
2000
|
-
break;
|
|
1715
|
+
if (obj.value !== void 0) {
|
|
1716
|
+
return __spreadProps(__spreadValues({}, obj), { value: fn(obj.value) });
|
|
2001
1717
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
1718
|
+
}
|
|
1719
|
+
return raw;
|
|
1720
|
+
}
|
|
1721
|
+
function mapAnimatableNumber(raw, fn) {
|
|
1722
|
+
if (typeof raw === "number") return fn(raw);
|
|
1723
|
+
if (raw && typeof raw === "object") {
|
|
1724
|
+
const obj = raw;
|
|
1725
|
+
if (Array.isArray(obj.keyframes)) {
|
|
1726
|
+
return __spreadProps(__spreadValues({}, obj), {
|
|
1727
|
+
keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
|
|
1728
|
+
});
|
|
2008
1729
|
}
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
if (api.isPlaying()) {
|
|
2012
|
-
handleEndAction();
|
|
2013
|
-
} else {
|
|
2014
|
-
start();
|
|
2015
|
-
}
|
|
2016
|
-
};
|
|
2017
|
-
root.addEventListener("click", clickHandler);
|
|
2018
|
-
break;
|
|
1730
|
+
if (obj.value !== void 0) {
|
|
1731
|
+
return __spreadProps(__spreadValues({}, obj), { value: fn(obj.value) });
|
|
2019
1732
|
}
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
)
|
|
2033
|
-
|
|
2034
|
-
|
|
1733
|
+
}
|
|
1734
|
+
return raw;
|
|
1735
|
+
}
|
|
1736
|
+
function synthesiseScale(raw, i) {
|
|
1737
|
+
const scalePowerFromPercent = (v) => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];
|
|
1738
|
+
const scalePowerFromUnits = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
|
|
1739
|
+
if (Array.isArray(raw)) {
|
|
1740
|
+
return { value: scalePowerFromPercent(raw) };
|
|
1741
|
+
}
|
|
1742
|
+
if (raw && typeof raw === "object") {
|
|
1743
|
+
const obj = raw;
|
|
1744
|
+
if (Array.isArray(obj.keyframes)) {
|
|
1745
|
+
return __spreadProps(__spreadValues({}, obj), {
|
|
1746
|
+
keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: scalePowerFromUnits(kf.value) }) : kf)
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1749
|
+
if (obj.value !== void 0) {
|
|
1750
|
+
return __spreadProps(__spreadValues({}, obj), { value: scalePowerFromPercent(obj.value) });
|
|
2035
1751
|
}
|
|
2036
|
-
case "programmatic":
|
|
2037
|
-
break;
|
|
2038
1752
|
}
|
|
2039
|
-
return
|
|
1753
|
+
return raw;
|
|
2040
1754
|
}
|
|
2041
1755
|
|
|
2042
|
-
// src/
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
if (anim.autoOrient) return true;
|
|
2048
|
-
for (const kf of kfs) {
|
|
2049
|
-
if (kf.tangentIn || kf.tangentOut) return true;
|
|
2050
|
-
}
|
|
2051
|
-
return false;
|
|
1756
|
+
// src/effects/retimeEffect.ts
|
|
1757
|
+
var RETIME_MATERIALISATION_MODE_INLINE_G = false;
|
|
1758
|
+
function asRetime(r) {
|
|
1759
|
+
var _a, _b;
|
|
1760
|
+
return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
|
|
2052
1761
|
}
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
const to = prevKf.tangentOut;
|
|
2058
|
-
const ti = nextKf.tangentIn;
|
|
2059
|
-
const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
|
|
2060
|
-
const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
|
|
2061
|
-
const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
|
|
2062
|
-
const entry = {
|
|
2063
|
-
P0: prevPos,
|
|
2064
|
-
P1,
|
|
2065
|
-
P2,
|
|
2066
|
-
P3: nextPos,
|
|
2067
|
-
lut,
|
|
2068
|
-
totalArc: lut.ds[lut.ds.length - 1]
|
|
1762
|
+
function concatRetime(child, parent) {
|
|
1763
|
+
return {
|
|
1764
|
+
start: parent.start + parent.stretch * child.start,
|
|
1765
|
+
stretch: parent.stretch * child.stretch
|
|
2069
1766
|
};
|
|
2070
|
-
_segmentCache.set(prevKf, entry);
|
|
2071
|
-
return entry;
|
|
2072
1767
|
}
|
|
2073
|
-
function
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
const
|
|
2079
|
-
|
|
2080
|
-
|
|
1768
|
+
function applyAllRetimeEffects(root, ctx) {
|
|
1769
|
+
var _a;
|
|
1770
|
+
ctx.idMap.clear();
|
|
1771
|
+
indexById(root, ctx.idMap);
|
|
1772
|
+
const sites = [];
|
|
1773
|
+
const collect = (n) => {
|
|
1774
|
+
var _a2, _b;
|
|
1775
|
+
if ((_a2 = n.effects) == null ? void 0 : _a2.retime) sites.push(n);
|
|
1776
|
+
(_b = n.children) == null ? void 0 : _b.forEach(collect);
|
|
1777
|
+
};
|
|
1778
|
+
collect(root);
|
|
1779
|
+
for (const useNode of sites) {
|
|
1780
|
+
const retime = (_a = useNode.effects) == null ? void 0 : _a.retime;
|
|
1781
|
+
if (!retime) continue;
|
|
1782
|
+
delete useNode.effects.retime;
|
|
1783
|
+
if (Object.keys(useNode.effects).length === 0) delete useNode.effects;
|
|
1784
|
+
materialiseRetime(useNode, asRetime(retime), ctx);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
function materialiseRetime(useNode, retime, ctx) {
|
|
1788
|
+
const targetId = stripHash(useNode.href);
|
|
1789
|
+
if (!targetId) {
|
|
1790
|
+
ctx.errors.push("retime: <use> has no href to follow");
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
const chainRootId = buildChainClone(targetId, retime, ctx, /* @__PURE__ */ new Set());
|
|
1794
|
+
if (!chainRootId) return;
|
|
1795
|
+
if (RETIME_MATERIALISATION_MODE_INLINE_G) {
|
|
1796
|
+
const cloneNode = ctx.idMap.get(chainRootId);
|
|
1797
|
+
useNode.type = "g";
|
|
1798
|
+
delete useNode.href;
|
|
1799
|
+
useNode.children = [cloneNode];
|
|
1800
|
+
applyUseOffsetToG(useNode);
|
|
1801
|
+
ctx.defs = ctx.defs.filter((d) => d !== cloneNode);
|
|
1802
|
+
} else {
|
|
1803
|
+
useNode.href = "#" + chainRootId;
|
|
1804
|
+
}
|
|
2081
1805
|
}
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
1806
|
+
function buildChainClone(targetId, accum, ctx, chain) {
|
|
1807
|
+
var _a, _b;
|
|
1808
|
+
if (chain.has(targetId)) {
|
|
1809
|
+
ctx.errors.push('retime: loop via "' + targetId + '"');
|
|
1810
|
+
return void 0;
|
|
1811
|
+
}
|
|
1812
|
+
const target = ctx.idMap.get(targetId);
|
|
1813
|
+
if (!target) {
|
|
1814
|
+
ctx.warnings.push('retime: target "' + targetId + '" not found');
|
|
1815
|
+
return void 0;
|
|
1816
|
+
}
|
|
1817
|
+
const cloneNode = clone(target);
|
|
1818
|
+
regenerateIdsInClone(cloneNode, ctx);
|
|
1819
|
+
if (target.type === "use") {
|
|
1820
|
+
remapKeyframeTimesOnly(cloneNode, accum.start, accum.stretch);
|
|
1821
|
+
} else {
|
|
1822
|
+
remapKeyframeTimes(cloneNode, accum.start, accum.stretch);
|
|
1823
|
+
}
|
|
1824
|
+
if ((_a = cloneNode.effects) == null ? void 0 : _a.retime) {
|
|
1825
|
+
delete cloneNode.effects.retime;
|
|
1826
|
+
if (Object.keys(cloneNode.effects).length === 0) delete cloneNode.effects;
|
|
1827
|
+
}
|
|
1828
|
+
if (target.type === "use" && target.href) {
|
|
1829
|
+
const subId = stripHash(target.href);
|
|
1830
|
+
if (subId) {
|
|
1831
|
+
const innerRetime = (_b = target.effects) == null ? void 0 : _b.retime;
|
|
1832
|
+
const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
|
|
1833
|
+
const subChain = new Set(chain);
|
|
1834
|
+
subChain.add(targetId);
|
|
1835
|
+
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
1836
|
+
if (subId2) cloneNode.href = "#" + subId2;
|
|
2095
1837
|
}
|
|
2096
1838
|
}
|
|
2097
|
-
|
|
1839
|
+
ctx.defs.push(cloneNode);
|
|
1840
|
+
if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
|
|
1841
|
+
return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
|
|
2098
1842
|
}
|
|
2099
|
-
function
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
1843
|
+
function remapKeyframeTimes(node, start, stretch) {
|
|
1844
|
+
var _a;
|
|
1845
|
+
remapKeyframeTimesOnly(node, start, stretch);
|
|
1846
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => remapKeyframeTimes(c, start, stretch));
|
|
1847
|
+
}
|
|
1848
|
+
function remapKeyframeTimesOnly(node, start, stretch) {
|
|
1849
|
+
const remap2 = (kfs) => {
|
|
1850
|
+
for (const kf of kfs) if (typeof kf.time === "number") kf.time = start + kf.time * stretch;
|
|
1851
|
+
};
|
|
1852
|
+
if (node.transform && typeof node.transform === "object" && Array.isArray(node.transform.keyframes)) {
|
|
1853
|
+
remap2(node.transform.keyframes);
|
|
1854
|
+
}
|
|
1855
|
+
if (node.animate && typeof node.animate === "object") {
|
|
1856
|
+
for (const prop of Object.keys(node.animate)) {
|
|
1857
|
+
const anim = node.animate[prop];
|
|
1858
|
+
if (anim && Array.isArray(anim.keyframes)) remap2(anim.keyframes);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
// src/effects/textAlongPathEffect.ts
|
|
1864
|
+
function applyTextAlongPathEffect(node, fx, _ctx) {
|
|
1865
|
+
var _a;
|
|
1866
|
+
if (!fx) return node;
|
|
1867
|
+
const href = typeof fx.href === "string" && !fx.href.startsWith("#") ? "#" + fx.href : fx.href;
|
|
1868
|
+
const textPath = {
|
|
1869
|
+
type: "textPath",
|
|
1870
|
+
href,
|
|
1871
|
+
children: (_a = node.children) != null ? _a : []
|
|
1872
|
+
};
|
|
1873
|
+
if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
|
|
1874
|
+
if (fx.method !== void 0) textPath.method = fx.method;
|
|
1875
|
+
if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
|
|
1876
|
+
applyAnimatableNumber(textPath, "startOffset", fx.startOffset);
|
|
1877
|
+
applyAnimatableNumber(textPath, "textLength", fx.textLength);
|
|
1878
|
+
node.children = [textPath];
|
|
1879
|
+
return node;
|
|
1880
|
+
}
|
|
1881
|
+
function applyAnimatableNumber(node, attrName, raw) {
|
|
1882
|
+
if (raw === void 0 || raw === null) return;
|
|
1883
|
+
if (typeof raw === "number") {
|
|
1884
|
+
node[attrName] = String(raw);
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1887
|
+
if (typeof raw === "object") {
|
|
1888
|
+
const obj = raw;
|
|
1889
|
+
if (Array.isArray(obj.keyframes)) {
|
|
1890
|
+
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
1891
|
+
const animate = __spreadValues({}, prevAnimate || {});
|
|
1892
|
+
animate[attrName] = { keyframes: obj.keyframes };
|
|
1893
|
+
node.animate = animate;
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1896
|
+
if (typeof obj.value === "number") {
|
|
1897
|
+
node[attrName] = String(obj.value);
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
// src/PxAnimatorUtil.ts
|
|
1904
|
+
function bezierToSvgPath(path) {
|
|
1905
|
+
var _a, _b, _c, _d;
|
|
1906
|
+
const v = path.v;
|
|
1907
|
+
const i = path.i;
|
|
1908
|
+
const o = path.o;
|
|
1909
|
+
const c = path.c;
|
|
1910
|
+
if (!v.length) return "";
|
|
1911
|
+
const d = [];
|
|
1912
|
+
const len = v.length;
|
|
1913
|
+
d.push("M" + v[0][0] + "," + v[0][1]);
|
|
1914
|
+
for (let idx = 1; idx < len; idx++) {
|
|
1915
|
+
const prevV = v[idx - 1];
|
|
1916
|
+
const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
|
|
1917
|
+
const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
|
|
1918
|
+
const currV = v[idx];
|
|
1919
|
+
const isLine = prevO[0] === prevV[0] && prevO[1] === prevV[1] && (currI[0] === currV[0] && currI[1] === currV[1]);
|
|
1920
|
+
if (isLine) {
|
|
1921
|
+
d.push("L" + currV[0] + "," + currV[1]);
|
|
1922
|
+
} else {
|
|
1923
|
+
d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
if (c && len > 0) {
|
|
1927
|
+
const lastV = v[len - 1];
|
|
1928
|
+
const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
|
|
1929
|
+
const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
|
|
1930
|
+
const firstV = v[0];
|
|
1931
|
+
const isLine = lastO[0] === lastV[0] && lastO[1] === lastV[1] && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
|
|
1932
|
+
if (!isLine) {
|
|
1933
|
+
d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
|
|
1934
|
+
}
|
|
1935
|
+
d.push("z");
|
|
1936
|
+
}
|
|
1937
|
+
return d.join("");
|
|
1938
|
+
}
|
|
1939
|
+
function interpolateNum(a, b, t) {
|
|
1940
|
+
return a + (b - a) * t;
|
|
1941
|
+
}
|
|
1942
|
+
function interpolateVec(a, b, t) {
|
|
1943
|
+
const res = [];
|
|
1944
|
+
const count = Math.max(a.length, b.length);
|
|
1945
|
+
for (let i = 0; i < count; i++) {
|
|
1946
|
+
res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
|
|
1947
|
+
}
|
|
1948
|
+
return res;
|
|
1949
|
+
}
|
|
1950
|
+
function interpolateColor(a, b, t) {
|
|
1951
|
+
return [
|
|
1952
|
+
interpolateNum(a[0] || 0, b[0] || 0, t),
|
|
1953
|
+
interpolateNum(a[1] || 0, b[1] || 0, t),
|
|
1954
|
+
interpolateNum(a[2] || 0, b[2] || 0, t),
|
|
1955
|
+
interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
|
|
1956
|
+
];
|
|
1957
|
+
}
|
|
1958
|
+
function interpolateBeziers(paths1, paths2, progress) {
|
|
1959
|
+
const count = Math.max(paths1.length, paths2.length);
|
|
1960
|
+
const res = [];
|
|
1961
|
+
for (let i = 0; i < count; i++) {
|
|
1962
|
+
res.push(interpolateBezier(paths1[i], paths2[i], progress));
|
|
1963
|
+
}
|
|
1964
|
+
return res;
|
|
1965
|
+
}
|
|
1966
|
+
function interpolateBezier(path1, path2, progress) {
|
|
1967
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1968
|
+
if (!path1 || !path2) return path1 || path2 || { v: [] };
|
|
1969
|
+
const t = Math.min(Math.max(progress, 0), 1);
|
|
1970
|
+
const len = Math.min(path1.v.length, path2.v.length);
|
|
1971
|
+
const v = [];
|
|
1972
|
+
const i = [];
|
|
1973
|
+
const o = [];
|
|
1974
|
+
for (let idx = 0; idx < len; idx++) {
|
|
1975
|
+
const v1 = path1.v[idx];
|
|
1976
|
+
const v2 = path2.v[idx];
|
|
1977
|
+
v.push(interpolateVec(v1, v2, t));
|
|
1978
|
+
const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
|
|
1979
|
+
const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
|
|
1980
|
+
i.push(interpolateVec(i1, i2, t));
|
|
1981
|
+
const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
|
|
1982
|
+
const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
|
|
1983
|
+
o.push(interpolateVec(o1, o2, t));
|
|
1984
|
+
}
|
|
1985
|
+
return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
|
|
1986
|
+
}
|
|
1987
|
+
function remap(value, inMin, inMax, outMin, outMax) {
|
|
1988
|
+
if (inMax === inMin) return outMin;
|
|
1989
|
+
const t = (value - inMin) / (inMax - inMin);
|
|
1990
|
+
return outMin + t * (outMax - outMin);
|
|
1991
|
+
}
|
|
1992
|
+
function solveCubicBezierX(p1x, p2x, x) {
|
|
1993
|
+
if (x <= 0) return 0;
|
|
1994
|
+
if (x >= 1) return 1;
|
|
1995
|
+
const cx = 3 * p1x;
|
|
1996
|
+
const bx = 3 * (p2x - p1x) - cx;
|
|
1997
|
+
const ax = 1 - cx - bx;
|
|
1998
|
+
function sampleX(t) {
|
|
1999
|
+
return ((ax * t + bx) * t + cx) * t;
|
|
2000
|
+
}
|
|
2001
|
+
function sampleDX(t) {
|
|
2002
|
+
return (3 * ax * t + 2 * bx) * t + cx;
|
|
2003
|
+
}
|
|
2004
|
+
let t2 = x;
|
|
2005
|
+
let t0 = 0;
|
|
2006
|
+
let t1 = 1;
|
|
2007
|
+
for (let i = 0; i < 8; i++) {
|
|
2008
|
+
const x2 = sampleX(t2) - x;
|
|
2009
|
+
if (Math.abs(x2) < 1e-6) return t2;
|
|
2010
|
+
const d2 = sampleDX(t2);
|
|
2011
|
+
if (Math.abs(d2) < 1e-6) break;
|
|
2012
|
+
t2 -= x2 / d2;
|
|
2013
|
+
}
|
|
2014
|
+
t2 = x;
|
|
2015
|
+
while (t0 < t1) {
|
|
2016
|
+
const x2 = sampleX(t2);
|
|
2017
|
+
if (Math.abs(x2 - x) < 1e-6) return t2;
|
|
2018
|
+
if (x > x2) t0 = t2;
|
|
2019
|
+
else t1 = t2;
|
|
2020
|
+
t2 = (t1 + t0) / 2;
|
|
2021
|
+
}
|
|
2022
|
+
return t2;
|
|
2023
|
+
}
|
|
2024
|
+
function cubicBezier(easing) {
|
|
2025
|
+
const [p1x, p1y, p2x, p2y] = easing;
|
|
2026
|
+
const cy = 3 * p1y;
|
|
2027
|
+
const by = 3 * (p2y - p1y) - cy;
|
|
2028
|
+
const ay = 1 - cy - by;
|
|
2029
|
+
function sampleCurveY(t) {
|
|
2030
|
+
return ((ay * t + by) * t + cy) * t;
|
|
2031
|
+
}
|
|
2032
|
+
return function(x) {
|
|
2033
|
+
return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
function lerp2(a, b, t) {
|
|
2037
|
+
return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
|
|
2038
|
+
}
|
|
2039
|
+
function subdivideCubicBezier(p0, p1, p2, p3, t) {
|
|
2040
|
+
const q0 = lerp2(p0, p1, t);
|
|
2041
|
+
const q1 = lerp2(p1, p2, t);
|
|
2042
|
+
const q2 = lerp2(p2, p3, t);
|
|
2043
|
+
const r0 = lerp2(q0, q1, t);
|
|
2044
|
+
const r1 = lerp2(q1, q2, t);
|
|
2045
|
+
const s = lerp2(r0, r1, t);
|
|
2046
|
+
return {
|
|
2047
|
+
left: [p0, q0, r0, s],
|
|
2048
|
+
right: [s, r1, q2, p3]
|
|
2049
|
+
};
|
|
2050
|
+
}
|
|
2051
|
+
function splitEasing(easing, xFraction) {
|
|
2052
|
+
if (!easing) return { left: void 0, right: void 0 };
|
|
2053
|
+
if (xFraction <= 0) return { left: void 0, right: easing };
|
|
2054
|
+
if (xFraction >= 1) return { left: easing, right: void 0 };
|
|
2055
|
+
const [x1, y1, x2, y2] = easing;
|
|
2056
|
+
const t = solveCubicBezierX(x1, x2, xFraction);
|
|
2057
|
+
const p0 = [0, 0];
|
|
2058
|
+
const p1 = [x1, y1];
|
|
2059
|
+
const p2 = [x2, y2];
|
|
2060
|
+
const p3 = [1, 1];
|
|
2061
|
+
const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
|
|
2062
|
+
const sx = left[3][0];
|
|
2063
|
+
const sy = left[3][1];
|
|
2064
|
+
let leftEasing;
|
|
2065
|
+
if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
|
|
2066
|
+
leftEasing = [
|
|
2067
|
+
left[1][0] / sx,
|
|
2068
|
+
left[1][1] / sy,
|
|
2069
|
+
left[2][0] / sx,
|
|
2070
|
+
left[2][1] / sy
|
|
2071
|
+
];
|
|
2072
|
+
}
|
|
2073
|
+
let rightEasing;
|
|
2074
|
+
const rx = 1 - sx;
|
|
2075
|
+
const ry = 1 - sy;
|
|
2076
|
+
if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
|
|
2077
|
+
rightEasing = [
|
|
2078
|
+
(right[1][0] - sx) / rx,
|
|
2079
|
+
(right[1][1] - sy) / ry,
|
|
2080
|
+
(right[2][0] - sx) / rx,
|
|
2081
|
+
(right[2][1] - sy) / ry
|
|
2082
|
+
];
|
|
2083
|
+
}
|
|
2084
|
+
return { left: leftEasing, right: rightEasing };
|
|
2085
|
+
}
|
|
2086
|
+
function reverseEasing(easing) {
|
|
2087
|
+
if (!easing) return void 0;
|
|
2088
|
+
return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
|
|
2089
|
+
}
|
|
2090
|
+
function toRGBA(color) {
|
|
2091
|
+
const r = Math.round(color[0] * 255);
|
|
2092
|
+
const g = Math.round(color[1] * 255);
|
|
2093
|
+
const b = Math.round(color[2] * 255);
|
|
2094
|
+
return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
|
|
2095
|
+
}
|
|
2096
|
+
function parseRgba(s) {
|
|
2097
|
+
var _a;
|
|
2098
|
+
const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
|
|
2099
|
+
if (!inner) throw new Error("Invalid rgb/rgba format");
|
|
2100
|
+
const parts = inner.split(",").map((v) => +v.trim());
|
|
2101
|
+
return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
|
|
2102
|
+
}
|
|
2103
|
+
function parseHex(s) {
|
|
2104
|
+
const hex = s.slice(1);
|
|
2105
|
+
const isShort = hex.length <= 4;
|
|
2106
|
+
const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
|
|
2107
|
+
const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
|
|
2108
|
+
const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
|
|
2109
|
+
const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
|
|
2110
|
+
const result = [
|
|
2111
|
+
parseInt(r, 16) / 255,
|
|
2112
|
+
parseInt(g, 16) / 255,
|
|
2113
|
+
parseInt(b, 16) / 255
|
|
2114
|
+
];
|
|
2115
|
+
if (a !== null) {
|
|
2116
|
+
result.push(parseInt(a, 16) / 255);
|
|
2117
|
+
}
|
|
2118
|
+
return result;
|
|
2119
|
+
}
|
|
2120
|
+
function parseColor(s) {
|
|
2121
|
+
if (!s) return void 0;
|
|
2122
|
+
if (Array.isArray(s)) return s;
|
|
2123
|
+
if (typeof s !== "string") return void 0;
|
|
2124
|
+
if (s.startsWith("#")) {
|
|
2125
|
+
return parseHex(s);
|
|
2126
|
+
} else if (s.startsWith("rgb")) {
|
|
2127
|
+
return parseRgba(s);
|
|
2128
|
+
} else {
|
|
2129
|
+
console.warn("Unsupported color format: " + s);
|
|
2130
|
+
}
|
|
2131
|
+
return void 0;
|
|
2132
|
+
}
|
|
2133
|
+
var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
|
|
2134
|
+
var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
|
|
2135
|
+
var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
2136
|
+
function composeTransformParts(parts, opts) {
|
|
2137
|
+
var _a;
|
|
2138
|
+
if (!parts) return "";
|
|
2139
|
+
const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
|
|
2140
|
+
const segs = [];
|
|
2141
|
+
const t = parts.translate;
|
|
2142
|
+
const o = parts.origin;
|
|
2143
|
+
const r = parts.rotate;
|
|
2144
|
+
const s = parts.scale;
|
|
2145
|
+
const tu = withUnits ? "px" : "";
|
|
2146
|
+
const ru = withUnits ? "deg" : "";
|
|
2147
|
+
if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
|
|
2148
|
+
if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
|
|
2149
|
+
if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
|
|
2150
|
+
if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
|
|
2151
|
+
if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
|
|
2152
|
+
return segs.join("");
|
|
2153
|
+
}
|
|
2154
|
+
var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
2155
|
+
var DEFAULT_DURATION_MS = 1e3;
|
|
2156
|
+
function kebabToCamelCaseWord(kebab) {
|
|
2157
|
+
return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
|
|
2158
|
+
}
|
|
2159
|
+
function isCamelCaseWord(word) {
|
|
2160
|
+
return !word.includes("-") && /[a-z][A-Z]/.test(word);
|
|
2161
|
+
}
|
|
2162
|
+
var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
|
|
2163
|
+
// Transform/positioning
|
|
2164
|
+
"viewBox",
|
|
2165
|
+
"preserveAspectRatio",
|
|
2166
|
+
// Gradient
|
|
2167
|
+
"gradientUnits",
|
|
2168
|
+
"gradientTransform",
|
|
2169
|
+
"spreadMethod",
|
|
2170
|
+
// Pattern
|
|
2171
|
+
"patternUnits",
|
|
2172
|
+
"patternContentUnits",
|
|
2173
|
+
"patternTransform",
|
|
2174
|
+
// Clipping/masking
|
|
2175
|
+
"clipPathUnits",
|
|
2176
|
+
"maskUnits",
|
|
2177
|
+
"maskContentUnits",
|
|
2178
|
+
// Marker (SVG spec keeps these camelCase, like viewBox)
|
|
2179
|
+
"markerUnits",
|
|
2180
|
+
"markerWidth",
|
|
2181
|
+
"markerHeight",
|
|
2182
|
+
"refX",
|
|
2183
|
+
"refY",
|
|
2184
|
+
// Text
|
|
2185
|
+
"textLength",
|
|
2186
|
+
"lengthAdjust",
|
|
2187
|
+
"startOffset",
|
|
2188
|
+
// Filter
|
|
2189
|
+
"filterUnits",
|
|
2190
|
+
"primitiveUnits",
|
|
2191
|
+
"stdDeviation",
|
|
2192
|
+
"baseFrequency",
|
|
2193
|
+
"numOctaves",
|
|
2194
|
+
"surfaceScale",
|
|
2195
|
+
"diffuseConstant",
|
|
2196
|
+
"specularConstant",
|
|
2197
|
+
"specularExponent",
|
|
2198
|
+
"kernelMatrix",
|
|
2199
|
+
"kernelUnitLength",
|
|
2200
|
+
"edgeMode",
|
|
2201
|
+
"preserveAlpha",
|
|
2202
|
+
"targetX",
|
|
2203
|
+
"targetY"
|
|
2204
|
+
// // Animation
|
|
2205
|
+
// 'attributeName',
|
|
2206
|
+
// 'attributeType',
|
|
2207
|
+
// 'calcMode',
|
|
2208
|
+
// 'keyTimes',
|
|
2209
|
+
// 'keySplines',
|
|
2210
|
+
// 'repeatCount',
|
|
2211
|
+
// 'repeatDur'
|
|
2212
|
+
]);
|
|
2213
|
+
function camelCaseToKebabWordIfNeeded(camel) {
|
|
2214
|
+
return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
2215
|
+
}
|
|
2216
|
+
function clamp(value, min, max) {
|
|
2217
|
+
return Math.max(min, Math.min(value, max));
|
|
2218
|
+
}
|
|
2219
|
+
function bezier2D_pointAt(P0, P1, P2, P3, t) {
|
|
2220
|
+
if (t <= 0) return [P0[0], P0[1]];
|
|
2221
|
+
if (t >= 1) return [P3[0], P3[1]];
|
|
2222
|
+
const u = 1 - t;
|
|
2223
|
+
const u2 = u * u;
|
|
2224
|
+
const u3 = u2 * u;
|
|
2225
|
+
const t2 = t * t;
|
|
2226
|
+
const t3 = t2 * t;
|
|
2227
|
+
const w0 = u3;
|
|
2228
|
+
const w1 = 3 * t * u2;
|
|
2229
|
+
const w2 = 3 * t2 * u;
|
|
2230
|
+
const w3 = t3;
|
|
2231
|
+
return [
|
|
2232
|
+
w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
|
|
2233
|
+
w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
|
|
2234
|
+
];
|
|
2235
|
+
}
|
|
2236
|
+
var BEZIER_T_NUDGE = 1e-4;
|
|
2237
|
+
function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
|
|
2238
|
+
const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
|
|
2239
|
+
if (result[0] === 0 && result[1] === 0) {
|
|
2240
|
+
const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
|
|
2241
|
+
return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
|
|
2242
|
+
}
|
|
2243
|
+
return result;
|
|
2244
|
+
}
|
|
2245
|
+
function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
|
|
2246
|
+
const u = 1 - t;
|
|
2247
|
+
const a = 3 * u * u;
|
|
2248
|
+
const b = 6 * t * u;
|
|
2249
|
+
const c = 3 * t * t;
|
|
2250
|
+
return [
|
|
2251
|
+
a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
|
|
2252
|
+
a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
|
|
2253
|
+
];
|
|
2254
|
+
}
|
|
2255
|
+
function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
|
|
2256
|
+
const n = steps + 1;
|
|
2257
|
+
const ts = new Float64Array(n);
|
|
2258
|
+
const ds = new Float64Array(n);
|
|
2259
|
+
let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
|
|
2260
|
+
ts[0] = 0;
|
|
2261
|
+
ds[0] = 0;
|
|
2262
|
+
let cum = 0;
|
|
2263
|
+
for (let i = 1; i < n; i++) {
|
|
2264
|
+
const t = i / steps;
|
|
2265
|
+
const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
|
|
2266
|
+
const dx = cur[0] - prev[0];
|
|
2267
|
+
const dy = cur[1] - prev[1];
|
|
2268
|
+
cum += Math.sqrt(dx * dx + dy * dy);
|
|
2269
|
+
ts[i] = t;
|
|
2270
|
+
ds[i] = cum;
|
|
2271
|
+
prev = cur;
|
|
2272
|
+
}
|
|
2273
|
+
return { ts, ds };
|
|
2274
|
+
}
|
|
2275
|
+
function bezier2D_arcAtT(lut, t) {
|
|
2276
|
+
const { ts, ds } = lut;
|
|
2277
|
+
const last = ts.length - 1;
|
|
2278
|
+
if (t <= ts[0]) return ds[0];
|
|
2279
|
+
if (t >= ts[last]) return ds[last];
|
|
2280
|
+
let lo = 1, hi = last;
|
|
2281
|
+
while (lo < hi) {
|
|
2282
|
+
const mid = lo + hi >>> 1;
|
|
2283
|
+
if (ts[mid] < t) lo = mid + 1;
|
|
2284
|
+
else hi = mid;
|
|
2285
|
+
}
|
|
2286
|
+
const tPrev = ts[hi - 1];
|
|
2287
|
+
const span = ts[hi] - tPrev;
|
|
2288
|
+
const frac = span > 0 ? (t - tPrev) / span : 0;
|
|
2289
|
+
return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);
|
|
2290
|
+
}
|
|
2291
|
+
function invertEasing(easing) {
|
|
2292
|
+
if (!easing) return (y) => y;
|
|
2293
|
+
const flipped = [easing[1], easing[0], easing[3], easing[2]];
|
|
2294
|
+
return cubicBezier(flipped);
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
// src/PxMotionPath.ts
|
|
2298
|
+
function getKfTranslate(kf) {
|
|
2299
|
+
var _a;
|
|
2300
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
2301
|
+
if (!v) return void 0;
|
|
2302
|
+
if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
|
|
2303
|
+
return [v[0], v[1]];
|
|
2304
|
+
}
|
|
2305
|
+
const tr = v.translate;
|
|
2306
|
+
if (Array.isArray(tr) && tr.length >= 2) return [tr[0], tr[1]];
|
|
2307
|
+
return void 0;
|
|
2308
|
+
}
|
|
2309
|
+
function getKfTime(kf) {
|
|
2310
|
+
var _a, _b;
|
|
2311
|
+
return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
|
|
2312
|
+
}
|
|
2313
|
+
function getKfEasing(kf) {
|
|
2314
|
+
var _a;
|
|
2315
|
+
return (_a = kf.easing) != null ? _a : kf.e;
|
|
2316
|
+
}
|
|
2317
|
+
function propAnimIsMotionPath(anim) {
|
|
2318
|
+
var _a, _b, _c;
|
|
2319
|
+
const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
|
|
2320
|
+
if (!Array.isArray(kfs)) return false;
|
|
2321
|
+
if (anim.autoOrient) return true;
|
|
2322
|
+
for (const kf of kfs) {
|
|
2323
|
+
if (((_b = kf.tangentIn) != null ? _b : kf.ti) || ((_c = kf.tangentOut) != null ? _c : kf.to)) return true;
|
|
2324
|
+
}
|
|
2325
|
+
return false;
|
|
2326
|
+
}
|
|
2327
|
+
var _segmentCache = /* @__PURE__ */ new WeakMap();
|
|
2328
|
+
function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
|
|
2329
|
+
var _a, _b;
|
|
2330
|
+
const existing = _segmentCache.get(prevKf);
|
|
2331
|
+
if (existing) return existing;
|
|
2332
|
+
const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
|
|
2333
|
+
const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
|
|
2334
|
+
const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
|
|
2335
|
+
const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
|
|
2336
|
+
const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
|
|
2337
|
+
const entry = {
|
|
2338
|
+
P0: prevPos,
|
|
2339
|
+
P1,
|
|
2340
|
+
P2,
|
|
2341
|
+
P3: nextPos,
|
|
2342
|
+
lut,
|
|
2343
|
+
totalArc: lut.ds[lut.ds.length - 1]
|
|
2344
|
+
};
|
|
2345
|
+
_segmentCache.set(prevKf, entry);
|
|
2346
|
+
return entry;
|
|
2347
|
+
}
|
|
2348
|
+
function evaluateMotionPathSegment(prevKf, nextKf, prevPos, nextPos, localProgress, autoOrient) {
|
|
2349
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
2350
|
+
const t = seg.totalArc === 0 ? localProgress : tFromArcFraction(seg.lut, localProgress);
|
|
2351
|
+
const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2352
|
+
if (!autoOrient) return { translate: point };
|
|
2353
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2354
|
+
const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
2355
|
+
return { translate: point, rotateDeg };
|
|
2356
|
+
}
|
|
2357
|
+
function tFromArcFraction(lut, arcFrac) {
|
|
2358
|
+
const total = lut.ds[lut.ds.length - 1];
|
|
2359
|
+
const target = arcFrac * total;
|
|
2360
|
+
const { ts, ds } = lut;
|
|
2361
|
+
const last = ds.length - 1;
|
|
2362
|
+
if (target <= 0) return ts[0];
|
|
2363
|
+
if (target >= ds[last]) return ts[last];
|
|
2364
|
+
let lo = 1, hi = last;
|
|
2365
|
+
while (lo < hi) {
|
|
2366
|
+
const mid = lo + hi >>> 1;
|
|
2367
|
+
if (ds[mid] < target) lo = mid + 1;
|
|
2368
|
+
else hi = mid;
|
|
2369
|
+
}
|
|
2370
|
+
const dPrev = ds[hi - 1];
|
|
2371
|
+
const span = ds[hi] - dPrev;
|
|
2372
|
+
const frac = span > 0 ? (target - dPrev) / span : 0;
|
|
2373
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
2374
|
+
}
|
|
2375
|
+
var DEFAULT_FLATNESS_TOL = 0.5;
|
|
2376
|
+
var DEFAULT_ROTATION_TOL = 5;
|
|
2377
|
+
var DEFAULT_MAX_SAMPLES = 32;
|
|
2378
|
+
function materialiseMotionPathInPropAnim(anim, opts) {
|
|
2379
|
+
var _a, _b, _c, _d;
|
|
2380
|
+
if (!propAnimIsMotionPath(anim)) return anim;
|
|
2381
|
+
const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
|
|
2382
|
+
if (!Array.isArray(kfs) || kfs.length < 2) return anim;
|
|
2383
|
+
const autoOrient = !!anim.autoOrient;
|
|
2384
|
+
const flatnessTol = (_b = opts == null ? void 0 : opts.flatnessTolerance) != null ? _b : DEFAULT_FLATNESS_TOL;
|
|
2385
|
+
const rotationTol = (_c = opts == null ? void 0 : opts.rotationTolerance) != null ? _c : DEFAULT_ROTATION_TOL;
|
|
2386
|
+
const maxSamples = (_d = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _d : DEFAULT_MAX_SAMPLES;
|
|
2387
|
+
const out = [];
|
|
2388
|
+
const firstPos = getKfTranslate(kfs[0]);
|
|
2389
|
+
if (!firstPos) return anim;
|
|
2390
|
+
const firstRotate = autoOrient ? derivAngleForFirstKf(kfs[0], kfs[1]) : void 0;
|
|
2391
|
+
out.push(makeOutKf(
|
|
2392
|
+
getKfTime(kfs[0]),
|
|
2393
|
+
buildOutKfValue(getKfValueParts(kfs[0]), getKfValueParts(kfs[0]), 0, firstPos, firstRotate, autoOrient)
|
|
2394
|
+
));
|
|
2395
|
+
for (let i = 0; i < kfs.length - 1; i++) {
|
|
2396
|
+
const prevKf = kfs[i];
|
|
2397
|
+
const nextKf = kfs[i + 1];
|
|
2398
|
+
const prevPos = getKfTranslate(prevKf);
|
|
2399
|
+
const nextPos = getKfTranslate(nextKf);
|
|
2400
|
+
if (!prevPos || !nextPos) {
|
|
2401
|
+
out.push(makeOutKf(
|
|
2402
|
+
getKfTime(nextKf),
|
|
2403
|
+
buildOutKfValue(getKfValueParts(nextKf), getKfValueParts(nextKf), 1, nextPos != null ? nextPos : [0, 0], void 0, autoOrient)
|
|
2404
|
+
));
|
|
2405
|
+
continue;
|
|
2406
|
+
}
|
|
2407
|
+
if (autoOrient && i > 0) {
|
|
2408
|
+
insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
|
|
2409
|
+
}
|
|
2410
|
+
materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
|
|
2411
|
+
}
|
|
2412
|
+
const lastInE = getKfEasing(kfs[kfs.length - 1]);
|
|
2413
|
+
if (lastInE) out[out.length - 1].e = lastInE;
|
|
2414
|
+
if (autoOrient) unwrapAutoOrientRotations(out);
|
|
2415
|
+
const result = { kfs: out };
|
|
2416
|
+
if (anim.loop !== void 0) result.loop = anim.loop;
|
|
2417
|
+
return result;
|
|
2418
|
+
}
|
|
2419
|
+
function unwrapAutoOrientRotations(kfs) {
|
|
2420
|
+
var _a;
|
|
2421
|
+
let prev;
|
|
2422
|
+
for (const kf of kfs) {
|
|
2423
|
+
const v = (_a = kf.v) != null ? _a : kf.value;
|
|
2424
|
+
if (!v || typeof v.rotate !== "number") continue;
|
|
2425
|
+
if (prev === void 0) {
|
|
2426
|
+
prev = v.rotate;
|
|
2427
|
+
continue;
|
|
2428
|
+
}
|
|
2429
|
+
let r = v.rotate;
|
|
2430
|
+
while (r - prev > 180) r -= 360;
|
|
2431
|
+
while (r - prev < -180) r += 360;
|
|
2432
|
+
v.rotate = r;
|
|
2433
|
+
prev = r;
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
function makeOutKf(time, value) {
|
|
2437
|
+
return { t: time, v: value };
|
|
2438
|
+
}
|
|
2439
|
+
function getKfValueParts(kf) {
|
|
2440
|
+
var _a;
|
|
2441
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
2442
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
|
|
2443
|
+
return v;
|
|
2444
|
+
}
|
|
2445
|
+
function interpolatePart(prev, next, p) {
|
|
2446
|
+
if (prev === void 0) return next;
|
|
2447
|
+
if (next === void 0) return prev;
|
|
2448
|
+
if (typeof prev === "number" && typeof next === "number") {
|
|
2449
|
+
return prev + (next - prev) * p;
|
|
2450
|
+
}
|
|
2451
|
+
if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {
|
|
2452
|
+
const out = new Array(prev.length);
|
|
2453
|
+
for (let i = 0; i < prev.length; i++) {
|
|
2454
|
+
const a = typeof prev[i] === "number" ? prev[i] : 0;
|
|
2455
|
+
const b = typeof next[i] === "number" ? next[i] : 0;
|
|
2456
|
+
out[i] = a + (b - a) * p;
|
|
2457
|
+
}
|
|
2458
|
+
return out;
|
|
2459
|
+
}
|
|
2460
|
+
return p < 0.5 ? prev : next;
|
|
2461
|
+
}
|
|
2462
|
+
function buildOutKfValue(prevV, nextV, p, translate, rotateDegFromAutoOrient, autoOrient) {
|
|
2463
|
+
const value = { translate };
|
|
2464
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2465
|
+
if (prevV) for (const k of Object.keys(prevV)) keys.add(k);
|
|
2466
|
+
if (nextV) for (const k of Object.keys(nextV)) keys.add(k);
|
|
2467
|
+
for (const k of keys) {
|
|
2468
|
+
if (k === "translate") continue;
|
|
2469
|
+
if (k === "rotate" && autoOrient) continue;
|
|
2470
|
+
const pv = prevV == null ? void 0 : prevV[k];
|
|
2471
|
+
const nv = nextV == null ? void 0 : nextV[k];
|
|
2472
|
+
if (pv === void 0 && nv === void 0) continue;
|
|
2473
|
+
value[k] = interpolatePart(pv, nv, p);
|
|
2474
|
+
}
|
|
2475
|
+
if (rotateDegFromAutoOrient !== void 0) value.rotate = rotateDegFromAutoOrient;
|
|
2476
|
+
return value;
|
|
2477
|
+
}
|
|
2478
|
+
function derivAngleForFirstKf(kf0, kf1) {
|
|
2479
|
+
const p0 = getKfTranslate(kf0);
|
|
2480
|
+
const p1 = getKfTranslate(kf1);
|
|
2481
|
+
if (!p0 || !p1) return 0;
|
|
2482
|
+
const seg = getSegmentCache(kf0, kf1, p0, p1);
|
|
2483
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
2484
|
+
return Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
2485
|
+
}
|
|
2486
|
+
function wrappedAngleDelta(a, b) {
|
|
2487
|
+
let d = a - b;
|
|
2488
|
+
while (d > 180) d -= 360;
|
|
2489
|
+
while (d < -180) d += 360;
|
|
2490
|
+
return d;
|
|
2491
|
+
}
|
|
2492
|
+
function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
|
|
2493
|
+
var _a;
|
|
2494
|
+
const lastKf = out[out.length - 1];
|
|
2495
|
+
const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
|
|
2496
|
+
const prevExit = lastV == null ? void 0 : lastV.rotate;
|
|
2497
|
+
if (typeof prevExit !== "number") return;
|
|
2498
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
2499
|
+
const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
2500
|
+
const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;
|
|
2501
|
+
const delta = wrappedAngleDelta(nextEntry, prevExit);
|
|
2502
|
+
if (Math.abs(delta) <= rotationTol) return;
|
|
2503
|
+
const dupValue = buildOutKfValue(
|
|
2504
|
+
getKfValueParts(prevKf),
|
|
2505
|
+
getKfValueParts(prevKf),
|
|
2506
|
+
0,
|
|
2507
|
+
prevPos,
|
|
2508
|
+
nextEntry,
|
|
2509
|
+
true
|
|
2510
|
+
);
|
|
2511
|
+
out.push(makeOutKf(getKfTime(prevKf), dupValue));
|
|
2512
|
+
}
|
|
2513
|
+
function materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
|
|
2514
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
2515
|
+
const prevTime = getKfTime(prevKf);
|
|
2516
|
+
const nextTime = getKfTime(nextKf);
|
|
2517
|
+
const prevEasing = getKfEasing(prevKf);
|
|
2518
|
+
const invertFn = invertEasing(prevEasing);
|
|
2519
|
+
const prevV = getKfValueParts(prevKf);
|
|
2520
|
+
const nextV = getKfValueParts(nextKf);
|
|
2521
|
+
const interiorTs = computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples);
|
|
2522
|
+
const samples = [];
|
|
2523
|
+
for (const t of interiorTs) {
|
|
2524
|
+
const arc = bezier2D_arcAtT(seg.lut, t);
|
|
2525
|
+
const p = clamp(seg.totalArc > 0 ? arc / seg.totalArc : t, 0, 1);
|
|
2526
|
+
const u = clamp(invertFn(p), 0, 1);
|
|
2527
|
+
const pos = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2528
|
+
const sample = { u, p, pos };
|
|
2529
|
+
if (autoOrient) {
|
|
2530
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2531
|
+
sample.rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
2532
|
+
}
|
|
2533
|
+
samples.push(sample);
|
|
2534
|
+
}
|
|
2535
|
+
let remaining = prevEasing;
|
|
2536
|
+
let prevU = 0;
|
|
2537
|
+
const startIdx = out.length - 1;
|
|
2538
|
+
for (let i = 0; i < samples.length; i++) {
|
|
2539
|
+
const s = samples[i];
|
|
2540
|
+
const xFrac = prevU < 1 ? clamp((s.u - prevU) / (1 - prevU), 0, 1) : 1;
|
|
2541
|
+
const { left, right } = splitEasing(remaining, xFrac);
|
|
2542
|
+
const ownerIdx = i === 0 ? startIdx : out.length - 1;
|
|
2543
|
+
if (left) out[ownerIdx].e = left;
|
|
2544
|
+
else delete out[ownerIdx].e;
|
|
2545
|
+
const tGlobal = prevTime + s.u * (nextTime - prevTime);
|
|
2546
|
+
const value = buildOutKfValue(prevV, nextV, s.p, s.pos, s.rotateDeg, autoOrient);
|
|
2547
|
+
out.push(makeOutKf(tGlobal, value));
|
|
2548
|
+
remaining = right;
|
|
2549
|
+
prevU = s.u;
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
function computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples) {
|
|
2553
|
+
const extremes = [];
|
|
2554
|
+
addAxisExtremes(seg.P0[0], seg.P1[0], seg.P2[0], seg.P3[0], extremes);
|
|
2555
|
+
addAxisExtremes(seg.P0[1], seg.P1[1], seg.P2[1], seg.P3[1], extremes);
|
|
2556
|
+
extremes.sort((a, b) => a - b);
|
|
2557
|
+
const critical = [0];
|
|
2558
|
+
for (const t of extremes) {
|
|
2559
|
+
if (t > critical[critical.length - 1] + 1e-6 && t < 1 - 1e-6) {
|
|
2560
|
+
critical.push(t);
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
critical.push(1);
|
|
2564
|
+
const out = [];
|
|
2565
|
+
const budget = { remaining: maxSamples - critical.length };
|
|
2566
|
+
for (let i = 0; i < critical.length - 1; i++) {
|
|
2567
|
+
bisect(critical[i], critical[i + 1], out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
2568
|
+
}
|
|
2569
|
+
return out;
|
|
2570
|
+
}
|
|
2571
|
+
function addAxisExtremes(p0, p1, p2, p3, out) {
|
|
2572
|
+
const a = p1 - p0;
|
|
2573
|
+
const b = p2 - p1;
|
|
2574
|
+
const c = p3 - p2;
|
|
2575
|
+
const A = a - 2 * b + c;
|
|
2576
|
+
const B = 2 * (b - a);
|
|
2577
|
+
const C = a;
|
|
2578
|
+
if (Math.abs(A) < 1e-10) {
|
|
2579
|
+
if (Math.abs(B) > 1e-10) {
|
|
2580
|
+
const t = -C / B;
|
|
2581
|
+
if (t > 1e-6 && t < 1 - 1e-6) out.push(t);
|
|
2582
|
+
}
|
|
2583
|
+
return;
|
|
2584
|
+
}
|
|
2585
|
+
const disc = B * B - 4 * A * C;
|
|
2586
|
+
if (disc < 0) return;
|
|
2587
|
+
const sq = Math.sqrt(disc);
|
|
2588
|
+
const t1 = (-B - sq) / (2 * A);
|
|
2589
|
+
const t2 = (-B + sq) / (2 * A);
|
|
2590
|
+
if (t1 > 1e-6 && t1 < 1 - 1e-6) out.push(t1);
|
|
2591
|
+
if (t2 > 1e-6 && t2 < 1 - 1e-6) out.push(t2);
|
|
2592
|
+
}
|
|
2593
|
+
function bisect(tA, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget) {
|
|
2594
|
+
const tMid = (tA + tB) / 2;
|
|
2595
|
+
const pA = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
|
|
2596
|
+
const pB = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
|
|
2597
|
+
const span = tB - tA;
|
|
2598
|
+
const p25 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.25);
|
|
2599
|
+
const p50 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tMid);
|
|
2600
|
+
const p75 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.75);
|
|
2601
|
+
const dev = Math.max(
|
|
2602
|
+
perpDist(p25, pA, pB),
|
|
2603
|
+
perpDist(p50, pA, pB),
|
|
2604
|
+
perpDist(p75, pA, pB)
|
|
2605
|
+
);
|
|
2606
|
+
let rotOk = true;
|
|
2607
|
+
if (autoOrient) {
|
|
2608
|
+
const tanA = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
|
|
2609
|
+
const tanB = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
|
|
2610
|
+
const angA = Math.atan2(tanA[1], tanA[0]) * 180 / Math.PI;
|
|
2611
|
+
const angB = Math.atan2(tanB[1], tanB[0]) * 180 / Math.PI;
|
|
2612
|
+
let delta = Math.abs(angA - angB);
|
|
2613
|
+
if (delta > 180) delta = 360 - delta;
|
|
2614
|
+
if (delta > rotationTol) rotOk = false;
|
|
2615
|
+
}
|
|
2616
|
+
if (dev <= flatnessTol && rotOk || budget.remaining <= 0 || span < 1e-6) {
|
|
2617
|
+
out.push(tB);
|
|
2618
|
+
return;
|
|
2619
|
+
}
|
|
2620
|
+
budget.remaining -= 1;
|
|
2621
|
+
bisect(tA, tMid, out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
2622
|
+
bisect(tMid, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
2623
|
+
}
|
|
2624
|
+
function perpDist(q, pA, pB) {
|
|
2625
|
+
const dx = pB[0] - pA[0];
|
|
2626
|
+
const dy = pB[1] - pA[1];
|
|
2627
|
+
const len2 = dx * dx + dy * dy;
|
|
2628
|
+
if (len2 < 1e-20) {
|
|
2629
|
+
const qdx = q[0] - pA[0];
|
|
2630
|
+
const qdy = q[1] - pA[1];
|
|
2631
|
+
return Math.sqrt(qdx * qdx + qdy * qdy);
|
|
2632
|
+
}
|
|
2633
|
+
const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
|
|
2634
|
+
return Math.abs(cross) / Math.sqrt(len2);
|
|
2635
|
+
}
|
|
2636
|
+
function materialiseMotionPathsInTree(root, opts) {
|
|
2637
|
+
const out = walkAndMaterialise(root, opts);
|
|
2638
|
+
return out != null ? out : root;
|
|
2639
|
+
}
|
|
2640
|
+
function walkAndMaterialise(node, opts) {
|
|
2641
|
+
let newChildren;
|
|
2642
|
+
if (node.children) {
|
|
2643
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2644
|
+
const ch = node.children[i];
|
|
2645
|
+
const ret = walkAndMaterialise(ch, opts);
|
|
2646
|
+
if (ret !== null) {
|
|
2647
|
+
if (!newChildren) newChildren = node.children.slice();
|
|
2648
|
+
newChildren[i] = ret;
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
let newAnimate;
|
|
2653
|
+
const animBucket = node.animate;
|
|
2654
|
+
if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
|
|
2655
|
+
const animDef = animBucket;
|
|
2656
|
+
const transformAnim = animDef.transform;
|
|
2657
|
+
if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
|
|
2658
|
+
const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);
|
|
2659
|
+
if (materialised !== transformAnim) {
|
|
2660
|
+
newAnimate = __spreadProps(__spreadValues({}, animDef), { transform: materialised });
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
if (!newChildren && !newAnimate) return null;
|
|
2665
|
+
const cloned = __spreadValues({}, node);
|
|
2666
|
+
if (newChildren) cloned.children = newChildren;
|
|
2667
|
+
if (newAnimate) cloned.animate = newAnimate;
|
|
2668
|
+
return cloned;
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
// src/PxDefinitions.ts
|
|
2672
|
+
function parsePathCommands(d) {
|
|
2673
|
+
const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
|
|
2674
|
+
const commands = [];
|
|
2675
|
+
let currentCommand = null;
|
|
2676
|
+
for (const token of tokens) {
|
|
2677
|
+
if (/[MLCZmlcz]/.test(token)) {
|
|
2678
|
+
currentCommand = { type: token, values: [] };
|
|
2679
|
+
commands.push(currentCommand);
|
|
2680
|
+
} else if (currentCommand) {
|
|
2681
|
+
const value = +token;
|
|
2682
|
+
currentCommand.values.push(Number.isNaN(value) ? 0 : value);
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
return commands;
|
|
2686
|
+
}
|
|
2687
|
+
function parseSvgPathToBezier(d) {
|
|
2688
|
+
const res = [];
|
|
2689
|
+
let currentPath;
|
|
2690
|
+
const commands = parsePathCommands(d);
|
|
2691
|
+
for (const command of commands) {
|
|
2692
|
+
const type = command.type;
|
|
2693
|
+
const values = command.values;
|
|
2694
|
+
if (type === "M" || type === "m") {
|
|
2695
|
+
const x = values[0] || 0;
|
|
2696
|
+
const y = values[1] || 0;
|
|
2697
|
+
currentPath = {
|
|
2110
2698
|
v: [[x, y]],
|
|
2111
2699
|
i: [[x, y]],
|
|
2112
2700
|
o: [[x, y]],
|
|
@@ -2115,471 +2703,1296 @@ function parseSvgPathToBezier(d) {
|
|
|
2115
2703
|
res.push(currentPath);
|
|
2116
2704
|
continue;
|
|
2117
2705
|
}
|
|
2118
|
-
if (!currentPath) {
|
|
2119
|
-
currentPath = {
|
|
2120
|
-
v: [[0, 0]],
|
|
2121
|
-
i: [[0, 0]],
|
|
2122
|
-
o: [[0, 0]],
|
|
2123
|
-
c: false
|
|
2124
|
-
};
|
|
2125
|
-
res.push(currentPath);
|
|
2706
|
+
if (!currentPath) {
|
|
2707
|
+
currentPath = {
|
|
2708
|
+
v: [[0, 0]],
|
|
2709
|
+
i: [[0, 0]],
|
|
2710
|
+
o: [[0, 0]],
|
|
2711
|
+
c: false
|
|
2712
|
+
};
|
|
2713
|
+
res.push(currentPath);
|
|
2714
|
+
}
|
|
2715
|
+
if (type === "L") {
|
|
2716
|
+
const x = values[0] || 0;
|
|
2717
|
+
const y = values[1] || 0;
|
|
2718
|
+
currentPath.v.push([x, y]);
|
|
2719
|
+
currentPath.i.push([x, y]);
|
|
2720
|
+
currentPath.o.push([x, y]);
|
|
2721
|
+
} else if (type === "C") {
|
|
2722
|
+
const outX = values[0] || 0;
|
|
2723
|
+
const outY = values[1] || 0;
|
|
2724
|
+
const inX2 = values[2] || 0;
|
|
2725
|
+
const inY2 = values[3] || 0;
|
|
2726
|
+
const x2 = values[4] || 0;
|
|
2727
|
+
const y2 = values[5] || 0;
|
|
2728
|
+
currentPath.o[currentPath.o.length - 1] = [outX, outY];
|
|
2729
|
+
currentPath.v.push([x2, y2]);
|
|
2730
|
+
currentPath.i.push([inX2, inY2]);
|
|
2731
|
+
currentPath.o.push([x2, y2]);
|
|
2732
|
+
} else if (type === "Z" || type === "z") {
|
|
2733
|
+
currentPath.c = true;
|
|
2734
|
+
} else {
|
|
2735
|
+
console.warn('Unsupported path command "' + type + '"');
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
return res;
|
|
2739
|
+
}
|
|
2740
|
+
function extractPathData(str) {
|
|
2741
|
+
if (str.startsWith("path(") && str.endsWith(")")) {
|
|
2742
|
+
return str.slice(5, -1);
|
|
2743
|
+
}
|
|
2744
|
+
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str)) {
|
|
2745
|
+
return str;
|
|
2746
|
+
}
|
|
2747
|
+
return void 0;
|
|
2748
|
+
}
|
|
2749
|
+
function isPathString(value) {
|
|
2750
|
+
return typeof value === "string" && extractPathData(value) !== void 0;
|
|
2751
|
+
}
|
|
2752
|
+
function normalizePathValue(value) {
|
|
2753
|
+
if (value && typeof value === "object" && typeof value.path === "string") {
|
|
2754
|
+
const d = extractPathData(value.path);
|
|
2755
|
+
return d ? { paths: parseSvgPathToBezier(d) } : value;
|
|
2756
|
+
}
|
|
2757
|
+
if (value && typeof value === "object" && "paths" in value) {
|
|
2758
|
+
const pathsArray = value.paths;
|
|
2759
|
+
if (Array.isArray(pathsArray) && pathsArray.length > 0) {
|
|
2760
|
+
if (isPathString(pathsArray[0])) {
|
|
2761
|
+
const paths = [];
|
|
2762
|
+
for (const pathStr2 of pathsArray) {
|
|
2763
|
+
const d = extractPathData(pathStr2);
|
|
2764
|
+
if (d) {
|
|
2765
|
+
paths.push(...parseSvgPathToBezier(d));
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
return { paths };
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
return value;
|
|
2772
|
+
}
|
|
2773
|
+
if (Array.isArray(value)) {
|
|
2774
|
+
if (value.length > 0 && isPathString(value[0])) {
|
|
2775
|
+
const paths = [];
|
|
2776
|
+
for (const pathStr2 of value) {
|
|
2777
|
+
const d = extractPathData(pathStr2);
|
|
2778
|
+
if (d) {
|
|
2779
|
+
paths.push(...parseSvgPathToBezier(d));
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
return { paths };
|
|
2783
|
+
}
|
|
2784
|
+
return { paths: value };
|
|
2785
|
+
}
|
|
2786
|
+
if (isPathString(value)) {
|
|
2787
|
+
const d = extractPathData(value);
|
|
2788
|
+
return { paths: parseSvgPathToBezier(d) };
|
|
2789
|
+
}
|
|
2790
|
+
return value;
|
|
2791
|
+
}
|
|
2792
|
+
function resolveEasing(easing, defs) {
|
|
2793
|
+
var _a;
|
|
2794
|
+
if (!easing) return void 0;
|
|
2795
|
+
if (Array.isArray(easing)) {
|
|
2796
|
+
return easing;
|
|
2797
|
+
}
|
|
2798
|
+
if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
|
|
2799
|
+
return defs.easings[easing];
|
|
2800
|
+
}
|
|
2801
|
+
console.warn("Unknown easing name: " + easing);
|
|
2802
|
+
return void 0;
|
|
2803
|
+
}
|
|
2804
|
+
function resolveAnimation(animRef, defs) {
|
|
2805
|
+
var _a;
|
|
2806
|
+
if (typeof animRef === "string") {
|
|
2807
|
+
const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
|
|
2808
|
+
if (!resolved) {
|
|
2809
|
+
console.warn("Unknown animation name: " + animRef);
|
|
2810
|
+
}
|
|
2811
|
+
return resolved;
|
|
2812
|
+
}
|
|
2813
|
+
return animRef;
|
|
2814
|
+
}
|
|
2815
|
+
function resolveElementAnimation(animate, defs) {
|
|
2816
|
+
if (!animate) return [];
|
|
2817
|
+
const results = [];
|
|
2818
|
+
if (typeof animate === "string") {
|
|
2819
|
+
const resolved = resolveAnimation(animate, defs);
|
|
2820
|
+
if (resolved) results.push(resolved);
|
|
2821
|
+
} else if (Array.isArray(animate)) {
|
|
2822
|
+
for (const item of animate) {
|
|
2823
|
+
const resolved = resolveAnimation(item, defs);
|
|
2824
|
+
if (resolved) results.push(resolved);
|
|
2126
2825
|
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2826
|
+
} else {
|
|
2827
|
+
results.push(animate);
|
|
2828
|
+
}
|
|
2829
|
+
return results;
|
|
2830
|
+
}
|
|
2831
|
+
function interpolateValue(propName, a, b, t) {
|
|
2832
|
+
var _a, _b;
|
|
2833
|
+
if (propName === "d") {
|
|
2834
|
+
const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
|
|
2835
|
+
const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
|
|
2836
|
+
return { paths: interpolateBeziers(aPaths, bPaths, t) };
|
|
2837
|
+
}
|
|
2838
|
+
if (COLOUR_ATTR_NAMES.has(propName)) {
|
|
2839
|
+
return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
|
|
2840
|
+
}
|
|
2841
|
+
if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
|
|
2842
|
+
return interpolateTransformParts(a, b, t);
|
|
2843
|
+
}
|
|
2844
|
+
if (propName === "rotate" && typeof a === "number" && typeof b === "number") {
|
|
2845
|
+
return interpolateNum(a, b, t);
|
|
2846
|
+
}
|
|
2847
|
+
if (TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
|
|
2848
|
+
return interpolateVec(a || [], b || [], t);
|
|
2849
|
+
}
|
|
2850
|
+
return interpolateNum(+(a || 0), +(b || 0), t);
|
|
2851
|
+
}
|
|
2852
|
+
function interpolateTransformParts(a, b, t) {
|
|
2853
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(a != null ? a : {}), ...Object.keys(b != null ? b : {})]);
|
|
2854
|
+
const out = {};
|
|
2855
|
+
for (const k of keys) {
|
|
2856
|
+
const av = a == null ? void 0 : a[k];
|
|
2857
|
+
const bv = b == null ? void 0 : b[k];
|
|
2858
|
+
if (k === "rotate") {
|
|
2859
|
+
out[k] = interpolateNum(+(av != null ? av : 0), +(bv != null ? bv : 0), t);
|
|
2860
|
+
} else if (k === "translate" || k === "scale" || k === "origin") {
|
|
2861
|
+
const fallback = k === "scale" ? [1, 1] : [0, 0];
|
|
2862
|
+
out[k] = interpolateVec(av || fallback, bv || fallback, t);
|
|
2146
2863
|
} else {
|
|
2147
|
-
|
|
2864
|
+
out[k] = bv != null ? bv : av;
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
return out;
|
|
2868
|
+
}
|
|
2869
|
+
function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
2870
|
+
var _a, _b, _c, _d, _e;
|
|
2871
|
+
const totalIntervals = keyframes.length - 1;
|
|
2872
|
+
const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
|
|
2873
|
+
let segKfs;
|
|
2874
|
+
if (loop.before) {
|
|
2875
|
+
segKfs = keyframes.slice(0, segCount + 1);
|
|
2876
|
+
} else {
|
|
2877
|
+
segKfs = keyframes.slice(totalIntervals - segCount);
|
|
2878
|
+
}
|
|
2879
|
+
const firstT = (_b = keyframes[0].t) != null ? _b : 0;
|
|
2880
|
+
const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
|
|
2881
|
+
let fillStart, fillEnd;
|
|
2882
|
+
if (loop.before) {
|
|
2883
|
+
fillStart = 0;
|
|
2884
|
+
fillEnd = firstT;
|
|
2885
|
+
} else {
|
|
2886
|
+
fillStart = lastT;
|
|
2887
|
+
fillEnd = duration;
|
|
2888
|
+
}
|
|
2889
|
+
const fillDuration = fillEnd - fillStart;
|
|
2890
|
+
if (fillDuration <= 0) return keyframes;
|
|
2891
|
+
const segStartT = (_d = segKfs[0].t) != null ? _d : 0;
|
|
2892
|
+
const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
|
|
2893
|
+
const segDuration = segEndT - segStartT;
|
|
2894
|
+
if (segDuration <= 0) return keyframes;
|
|
2895
|
+
const template = segKfs.map((kf) => {
|
|
2896
|
+
var _a2, _b2;
|
|
2897
|
+
return {
|
|
2898
|
+
relT: (kf.t - segStartT) / segDuration,
|
|
2899
|
+
v: kf.v,
|
|
2900
|
+
e: kf.e,
|
|
2901
|
+
tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
|
|
2902
|
+
tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
|
|
2903
|
+
};
|
|
2904
|
+
});
|
|
2905
|
+
const fullReps = Math.floor(fillDuration / segDuration);
|
|
2906
|
+
const remainder = fillDuration - fullReps * segDuration;
|
|
2907
|
+
const partialFraction = remainder / segDuration;
|
|
2908
|
+
const looped = [];
|
|
2909
|
+
function appendRep(repStart, isReversed, partial) {
|
|
2910
|
+
let entries;
|
|
2911
|
+
if (isReversed) {
|
|
2912
|
+
entries = [];
|
|
2913
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
2914
|
+
entries.push({
|
|
2915
|
+
relT: 1 - template[i].relT,
|
|
2916
|
+
v: template[i].v,
|
|
2917
|
+
// Easing for reversed transition: use reversed easing from the forward "from" keyframe
|
|
2918
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
2919
|
+
// Reversed traversal swaps each vertex's in/out spatial tangents
|
|
2920
|
+
// (geometry is identical, walked backwards), so curvature and
|
|
2921
|
+
// auto-orientation survive the reversed rep.
|
|
2922
|
+
tangentIn: template[i].tangentOut,
|
|
2923
|
+
tangentOut: template[i].tangentIn
|
|
2924
|
+
});
|
|
2925
|
+
}
|
|
2926
|
+
} else {
|
|
2927
|
+
entries = template;
|
|
2928
|
+
}
|
|
2929
|
+
const cutRelT = partial !== void 0 ? partial : 1;
|
|
2930
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2931
|
+
const entry = entries[i];
|
|
2932
|
+
if (entry.relT > cutRelT + 1e-9) {
|
|
2933
|
+
const prev = entries[i - 1];
|
|
2934
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
2935
|
+
const localFrac = (cutRelT - prev.relT) / intervalSpan;
|
|
2936
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
2937
|
+
const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
2938
|
+
const { left: leftEasing } = splitEasing(prev.e, localFrac);
|
|
2939
|
+
if (looped.length > 0 && prev.relT <= cutRelT) {
|
|
2940
|
+
looped[looped.length - 1].e = leftEasing;
|
|
2941
|
+
}
|
|
2942
|
+
looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
|
|
2943
|
+
return;
|
|
2944
|
+
}
|
|
2945
|
+
const pushed = {
|
|
2946
|
+
t: repStart + entry.relT * segDuration,
|
|
2947
|
+
v: entry.v,
|
|
2948
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
2949
|
+
};
|
|
2950
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
2951
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
2952
|
+
looped.push(pushed);
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
2956
|
+
const distFromBoundary = loop.before ? fullReps - 1 - rep : rep;
|
|
2957
|
+
const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
|
|
2958
|
+
const repStart = fillStart + rep * segDuration;
|
|
2959
|
+
appendRep(repStart, isReversed);
|
|
2960
|
+
}
|
|
2961
|
+
if (partialFraction > 1e-9) {
|
|
2962
|
+
const isReversed = !!loop.alternate && fullReps % 2 === 0;
|
|
2963
|
+
const repStart = fillStart + fullReps * segDuration;
|
|
2964
|
+
appendRep(repStart, isReversed, partialFraction);
|
|
2965
|
+
}
|
|
2966
|
+
if (loop.before) {
|
|
2967
|
+
return [...looped, ...keyframes];
|
|
2968
|
+
} else {
|
|
2969
|
+
return [...keyframes, ...looped];
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
function normalizeKeyframes(propName, propAnim, duration, defs) {
|
|
2973
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2974
|
+
const keyframes = propAnim.keyframes || propAnim.kfs || [];
|
|
2975
|
+
const normalized = [];
|
|
2976
|
+
for (const kf of keyframes) {
|
|
2977
|
+
const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
|
|
2978
|
+
let value = (_c = kf.value) != null ? _c : kf.v;
|
|
2979
|
+
const easing = (_d = kf.easing) != null ? _d : kf.e;
|
|
2980
|
+
if (propName === "d") {
|
|
2981
|
+
value = normalizePathValue(value);
|
|
2982
|
+
}
|
|
2983
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
2984
|
+
if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
|
|
2985
|
+
value = (_e = parseColor(value)) != null ? _e : value;
|
|
2986
|
+
}
|
|
2987
|
+
const normKf = {
|
|
2988
|
+
t: timePct,
|
|
2989
|
+
v: value,
|
|
2990
|
+
e: resolveEasing(easing, defs)
|
|
2991
|
+
};
|
|
2992
|
+
const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
|
|
2993
|
+
const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
|
|
2994
|
+
if (tIn) normKf.tangentIn = tIn;
|
|
2995
|
+
if (tOut) normKf.tangentOut = tOut;
|
|
2996
|
+
normalized.push(normKf);
|
|
2997
|
+
}
|
|
2998
|
+
normalized.sort((a, b) => {
|
|
2999
|
+
var _a2, _b2;
|
|
3000
|
+
return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
|
|
3001
|
+
});
|
|
3002
|
+
const loopRaw = propAnim.loop;
|
|
3003
|
+
const loop = loopRaw === true ? {} : loopRaw || void 0;
|
|
3004
|
+
if (loop && normalized.length >= 2) {
|
|
3005
|
+
return expandLoopKeyframes(propName, normalized, loop, duration);
|
|
3006
|
+
}
|
|
3007
|
+
return normalized;
|
|
3008
|
+
}
|
|
3009
|
+
function mergeAnimationDefinitions(animations) {
|
|
3010
|
+
const merged = {};
|
|
3011
|
+
for (const anim of animations) {
|
|
3012
|
+
for (const [prop, propAnim] of Object.entries(anim)) {
|
|
3013
|
+
merged[prop] = propAnim;
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
return merged;
|
|
3017
|
+
}
|
|
3018
|
+
function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
|
|
3019
|
+
var _a;
|
|
3020
|
+
const loopRaw = propAnim.loop;
|
|
3021
|
+
if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
|
|
3022
|
+
const loop = loopRaw === true ? {} : loopRaw;
|
|
3023
|
+
const rawKfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
|
|
3024
|
+
if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
|
|
3025
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
3026
|
+
const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
|
|
3027
|
+
const kfs = rawKfs.map((kf) => {
|
|
3028
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
3029
|
+
const t = (_a2 = kf.t) != null ? _a2 : kf.time;
|
|
3030
|
+
let v = (_b = kf.v) != null ? _b : kf.value;
|
|
3031
|
+
if (propName === "d") v = normalizePathValue(v);
|
|
3032
|
+
if (isColour) v = (_c = parseColor(v)) != null ? _c : v;
|
|
3033
|
+
const e = (_d = kf.e) != null ? _d : kf.easing;
|
|
3034
|
+
const out2 = { t, v, e };
|
|
3035
|
+
if ((_e = kf.tangentIn) != null ? _e : kf.ti) out2.tangentIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
|
|
3036
|
+
if ((_g = kf.tangentOut) != null ? _g : kf.to) out2.tangentOut = (_h = kf.tangentOut) != null ? _h : kf.to;
|
|
3037
|
+
return out2;
|
|
3038
|
+
});
|
|
3039
|
+
const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
|
|
3040
|
+
const out = { kfs: expanded };
|
|
3041
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
3042
|
+
return out;
|
|
3043
|
+
}
|
|
3044
|
+
function materialiseInternalLoopsInTree(root, duration) {
|
|
3045
|
+
const ret = walkAndMaterialiseLoops(root, duration);
|
|
3046
|
+
return ret != null ? ret : root;
|
|
3047
|
+
}
|
|
3048
|
+
function walkAndMaterialiseLoops(node, duration) {
|
|
3049
|
+
let newChildren;
|
|
3050
|
+
if (node.children) {
|
|
3051
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
3052
|
+
const ret = walkAndMaterialiseLoops(node.children[i], duration);
|
|
3053
|
+
if (ret !== null) {
|
|
3054
|
+
if (!newChildren) newChildren = node.children.slice();
|
|
3055
|
+
newChildren[i] = ret;
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
let newAnimate;
|
|
3060
|
+
const animBucket = node.animate;
|
|
3061
|
+
if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
|
|
3062
|
+
const animDef = animBucket;
|
|
3063
|
+
for (const propName of Object.keys(animDef)) {
|
|
3064
|
+
const propAnim = animDef[propName];
|
|
3065
|
+
const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);
|
|
3066
|
+
if (materialised !== propAnim) {
|
|
3067
|
+
if (!newAnimate) newAnimate = __spreadValues({}, animDef);
|
|
3068
|
+
newAnimate[propName] = materialised;
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
if (!newChildren && !newAnimate) return null;
|
|
3073
|
+
const cloned = __spreadValues({}, node);
|
|
3074
|
+
if (newChildren) cloned.children = newChildren;
|
|
3075
|
+
if (newAnimate) cloned.animate = newAnimate;
|
|
3076
|
+
return cloned;
|
|
3077
|
+
}
|
|
3078
|
+
var _elementIdCounter = 0;
|
|
3079
|
+
function generateElementId() {
|
|
3080
|
+
return "_px_el_" + ++_elementIdCounter;
|
|
3081
|
+
}
|
|
3082
|
+
function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.webapi) {
|
|
3083
|
+
const normalized = {};
|
|
3084
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
3085
|
+
const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
|
|
3086
|
+
if (normalizedKfs.length > 0) {
|
|
3087
|
+
const out = { kfs: normalizedKfs };
|
|
3088
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
3089
|
+
if (propAnim.loop !== void 0) out.loop = propAnim.loop;
|
|
3090
|
+
normalized[propName] = engine === PxAnimatorEngine.webapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
|
|
3091
|
+
}
|
|
3092
|
+
}
|
|
3093
|
+
return normalized;
|
|
3094
|
+
}
|
|
3095
|
+
function getNormalisedBindings(doc, engine = PxAnimatorEngine.webapi) {
|
|
3096
|
+
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
3097
|
+
const defs = getDefs(doc);
|
|
3098
|
+
const duration = animatorConfig.duration || 1e3;
|
|
3099
|
+
const bindings = [];
|
|
3100
|
+
const processAnimation = (id, animate) => {
|
|
3101
|
+
if (!animate) return null;
|
|
3102
|
+
const animDefs = resolveElementAnimation(animate, defs);
|
|
3103
|
+
if (animDefs.length === 0) return null;
|
|
3104
|
+
const merged = mergeAnimationDefinitions(animDefs);
|
|
3105
|
+
const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
|
|
3106
|
+
if (Object.keys(normalizedAnim).length === 0) return null;
|
|
3107
|
+
return {
|
|
3108
|
+
id,
|
|
3109
|
+
animate: normalizedAnim
|
|
3110
|
+
};
|
|
3111
|
+
};
|
|
3112
|
+
const docBindings = getBindings(doc);
|
|
3113
|
+
if (docBindings) {
|
|
3114
|
+
for (const binding of docBindings) {
|
|
3115
|
+
const normalized = processAnimation(binding.id, binding.animate);
|
|
3116
|
+
if (normalized) bindings.push(normalized);
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
const processNode = (node) => {
|
|
3120
|
+
const inlineAnim = node.animate;
|
|
3121
|
+
if (inlineAnim && Object.keys(inlineAnim).length > 0) {
|
|
3122
|
+
const nodeId = node.id || generateElementId();
|
|
3123
|
+
node.id = nodeId;
|
|
3124
|
+
const normalized = processAnimation(nodeId, inlineAnim);
|
|
3125
|
+
if (normalized) bindings.push(normalized);
|
|
3126
|
+
}
|
|
3127
|
+
if (node.children) {
|
|
3128
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
3129
|
+
processNode(node.children[i]);
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
};
|
|
3133
|
+
if (doc.children) {
|
|
3134
|
+
for (let i = 0; i < doc.children.length; i++) {
|
|
3135
|
+
processNode(doc.children[i]);
|
|
2148
3136
|
}
|
|
2149
3137
|
}
|
|
2150
|
-
return
|
|
3138
|
+
return bindings;
|
|
2151
3139
|
}
|
|
2152
|
-
function
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
3140
|
+
function getKeyframesPair(keyframes, progress) {
|
|
3141
|
+
var _a, _b;
|
|
3142
|
+
let prevKf = keyframes[0];
|
|
3143
|
+
let nextKf = keyframes[keyframes.length - 1];
|
|
3144
|
+
for (let j = 0; j < keyframes.length - 1; j++) {
|
|
3145
|
+
const aOff = (_a = keyframes[j].t) != null ? _a : 0;
|
|
3146
|
+
const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
|
|
3147
|
+
if (aOff <= progress && progress <= bOff) {
|
|
3148
|
+
prevKf = keyframes[j];
|
|
3149
|
+
nextKf = keyframes[j + 1];
|
|
3150
|
+
break;
|
|
3151
|
+
}
|
|
2158
3152
|
}
|
|
2159
|
-
return
|
|
2160
|
-
}
|
|
2161
|
-
function isPathString(value) {
|
|
2162
|
-
return typeof value === "string" && extractPathData(value) !== void 0;
|
|
3153
|
+
return { prevKf, nextKf };
|
|
2163
3154
|
}
|
|
2164
|
-
function
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
3155
|
+
function calcPropertyValue(propName, propAnim, progress) {
|
|
3156
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
3157
|
+
const keyframes = propAnim.kfs || propAnim.keyframes || [];
|
|
3158
|
+
if (keyframes.length === 0) return null;
|
|
3159
|
+
const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
|
|
3160
|
+
let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
|
|
3161
|
+
localProgress = clamp(localProgress, 0, 1);
|
|
3162
|
+
const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
|
|
3163
|
+
if (easing && Array.isArray(easing)) {
|
|
3164
|
+
try {
|
|
3165
|
+
localProgress = cubicBezier(easing)(localProgress);
|
|
3166
|
+
} catch (e) {
|
|
3167
|
+
}
|
|
2168
3168
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
3169
|
+
let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
3170
|
+
let cssValue = null;
|
|
3171
|
+
const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
|
|
3172
|
+
const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
|
|
3173
|
+
if (cssAttrName === "d") {
|
|
3174
|
+
const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
|
|
3175
|
+
const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
|
|
3176
|
+
cssValue = interpolateBeziers(
|
|
3177
|
+
prevPaths,
|
|
3178
|
+
nextPaths,
|
|
3179
|
+
localProgress
|
|
3180
|
+
).map((bz) => bezierToSvgPath(bz)).join("");
|
|
3181
|
+
} else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {
|
|
3182
|
+
cssValue = toRGBA(interpolateColor(
|
|
3183
|
+
prevV || [0, 0, 0, 1],
|
|
3184
|
+
nextV || [0, 0, 0, 1],
|
|
3185
|
+
localProgress
|
|
3186
|
+
));
|
|
3187
|
+
cssAttrName = propName;
|
|
3188
|
+
} else if (cssAttrName === "stroke-dasharray") {
|
|
3189
|
+
cssValue = interpolateVec(
|
|
3190
|
+
prevV || [],
|
|
3191
|
+
nextV || [],
|
|
3192
|
+
localProgress
|
|
3193
|
+
).join(" ");
|
|
3194
|
+
cssAttrName = propName;
|
|
3195
|
+
} else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
|
|
3196
|
+
const partKeys = /* @__PURE__ */ new Set([
|
|
3197
|
+
...prevV ? Object.keys(prevV) : [],
|
|
3198
|
+
...nextV ? Object.keys(nextV) : []
|
|
3199
|
+
]);
|
|
3200
|
+
const partsResult = {};
|
|
3201
|
+
for (const partKey of partKeys) {
|
|
3202
|
+
const prevPart = prevV == null ? void 0 : prevV[partKey];
|
|
3203
|
+
const nextPart = nextV == null ? void 0 : nextV[partKey];
|
|
3204
|
+
if (partKey === "rotate") {
|
|
3205
|
+
partsResult.rotate = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
|
|
3206
|
+
} else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
|
|
3207
|
+
const fallback = partKey === "scale" ? [1, 1] : [0, 0];
|
|
3208
|
+
const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
|
|
3209
|
+
partsResult[partKey] = interp;
|
|
2181
3210
|
}
|
|
2182
3211
|
}
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
3212
|
+
if (propAnimIsMotionPath(propAnim)) {
|
|
3213
|
+
const prevTr = prevV.translate;
|
|
3214
|
+
const nextTr = nextV.translate;
|
|
3215
|
+
if (Array.isArray(prevTr) && Array.isArray(nextTr)) {
|
|
3216
|
+
const sample = evaluateMotionPathSegment(
|
|
3217
|
+
prevKf,
|
|
3218
|
+
nextKf,
|
|
3219
|
+
[+prevTr[0], +prevTr[1]],
|
|
3220
|
+
[+nextTr[0], +nextTr[1]],
|
|
3221
|
+
localProgress,
|
|
3222
|
+
!!propAnim.autoOrient
|
|
3223
|
+
);
|
|
3224
|
+
partsResult.translate = [sample.translate[0], sample.translate[1]];
|
|
3225
|
+
if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
|
|
2193
3226
|
}
|
|
2194
|
-
return { paths };
|
|
2195
3227
|
}
|
|
2196
|
-
|
|
3228
|
+
cssValue = composeTransformParts(partsResult, { withUnits: false });
|
|
3229
|
+
cssAttrName = "transform";
|
|
3230
|
+
} else if (cssAttrName === "translate") {
|
|
3231
|
+
const v = interpolateVec(
|
|
3232
|
+
prevV || [0, 0],
|
|
3233
|
+
nextV || [0, 0],
|
|
3234
|
+
localProgress
|
|
3235
|
+
);
|
|
3236
|
+
cssValue = "translate(" + v.join(",") + ")";
|
|
3237
|
+
cssAttrName = "transform";
|
|
3238
|
+
} else if (cssAttrName === "rotate") {
|
|
3239
|
+
const v = interpolateNum(
|
|
3240
|
+
+(prevV || 0),
|
|
3241
|
+
+(nextV || 0),
|
|
3242
|
+
localProgress
|
|
3243
|
+
);
|
|
3244
|
+
cssValue = "rotate(" + v + ")";
|
|
3245
|
+
cssAttrName = "transform";
|
|
3246
|
+
} else if (cssAttrName === "scale") {
|
|
3247
|
+
const v = interpolateVec(
|
|
3248
|
+
prevV || [1, 1],
|
|
3249
|
+
nextV || [1, 1],
|
|
3250
|
+
localProgress
|
|
3251
|
+
);
|
|
3252
|
+
cssValue = "scale(" + v.join(",") + ")";
|
|
3253
|
+
cssAttrName = "transform";
|
|
3254
|
+
} else {
|
|
3255
|
+
const num2 = interpolateNum(
|
|
3256
|
+
+(prevV || 0),
|
|
3257
|
+
+(nextV || 0),
|
|
3258
|
+
localProgress
|
|
3259
|
+
);
|
|
3260
|
+
cssValue = num2;
|
|
2197
3261
|
}
|
|
2198
|
-
if (
|
|
2199
|
-
|
|
2200
|
-
return { paths: parseSvgPathToBezier(d) };
|
|
3262
|
+
if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
|
|
3263
|
+
cssValue = cssValue * 100 + "%";
|
|
2201
3264
|
}
|
|
2202
|
-
return
|
|
3265
|
+
return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
|
|
2203
3266
|
}
|
|
2204
|
-
function
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
return defs.easings[easing];
|
|
3267
|
+
function calcAnimationValues(animDef, progress) {
|
|
3268
|
+
const result = {};
|
|
3269
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
3270
|
+
const computed = calcPropertyValue(propName, propAnim, progress);
|
|
3271
|
+
if (computed) {
|
|
3272
|
+
result[computed.k] = computed.v;
|
|
3273
|
+
}
|
|
2212
3274
|
}
|
|
2213
|
-
|
|
2214
|
-
return void 0;
|
|
3275
|
+
return result;
|
|
2215
3276
|
}
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
3277
|
+
|
|
3278
|
+
// src/effects/trimPathEffect.ts
|
|
3279
|
+
function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
|
|
3280
|
+
if (!trimPath) return node;
|
|
3281
|
+
const trimAllAsOne = !!trimPath.trimAllAsOne;
|
|
3282
|
+
const leafEntries = [];
|
|
3283
|
+
let acc = 0;
|
|
3284
|
+
const measure = (n) => {
|
|
3285
|
+
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
3286
|
+
for (const ch of n.children) measure(ch);
|
|
3287
|
+
return;
|
|
2222
3288
|
}
|
|
2223
|
-
|
|
3289
|
+
const d = typeof n.d === "string" ? n.d : rectToPathD(n);
|
|
3290
|
+
if (d === void 0) return;
|
|
3291
|
+
const subpaths = parseSvgPathToBezier(d);
|
|
3292
|
+
if (!subpaths.length) return;
|
|
3293
|
+
const entry = { leaf: n, subpaths: [] };
|
|
3294
|
+
for (const sp of subpaths) {
|
|
3295
|
+
if (!trimAllAsOne) acc = 0;
|
|
3296
|
+
const lengthPx = pxBezierPathLength(sp);
|
|
3297
|
+
entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: acc });
|
|
3298
|
+
acc += lengthPx;
|
|
3299
|
+
}
|
|
3300
|
+
leafEntries.push(entry);
|
|
3301
|
+
};
|
|
3302
|
+
measure(node);
|
|
3303
|
+
if (!leafEntries.length) return node;
|
|
3304
|
+
const chainLengthPx = acc;
|
|
3305
|
+
if (trimAllAsOne && chainLengthPx < 1e-3) return node;
|
|
3306
|
+
const offsetReadRaw = readAnimatable(trimPath.offset);
|
|
3307
|
+
const offsetRead = offsetReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: 0 } : offsetReadRaw;
|
|
3308
|
+
const rangeReadRaw = readRangeWithCrossings(trimPath.range);
|
|
3309
|
+
const rangeRead = rangeReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: [0, 1] } : rangeReadRaw;
|
|
3310
|
+
const offsetValues = readScalarValues(offsetRead);
|
|
3311
|
+
const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;
|
|
3312
|
+
const maxOffset = offsetValues.length ? Math.max(...offsetValues) : 0;
|
|
3313
|
+
const minMaxOffset = [minOffset, maxOffset];
|
|
3314
|
+
if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
|
|
3315
|
+
const entry = leafEntries[0];
|
|
3316
|
+
const sp = entry.subpaths[0];
|
|
3317
|
+
const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
|
|
3318
|
+
if (pathLengthPx < 1e-3) return node;
|
|
3319
|
+
const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
|
|
3320
|
+
return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
|
|
3321
|
+
}
|
|
3322
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
3323
|
+
for (const entry of leafEntries) {
|
|
3324
|
+
const newChildren = [];
|
|
3325
|
+
for (const sp of entry.subpaths) {
|
|
3326
|
+
const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
|
|
3327
|
+
if (pathLengthPx < 1e-3) continue;
|
|
3328
|
+
const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
|
|
3329
|
+
newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
|
|
3330
|
+
}
|
|
3331
|
+
replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
|
|
2224
3332
|
}
|
|
2225
|
-
|
|
3333
|
+
const swap = (n) => {
|
|
3334
|
+
const r = replacements.get(n);
|
|
3335
|
+
if (r) return r;
|
|
3336
|
+
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
3337
|
+
return __spreadProps(__spreadValues({}, n), { children: n.children.map(swap) });
|
|
3338
|
+
}
|
|
3339
|
+
return n;
|
|
3340
|
+
};
|
|
3341
|
+
return swap(node);
|
|
3342
|
+
}
|
|
3343
|
+
function wrapLeafAsGroup(leaf, children) {
|
|
3344
|
+
const wrapper = __spreadProps(__spreadValues({}, leaf), { type: "g", children });
|
|
3345
|
+
delete wrapper.d;
|
|
3346
|
+
delete wrapper.strokeDasharray;
|
|
3347
|
+
delete wrapper.strokeDashoffset;
|
|
3348
|
+
delete wrapper.effects;
|
|
3349
|
+
return wrapper;
|
|
2226
3350
|
}
|
|
2227
|
-
function
|
|
2228
|
-
|
|
2229
|
-
const
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
3351
|
+
function buildSubpathNodes(leaf, subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx) {
|
|
3352
|
+
const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
|
|
3353
|
+
const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
|
|
3354
|
+
const dashOffsetAttr = computeAnimAttr(offsetRead, offsetToDashOffset);
|
|
3355
|
+
const dashArrayAttr = computeAnimAttr(rangeRead, rangeToDasharray);
|
|
3356
|
+
const strokeOpacityAttr = computeOpacityFromRange(rangeRead);
|
|
3357
|
+
const dStr = bezierToSvgPath(subpath);
|
|
3358
|
+
const base = makeBareSubpath(dStr);
|
|
3359
|
+
applyAttr(base, "strokeDasharray", dashArrayAttr);
|
|
3360
|
+
applyAttr(base, "strokeDashoffset", dashOffsetAttr);
|
|
3361
|
+
applyAttr(base, "strokeOpacity", strokeOpacityAttr);
|
|
3362
|
+
return [base];
|
|
3363
|
+
}
|
|
3364
|
+
function collapseLeafWithTrim(leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead) {
|
|
3365
|
+
const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
|
|
3366
|
+
const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
|
|
3367
|
+
const node = __spreadValues({}, leaf);
|
|
3368
|
+
delete node.effects;
|
|
3369
|
+
applyAttr(node, "strokeDasharray", computeAnimAttr(rangeRead, rangeToDasharray));
|
|
3370
|
+
applyAttr(node, "strokeDashoffset", computeAnimAttr(offsetRead, offsetToDashOffset));
|
|
3371
|
+
applyAttr(node, "strokeOpacity", computeOpacityFromRange(rangeRead));
|
|
3372
|
+
return node;
|
|
3373
|
+
}
|
|
3374
|
+
function makeBareSubpath(dStr) {
|
|
3375
|
+
return { type: "path", d: dStr };
|
|
3376
|
+
}
|
|
3377
|
+
var SMALL_PADDING_PX = 1;
|
|
3378
|
+
function makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset) {
|
|
3379
|
+
const [minIdx] = getOffsetIndexRange(minMaxOffset);
|
|
3380
|
+
return (offsetVal) => pathLengthPx * (-offsetVal - minIdx + startOffsetPct) + SMALL_PADDING_PX;
|
|
3381
|
+
}
|
|
3382
|
+
function makeRangeToDasharray(pathLengthPx, minMaxOffset) {
|
|
3383
|
+
const [minIdx, maxIdx] = getOffsetIndexRange(minMaxOffset);
|
|
3384
|
+
const repeats = maxIdx - minIdx + 1;
|
|
3385
|
+
return (rangeVal) => {
|
|
3386
|
+
const a = clamp(rangeVal[0], 0, 1);
|
|
3387
|
+
const b = clamp(rangeVal[1], 0, 1);
|
|
3388
|
+
const minR = Math.min(a, b);
|
|
3389
|
+
const maxR = Math.max(a, b);
|
|
3390
|
+
const out = [0];
|
|
3391
|
+
let gap = SMALL_PADDING_PX;
|
|
3392
|
+
for (let i = 0; i < repeats; i++) {
|
|
3393
|
+
out.push(gap + minR * pathLengthPx);
|
|
3394
|
+
out.push((maxR - minR) * pathLengthPx);
|
|
3395
|
+
gap = (1 - maxR) * pathLengthPx;
|
|
2237
3396
|
}
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
}
|
|
2241
|
-
return results;
|
|
3397
|
+
out.push(gap + SMALL_PADDING_PX);
|
|
3398
|
+
return out;
|
|
3399
|
+
};
|
|
2242
3400
|
}
|
|
2243
|
-
function
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
3401
|
+
function getOffsetIndexRange(minMaxOffset) {
|
|
3402
|
+
return [
|
|
3403
|
+
Math.floor(Math.min(-minMaxOffset[0], -minMaxOffset[1])),
|
|
3404
|
+
Math.ceil(Math.max(-minMaxOffset[0], -minMaxOffset[1]))
|
|
3405
|
+
];
|
|
3406
|
+
}
|
|
3407
|
+
function readScalarValues(r) {
|
|
3408
|
+
var _a;
|
|
3409
|
+
if (r.kind === "absent" /* Absent */) return [];
|
|
3410
|
+
if (r.kind === "static" /* Static */) return [r.value];
|
|
3411
|
+
const out = [];
|
|
3412
|
+
for (const kf of r.keyframes) {
|
|
3413
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
3414
|
+
if (typeof v === "number") out.push(v);
|
|
2255
3415
|
}
|
|
2256
|
-
return
|
|
3416
|
+
return out;
|
|
2257
3417
|
}
|
|
2258
|
-
function
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
3418
|
+
function computeAnimAttr(read, map) {
|
|
3419
|
+
if (read.kind === "absent" /* Absent */) return void 0;
|
|
3420
|
+
if (read.kind === "static" /* Static */) return { kind: "static" /* Static */, value: map(read.value) };
|
|
3421
|
+
return {
|
|
3422
|
+
kind: "animated" /* Animated */,
|
|
3423
|
+
keyframes: read.keyframes.map((kf) => {
|
|
3424
|
+
var _a, _b, _c, _d;
|
|
3425
|
+
return {
|
|
3426
|
+
time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
|
|
3427
|
+
value: map((_c = kf.value) != null ? _c : kf.v),
|
|
3428
|
+
easing: (_d = kf.easing) != null ? _d : kf.e
|
|
3429
|
+
};
|
|
3430
|
+
})
|
|
3431
|
+
};
|
|
3432
|
+
}
|
|
3433
|
+
function applyAttr(node, attrName, attr) {
|
|
3434
|
+
if (!attr) return;
|
|
3435
|
+
if (attr.kind === "static" /* Static */) {
|
|
3436
|
+
node[attrName] = attr.value;
|
|
3437
|
+
return;
|
|
2267
3438
|
}
|
|
2268
|
-
const
|
|
2269
|
-
const
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
3439
|
+
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
3440
|
+
const animate = __spreadValues({}, prevAnimate || {});
|
|
3441
|
+
animate[attrName] = { keyframes: attr.keyframes };
|
|
3442
|
+
node.animate = animate;
|
|
3443
|
+
}
|
|
3444
|
+
function computeOpacityFromRange(rangeRead) {
|
|
3445
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3446
|
+
const hide = (v) => v[0] === v[1];
|
|
3447
|
+
if (rangeRead.kind === "absent" /* Absent */) return void 0;
|
|
3448
|
+
if (rangeRead.kind === "static" /* Static */) return hide(rangeRead.value) ? { kind: "static" /* Static */, value: 0 } : void 0;
|
|
3449
|
+
const kfs = rangeRead.keyframes;
|
|
3450
|
+
let anyHide = false;
|
|
3451
|
+
let allHide = true;
|
|
3452
|
+
for (const kf of kfs) {
|
|
3453
|
+
if (hide((_a = kf.value) != null ? _a : kf.v)) anyHide = true;
|
|
3454
|
+
else allHide = false;
|
|
2277
3455
|
}
|
|
2278
|
-
|
|
2279
|
-
if (
|
|
2280
|
-
const
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
3456
|
+
if (!anyHide) return void 0;
|
|
3457
|
+
if (allHide) return { kind: "static" /* Static */, value: 0 };
|
|
3458
|
+
const out = [];
|
|
3459
|
+
for (let i = 0; i < kfs.length; i++) {
|
|
3460
|
+
const kf = kfs[i];
|
|
3461
|
+
const prevKf = i > 0 ? kfs[i - 1] : void 0;
|
|
3462
|
+
const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
|
|
3463
|
+
const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
|
|
3464
|
+
const thisHide = hide((_d = kf.value) != null ? _d : kf.v);
|
|
3465
|
+
const prevHide = prevKf ? thisHide && hide((_e = prevKf.value) != null ? _e : prevKf.v) : thisHide;
|
|
3466
|
+
const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
|
|
3467
|
+
if (prevHide && !nextHide) {
|
|
3468
|
+
out.push({ time: t, value: 0 });
|
|
3469
|
+
out.push({ time: t + 1, value: 1 });
|
|
3470
|
+
} else if (!prevHide && nextHide) {
|
|
3471
|
+
out.push({ time: t - 1, value: 1 });
|
|
3472
|
+
out.push({ time: t, value: 0 });
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
if (out.length <= 1) return void 0;
|
|
3476
|
+
return { kind: "animated" /* Animated */, keyframes: out };
|
|
3477
|
+
}
|
|
3478
|
+
function readRangeWithCrossings(raw) {
|
|
3479
|
+
const r = readAnimatable(raw);
|
|
3480
|
+
if (r.kind !== "animated" /* Animated */) return r;
|
|
3481
|
+
const kfs = r.keyframes.map((kf) => {
|
|
3482
|
+
var _a, _b, _c, _d;
|
|
3483
|
+
return {
|
|
3484
|
+
time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
|
|
3485
|
+
value: (_c = kf.value) != null ? _c : kf.v,
|
|
3486
|
+
easing: (_d = kf.easing) != null ? _d : kf.e
|
|
3487
|
+
};
|
|
3488
|
+
});
|
|
3489
|
+
const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
|
|
3490
|
+
if (!hasReverse) {
|
|
3491
|
+
return {
|
|
3492
|
+
kind: "animated" /* Animated */,
|
|
3493
|
+
keyframes: kfs.map((kf) => ({ time: kf.time, value: kf.value, easing: kf.easing }))
|
|
3494
|
+
};
|
|
3495
|
+
}
|
|
3496
|
+
const crossingTimes = [];
|
|
3497
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
3498
|
+
const prev = kfs[i - 1];
|
|
3499
|
+
const cur = kfs[i];
|
|
3500
|
+
const dPrev = prev.value[1] - prev.value[0];
|
|
3501
|
+
const dCur = cur.value[1] - cur.value[0];
|
|
3502
|
+
if (dPrev * dCur < 0) {
|
|
3503
|
+
const t = bisectionForRangeCrossing(prev, cur);
|
|
3504
|
+
if (t !== null && t > prev.time && t < cur.time) {
|
|
3505
|
+
crossingTimes.push(Math.round(t));
|
|
2304
3506
|
}
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
const uniqueTs = Array.from(new Set(crossingTimes)).sort((a, b) => a - b);
|
|
3510
|
+
const out = [];
|
|
3511
|
+
let j = 0;
|
|
3512
|
+
for (const kf of kfs) {
|
|
3513
|
+
while (j < uniqueTs.length && uniqueTs[j] < kf.time) {
|
|
3514
|
+
const t = uniqueTs[j++];
|
|
3515
|
+
const v2 = interpolateRangeAt(kfs, t);
|
|
3516
|
+
const m = (v2[0] + v2[1]) / 2;
|
|
3517
|
+
out.push({ time: t, value: [m, m] });
|
|
3518
|
+
}
|
|
3519
|
+
const v = kf.value[0] > kf.value[1] ? [kf.value[1], kf.value[0]] : kf.value;
|
|
3520
|
+
out.push({ time: kf.time, value: v, easing: kf.easing });
|
|
3521
|
+
}
|
|
3522
|
+
while (j < uniqueTs.length) {
|
|
3523
|
+
const t = uniqueTs[j++];
|
|
3524
|
+
const v = interpolateRangeAt(kfs, t);
|
|
3525
|
+
const m = (v[0] + v[1]) / 2;
|
|
3526
|
+
out.push({ time: t, value: [m, m] });
|
|
3527
|
+
}
|
|
3528
|
+
return { kind: "animated" /* Animated */, keyframes: out };
|
|
3529
|
+
}
|
|
3530
|
+
function bisectionForRangeCrossing(prev, cur) {
|
|
3531
|
+
const f = (t) => {
|
|
3532
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
3533
|
+
const v0 = prev.value[0] + (cur.value[0] - prev.value[0]) * a;
|
|
3534
|
+
const v1 = prev.value[1] + (cur.value[1] - prev.value[1]) * a;
|
|
3535
|
+
return v1 - v0;
|
|
3536
|
+
};
|
|
3537
|
+
let lo = prev.time, hi = cur.time;
|
|
3538
|
+
let fLo = f(lo);
|
|
3539
|
+
if (fLo === 0) return lo;
|
|
3540
|
+
const fHi = f(hi);
|
|
3541
|
+
if (fHi === 0) return hi;
|
|
3542
|
+
if (fLo * fHi > 0) return null;
|
|
3543
|
+
for (let i = 0; i < 100; i++) {
|
|
3544
|
+
const mid = (lo + hi) / 2;
|
|
3545
|
+
const fMid = f(mid);
|
|
3546
|
+
if (fMid === 0 || Math.abs(hi - lo) < 1e-4) return mid;
|
|
3547
|
+
if (fLo * fMid < 0) {
|
|
3548
|
+
hi = mid;
|
|
2305
3549
|
} else {
|
|
2306
|
-
|
|
3550
|
+
lo = mid;
|
|
3551
|
+
fLo = fMid;
|
|
2307
3552
|
}
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
}
|
|
2324
|
-
looped.push({
|
|
2325
|
-
t: repStart + entry.relT * segDuration,
|
|
2326
|
-
v: entry.v,
|
|
2327
|
-
e: i < entries.length - 1 ? entry.e : void 0
|
|
2328
|
-
});
|
|
3553
|
+
}
|
|
3554
|
+
return (lo + hi) / 2;
|
|
3555
|
+
}
|
|
3556
|
+
function interpolateRangeAt(kfs, t) {
|
|
3557
|
+
if (t <= kfs[0].time) return kfs[0].value;
|
|
3558
|
+
if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
|
|
3559
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
3560
|
+
if (t <= kfs[i].time) {
|
|
3561
|
+
const prev = kfs[i - 1];
|
|
3562
|
+
const cur = kfs[i];
|
|
3563
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
3564
|
+
return [
|
|
3565
|
+
prev.value[0] + (cur.value[0] - prev.value[0]) * a,
|
|
3566
|
+
prev.value[1] + (cur.value[1] - prev.value[1]) * a
|
|
3567
|
+
];
|
|
2329
3568
|
}
|
|
2330
3569
|
}
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
3570
|
+
return kfs[kfs.length - 1].value;
|
|
3571
|
+
}
|
|
3572
|
+
function pxBezierPathLength(path) {
|
|
3573
|
+
const v = path.v;
|
|
3574
|
+
if (!v || v.length < 2) return 0;
|
|
3575
|
+
let total = 0;
|
|
3576
|
+
for (let i = 0; i < v.length - 1; i++) {
|
|
3577
|
+
total += segmentLength(path, i, i + 1);
|
|
2336
3578
|
}
|
|
2337
|
-
if (
|
|
2338
|
-
|
|
2339
|
-
const repStart = fillStart + fullReps * segDuration;
|
|
2340
|
-
appendRep(repStart, isReversed, partialFraction);
|
|
3579
|
+
if (path.c && v.length > 1) {
|
|
3580
|
+
total += segmentLength(path, v.length - 1, 0);
|
|
2341
3581
|
}
|
|
2342
|
-
|
|
2343
|
-
|
|
3582
|
+
return total;
|
|
3583
|
+
}
|
|
3584
|
+
function segmentLength(path, from, to) {
|
|
3585
|
+
var _a, _b, _c, _d;
|
|
3586
|
+
const v = path.v;
|
|
3587
|
+
const p0 = v[from];
|
|
3588
|
+
const p3 = v[to];
|
|
3589
|
+
const p1 = (_b = (_a = path.o) == null ? void 0 : _a[from]) != null ? _b : p0;
|
|
3590
|
+
const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
|
|
3591
|
+
const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
|
|
3592
|
+
return lut.ds[lut.ds.length - 1];
|
|
3593
|
+
}
|
|
3594
|
+
function rectToPathD(node) {
|
|
3595
|
+
var _a, _b, _c, _d;
|
|
3596
|
+
if (node.type !== "rect") return void 0;
|
|
3597
|
+
const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
|
|
3598
|
+
const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
|
|
3599
|
+
return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
// src/effects/PlayerEffectsUtil.ts
|
|
3603
|
+
function applyPlayerEffects(root) {
|
|
3604
|
+
const ctx = {
|
|
3605
|
+
defs: [],
|
|
3606
|
+
warnings: [],
|
|
3607
|
+
errors: [],
|
|
3608
|
+
idMap: /* @__PURE__ */ new Map(),
|
|
3609
|
+
nextId: 0,
|
|
3610
|
+
contentRefInnerIds: /* @__PURE__ */ new Map(),
|
|
3611
|
+
maskAncestorChains: /* @__PURE__ */ new Map()
|
|
3612
|
+
};
|
|
3613
|
+
const working = clone(root);
|
|
3614
|
+
indexById(working, ctx.idMap);
|
|
3615
|
+
identifyContentRefTargets(working, ctx, () => genId(ctx, "inner"));
|
|
3616
|
+
collectMaskAncestorChains(working, ctx);
|
|
3617
|
+
const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);
|
|
3618
|
+
const out = applyPlayerEffects_retime(afterPass1, ctx);
|
|
3619
|
+
spliceDefs(out, ctx.defs);
|
|
3620
|
+
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
3621
|
+
}
|
|
3622
|
+
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
3623
|
+
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
3624
|
+
const fx = node.effects;
|
|
3625
|
+
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
3626
|
+
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
3627
|
+
if (!fx && !innerIdForContentRef) return node;
|
|
3628
|
+
const { transformation, repeater, maskedBy, trimPath, retime, ref, fillGradient, strokeGradient, textAlongPath } = fx != null ? fx : {};
|
|
3629
|
+
const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
|
|
3630
|
+
if (fx) delete node.effects;
|
|
3631
|
+
let n = node;
|
|
3632
|
+
n = applyTextAlongPathEffect(n, textAlongPath, ctx);
|
|
3633
|
+
n = applyFillGradientEffect(n, fillGradient, ctx);
|
|
3634
|
+
n = applyStrokeGradientEffect(n, strokeGradient, ctx);
|
|
3635
|
+
n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
|
|
3636
|
+
n = applyRepeaterEffect(n, repeater, ctx);
|
|
3637
|
+
n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
|
|
3638
|
+
if (innerIdForContentRef) {
|
|
3639
|
+
n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
|
|
2344
3640
|
} else {
|
|
2345
|
-
|
|
3641
|
+
n = applyRefAndTransformationEffect(n, ref, transformation, ctx);
|
|
2346
3642
|
}
|
|
3643
|
+
if (retime) node.effects = { retime };
|
|
3644
|
+
if (originalId) ctx.idMap.set(originalId, n);
|
|
3645
|
+
return n;
|
|
2347
3646
|
}
|
|
2348
|
-
function
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
3647
|
+
function applyPlayerEffects_retime(node, ctx) {
|
|
3648
|
+
applyAllRetimeEffects(node, ctx);
|
|
3649
|
+
return node;
|
|
3650
|
+
}
|
|
3651
|
+
|
|
3652
|
+
// src/PxAnimatorUseMaterialiser.ts
|
|
3653
|
+
function materialiseAnimatedUseInstances(root) {
|
|
3654
|
+
var _a;
|
|
3655
|
+
const idMap = buildIdMap(root);
|
|
3656
|
+
const animatedIds = computeAnimatedSubtreeIds(root, idMap);
|
|
3657
|
+
if (animatedIds.size === 0) return root;
|
|
3658
|
+
let idCounter = 0;
|
|
3659
|
+
const genId3 = () => "_lw_use_mat_" + ++idCounter;
|
|
3660
|
+
const defsCollector = [];
|
|
3661
|
+
const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector);
|
|
3662
|
+
if (defsCollector.length === 0) return walked;
|
|
3663
|
+
const defsNode = { type: "defs", children: defsCollector };
|
|
3664
|
+
const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
|
|
3665
|
+
return __spreadProps(__spreadValues({}, walked), { children: newChildren });
|
|
3666
|
+
}
|
|
3667
|
+
function buildIdMap(root) {
|
|
3668
|
+
const map = /* @__PURE__ */ new Map();
|
|
3669
|
+
const visit = (n) => {
|
|
3670
|
+
var _a;
|
|
3671
|
+
if (typeof n.id === "string") map.set(n.id, n);
|
|
3672
|
+
(_a = n.children) == null ? void 0 : _a.forEach(visit);
|
|
3673
|
+
};
|
|
3674
|
+
visit(root);
|
|
3675
|
+
return map;
|
|
3676
|
+
}
|
|
3677
|
+
function computeAnimatedSubtreeIds(root, idMap) {
|
|
3678
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
3679
|
+
const result = /* @__PURE__ */ new Set();
|
|
3680
|
+
const hasAnim = (n, visiting) => {
|
|
3681
|
+
const cached = cache.get(n);
|
|
3682
|
+
if (cached !== void 0) return cached;
|
|
3683
|
+
if (visiting.has(n)) return false;
|
|
3684
|
+
visiting.add(n);
|
|
3685
|
+
let r = false;
|
|
3686
|
+
if (n.animate && typeof n.animate === "object" && !Array.isArray(n.animate)) {
|
|
3687
|
+
for (const _ in n.animate) {
|
|
3688
|
+
r = true;
|
|
3689
|
+
break;
|
|
3690
|
+
}
|
|
2358
3691
|
}
|
|
2359
|
-
if (
|
|
2360
|
-
|
|
3692
|
+
if (!r && n.children) {
|
|
3693
|
+
for (const ch of n.children) {
|
|
3694
|
+
if (hasAnim(ch, visiting)) {
|
|
3695
|
+
r = true;
|
|
3696
|
+
break;
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
2361
3699
|
}
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
}
|
|
3700
|
+
if (!r && n.type === "use" && typeof n.href === "string") {
|
|
3701
|
+
const targetId = stripHash2(n.href);
|
|
3702
|
+
const target = targetId ? idMap.get(targetId) : void 0;
|
|
3703
|
+
if (target) r = hasAnim(target, visiting);
|
|
3704
|
+
}
|
|
3705
|
+
visiting.delete(n);
|
|
3706
|
+
cache.set(n, r);
|
|
3707
|
+
return r;
|
|
3708
|
+
};
|
|
3709
|
+
for (const [id, node] of idMap) {
|
|
3710
|
+
if (hasAnim(node, /* @__PURE__ */ new Set())) result.add(id);
|
|
2367
3711
|
}
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
3712
|
+
return result;
|
|
3713
|
+
}
|
|
3714
|
+
function stripHash2(href) {
|
|
3715
|
+
if (typeof href !== "string") return void 0;
|
|
3716
|
+
return href.startsWith("#") ? href.slice(1) : href;
|
|
3717
|
+
}
|
|
3718
|
+
function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector) {
|
|
3719
|
+
const clone2 = deepClonePxNode(target);
|
|
3720
|
+
regenerateIdsAndRewriteRefs(clone2, genId3);
|
|
3721
|
+
const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector) : clone2;
|
|
3722
|
+
const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector);
|
|
3723
|
+
const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materialisedClone] });
|
|
3724
|
+
delete newNode.href;
|
|
3725
|
+
return applyUseOffsetToG(newNode);
|
|
3726
|
+
}
|
|
3727
|
+
function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector) {
|
|
3728
|
+
const viewBox = parseViewBox(symbolNode.viewBox);
|
|
3729
|
+
const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
|
|
3730
|
+
delete g.viewBox;
|
|
3731
|
+
delete g.preserveAspectRatio;
|
|
3732
|
+
delete g.width;
|
|
3733
|
+
delete g.height;
|
|
3734
|
+
if (!viewBox) return g;
|
|
3735
|
+
const [vbX, vbY, vbW, vbH] = viewBox;
|
|
3736
|
+
if (vbX !== 0 || vbY !== 0) {
|
|
3737
|
+
g.transform = "translate(" + -vbX + "," + -vbY + ")";
|
|
3738
|
+
}
|
|
3739
|
+
const clipId = genId3();
|
|
3740
|
+
defsCollector.push({
|
|
3741
|
+
type: "clipPath",
|
|
3742
|
+
id: clipId,
|
|
3743
|
+
children: [{ type: "rect", x: vbX, y: vbY, width: vbW, height: vbH }]
|
|
2371
3744
|
});
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
if (loop && normalized.length >= 2) {
|
|
2375
|
-
return expandLoopKeyframes(propName, normalized, loop, duration);
|
|
2376
|
-
}
|
|
2377
|
-
return normalized;
|
|
3745
|
+
g.clipPath = "url(#" + clipId + ")";
|
|
3746
|
+
return g;
|
|
2378
3747
|
}
|
|
2379
|
-
function
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
3748
|
+
function parseViewBox(v) {
|
|
3749
|
+
if (typeof v !== "string") return void 0;
|
|
3750
|
+
const parts = v.trim().split(/[\s,]+/).map(Number);
|
|
3751
|
+
if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
|
|
3752
|
+
return [parts[0], parts[1], parts[2], parts[3]];
|
|
3753
|
+
}
|
|
3754
|
+
function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector) {
|
|
3755
|
+
if (node.type === "use" && typeof node.href === "string") {
|
|
3756
|
+
const targetId = stripHash2(node.href);
|
|
3757
|
+
if (targetId && animatedIds.has(targetId)) {
|
|
3758
|
+
const target = idMap.get(targetId);
|
|
3759
|
+
if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector);
|
|
2384
3760
|
}
|
|
2385
3761
|
}
|
|
2386
|
-
return
|
|
3762
|
+
if (!node.children) return node;
|
|
3763
|
+
let changed = false;
|
|
3764
|
+
const newChildren = node.children.map((ch) => {
|
|
3765
|
+
const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector);
|
|
3766
|
+
if (m !== ch) changed = true;
|
|
3767
|
+
return m;
|
|
3768
|
+
});
|
|
3769
|
+
return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
|
|
2387
3770
|
}
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
3771
|
+
|
|
3772
|
+
// src/PxAnimatorMaterialiseAll.ts
|
|
3773
|
+
function materialiseAllInTree(doc, engine, opts) {
|
|
3774
|
+
var _a, _b;
|
|
3775
|
+
let root = applyPlayerEffects(doc).root;
|
|
3776
|
+
const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
|
|
3777
|
+
root = materialiseInternalLoopsInTree(root, duration);
|
|
3778
|
+
if (engine === PxAnimatorEngine.webapi) {
|
|
3779
|
+
root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
|
|
3780
|
+
root = materialiseAnimatedUseInstances(root);
|
|
3781
|
+
}
|
|
3782
|
+
return root;
|
|
2391
3783
|
}
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
3784
|
+
|
|
3785
|
+
// src/PxAnimatorDOM.ts
|
|
3786
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
3787
|
+
var DISALLOWED_SVG_TAGS_LOWER = /* @__PURE__ */ new Set([
|
|
3788
|
+
"script",
|
|
3789
|
+
"foreignobject"
|
|
3790
|
+
]);
|
|
3791
|
+
var URL_VALUE_ATTRS_LOWER = /* @__PURE__ */ new Set([
|
|
3792
|
+
"href",
|
|
3793
|
+
// <use>, <image>
|
|
3794
|
+
"xlink:href",
|
|
3795
|
+
// legacy <use>
|
|
3796
|
+
"src",
|
|
3797
|
+
// <image>
|
|
3798
|
+
"filter",
|
|
3799
|
+
// url(#filterId)
|
|
3800
|
+
"clippath",
|
|
3801
|
+
// clip-path="url(#…)"
|
|
3802
|
+
"mask",
|
|
3803
|
+
// url(#maskId)
|
|
3804
|
+
"markerstart",
|
|
3805
|
+
// marker-start="url(#…)"
|
|
3806
|
+
"markermid",
|
|
3807
|
+
// marker-mid="url(#…)"
|
|
3808
|
+
"markerend"
|
|
3809
|
+
// marker-end="url(#…)"
|
|
3810
|
+
]);
|
|
3811
|
+
var IMAGE_REF_ATTRS_LOWER = /* @__PURE__ */ new Set(["href", "xlink:href", "src"]);
|
|
3812
|
+
var DATA_RASTER_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,/i;
|
|
3813
|
+
function isDangerousAttrName(nameLower) {
|
|
3814
|
+
if (nameLower.startsWith("on")) return true;
|
|
3815
|
+
return false;
|
|
3816
|
+
}
|
|
3817
|
+
function sanitiseAttributeValue(name, value) {
|
|
3818
|
+
const nameLower = name.toLowerCase();
|
|
3819
|
+
if (isDangerousAttrName(nameLower)) {
|
|
3820
|
+
console.warn("Attribute blocked (event handler / dangerous): ", nameLower);
|
|
3821
|
+
return void 0;
|
|
3822
|
+
}
|
|
3823
|
+
if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
|
|
3824
|
+
const str = String(value);
|
|
3825
|
+
if (str.includes("url(") && !/^url\(#[^)]+\)$/.test(str)) {
|
|
3826
|
+
console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
|
|
3827
|
+
return void 0;
|
|
2398
3828
|
}
|
|
3829
|
+
return value;
|
|
2399
3830
|
}
|
|
2400
|
-
|
|
3831
|
+
if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
|
|
3832
|
+
const str = String(value);
|
|
3833
|
+
if (str.startsWith("#")) return value;
|
|
3834
|
+
if (/^url\(#[^)]+\)$/.test(str)) return value;
|
|
3835
|
+
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && DATA_RASTER_IMAGE_RE.test(str)) return value;
|
|
3836
|
+
console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or base64 raster data: URI, got:', value);
|
|
3837
|
+
return void 0;
|
|
3838
|
+
}
|
|
3839
|
+
return value;
|
|
2401
3840
|
}
|
|
2402
|
-
function
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
const bindings = [];
|
|
2407
|
-
const processAnimation = (id, animate) => {
|
|
2408
|
-
if (!animate) return null;
|
|
2409
|
-
const animDefs = resolveElementAnimation(animate, defs);
|
|
2410
|
-
if (animDefs.length === 0) return null;
|
|
2411
|
-
const merged = mergeAnimationDefinitions(animDefs);
|
|
2412
|
-
const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs);
|
|
2413
|
-
if (Object.keys(normalizedAnim).length === 0) return null;
|
|
2414
|
-
return {
|
|
2415
|
-
id,
|
|
2416
|
-
animate: normalizedAnim
|
|
2417
|
-
};
|
|
2418
|
-
};
|
|
2419
|
-
const docBindings = getBindings(doc);
|
|
2420
|
-
if (docBindings) {
|
|
2421
|
-
for (const binding of docBindings) {
|
|
2422
|
-
const normalized = processAnimation(binding.id, binding.animate);
|
|
2423
|
-
if (normalized) bindings.push(normalized);
|
|
2424
|
-
}
|
|
3841
|
+
function createElement(tagName, normalisedProps, style, children, textContent) {
|
|
3842
|
+
if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
|
|
3843
|
+
console.warn("SVG tag blocked (dangerous): ", tagName);
|
|
3844
|
+
return null;
|
|
2425
3845
|
}
|
|
2426
|
-
const
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
for (let i = 0; i < node.children.length; i++) {
|
|
2436
|
-
processNode(node.children[i]);
|
|
2437
|
-
}
|
|
2438
|
-
}
|
|
2439
|
-
};
|
|
2440
|
-
if (doc.children) {
|
|
2441
|
-
for (let i = 0; i < doc.children.length; i++) {
|
|
2442
|
-
processNode(doc.children[i]);
|
|
3846
|
+
const element = document.createElementNS(SVG_NS, tagName);
|
|
3847
|
+
for (const propName in normalisedProps) {
|
|
3848
|
+
const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
|
|
3849
|
+
if (sanitised === void 0) continue;
|
|
3850
|
+
element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
|
|
3851
|
+
}
|
|
3852
|
+
if (style) {
|
|
3853
|
+
for (const styleProp in style) {
|
|
3854
|
+
element.style[styleProp] = String(style[styleProp]);
|
|
2443
3855
|
}
|
|
2444
3856
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
var _a, _b;
|
|
2449
|
-
let prevKf = keyframes[0];
|
|
2450
|
-
let nextKf = keyframes[keyframes.length - 1];
|
|
2451
|
-
for (let j = 0; j < keyframes.length - 1; j++) {
|
|
2452
|
-
const aOff = (_a = keyframes[j].t) != null ? _a : 0;
|
|
2453
|
-
const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
|
|
2454
|
-
if (aOff <= progress && progress <= bOff) {
|
|
2455
|
-
prevKf = keyframes[j];
|
|
2456
|
-
nextKf = keyframes[j + 1];
|
|
2457
|
-
break;
|
|
3857
|
+
if (children) {
|
|
3858
|
+
for (const child of children) {
|
|
3859
|
+
element.appendChild(child);
|
|
2458
3860
|
}
|
|
2459
3861
|
}
|
|
2460
|
-
|
|
3862
|
+
if (textContent) element.textContent = textContent;
|
|
3863
|
+
return element;
|
|
2461
3864
|
}
|
|
2462
|
-
function
|
|
2463
|
-
var _a
|
|
2464
|
-
|
|
2465
|
-
if (
|
|
2466
|
-
|
|
2467
|
-
let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
|
|
2468
|
-
localProgress = clamp(localProgress, 0, 1);
|
|
2469
|
-
const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
|
|
2470
|
-
if (easing && Array.isArray(easing)) {
|
|
2471
|
-
try {
|
|
2472
|
-
localProgress = cubicBezier(easing)(localProgress);
|
|
2473
|
-
} catch (e) {
|
|
2474
|
-
}
|
|
3865
|
+
function resolveStyle(style, defs) {
|
|
3866
|
+
var _a;
|
|
3867
|
+
if (!style) return void 0;
|
|
3868
|
+
if (typeof style === "string") {
|
|
3869
|
+
return (_a = defs == null ? void 0 : defs.styles) == null ? void 0 : _a[style];
|
|
2475
3870
|
}
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
const
|
|
2480
|
-
|
|
2481
|
-
const
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
));
|
|
2494
|
-
cssAttrName = propName;
|
|
2495
|
-
} else if (cssAttrName === "stroke-dasharray") {
|
|
2496
|
-
cssValue = interpolateVec(
|
|
2497
|
-
prevV || [],
|
|
2498
|
-
nextV || [],
|
|
2499
|
-
localProgress
|
|
2500
|
-
).join(" ");
|
|
2501
|
-
cssAttrName = propName;
|
|
2502
|
-
} else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
|
|
2503
|
-
const partKeys = /* @__PURE__ */ new Set([
|
|
2504
|
-
...prevV ? Object.keys(prevV) : [],
|
|
2505
|
-
...nextV ? Object.keys(nextV) : []
|
|
2506
|
-
]);
|
|
2507
|
-
const partsResult = {};
|
|
2508
|
-
for (const partKey of partKeys) {
|
|
2509
|
-
const prevPart = prevV == null ? void 0 : prevV[partKey];
|
|
2510
|
-
const nextPart = nextV == null ? void 0 : nextV[partKey];
|
|
2511
|
-
if (partKey === "rotate") {
|
|
2512
|
-
partsResult.rotate = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
|
|
2513
|
-
} else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
|
|
2514
|
-
const fallback = partKey === "scale" ? [1, 1] : [0, 0];
|
|
2515
|
-
const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
|
|
2516
|
-
partsResult[partKey] = interp;
|
|
3871
|
+
return style;
|
|
3872
|
+
}
|
|
3873
|
+
function getNormalizedProps(props) {
|
|
3874
|
+
const propsCopy = {};
|
|
3875
|
+
for (const rawKey of Object.keys(props)) {
|
|
3876
|
+
const key = kebabToCamelCaseWord(rawKey);
|
|
3877
|
+
if (INTERNAL_ATTRS.has(key)) continue;
|
|
3878
|
+
if (key === "style") continue;
|
|
3879
|
+
let value = props[rawKey];
|
|
3880
|
+
if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
|
|
3881
|
+
propsCopy[key] = toRGBA(value);
|
|
3882
|
+
} else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
|
|
3883
|
+
propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
|
|
3884
|
+
} else if (TRANSFORM_FN_NAMES.has(key)) {
|
|
3885
|
+
if (Array.isArray(value)) {
|
|
3886
|
+
if (key === "translate") value = value.map((v) => v + "px");
|
|
3887
|
+
value = value.join(",");
|
|
2517
3888
|
}
|
|
3889
|
+
if (key === "rotate") value = value + "deg";
|
|
3890
|
+
propsCopy["transform"] = key + "(" + value + ")";
|
|
3891
|
+
} else if (value !== void 0 && value !== null) {
|
|
3892
|
+
propsCopy[key] = String(value);
|
|
2518
3893
|
}
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
if (
|
|
3894
|
+
}
|
|
3895
|
+
return propsCopy;
|
|
3896
|
+
}
|
|
3897
|
+
function renderNode(node, defs) {
|
|
3898
|
+
if (!node) return null;
|
|
3899
|
+
const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
|
|
3900
|
+
const nodeDefs = getDefs(node) || defs;
|
|
3901
|
+
const resolvedStyle = resolveStyle(style, nodeDefs);
|
|
3902
|
+
let childElements;
|
|
3903
|
+
if (children) {
|
|
3904
|
+
for (const ch of children) {
|
|
3905
|
+
const child = renderNode(ch, nodeDefs);
|
|
3906
|
+
if (child) {
|
|
3907
|
+
if (!childElements) childElements = [];
|
|
3908
|
+
childElements.push(child);
|
|
2533
3909
|
}
|
|
2534
3910
|
}
|
|
2535
|
-
cssValue = composeTransformParts(partsResult, { withUnits: false });
|
|
2536
|
-
cssAttrName = "transform";
|
|
2537
|
-
} else if (cssAttrName === "translate") {
|
|
2538
|
-
const v = interpolateVec(
|
|
2539
|
-
prevV || [0, 0],
|
|
2540
|
-
nextV || [0, 0],
|
|
2541
|
-
localProgress
|
|
2542
|
-
);
|
|
2543
|
-
cssValue = "translate(" + v.join(",") + ")";
|
|
2544
|
-
cssAttrName = "transform";
|
|
2545
|
-
} else if (cssAttrName === "rotate") {
|
|
2546
|
-
const v = interpolateNum(
|
|
2547
|
-
+(prevV || 0),
|
|
2548
|
-
+(nextV || 0),
|
|
2549
|
-
localProgress
|
|
2550
|
-
);
|
|
2551
|
-
cssValue = "rotate(" + v + ")";
|
|
2552
|
-
cssAttrName = "transform";
|
|
2553
|
-
} else if (cssAttrName === "scale") {
|
|
2554
|
-
const v = interpolateVec(
|
|
2555
|
-
prevV || [1, 1],
|
|
2556
|
-
nextV || [1, 1],
|
|
2557
|
-
localProgress
|
|
2558
|
-
);
|
|
2559
|
-
cssValue = "scale(" + v.join(",") + ")";
|
|
2560
|
-
cssAttrName = "transform";
|
|
2561
|
-
} else {
|
|
2562
|
-
const num2 = interpolateNum(
|
|
2563
|
-
+(prevV || 0),
|
|
2564
|
-
+(nextV || 0),
|
|
2565
|
-
localProgress
|
|
2566
|
-
);
|
|
2567
|
-
cssValue = num2;
|
|
2568
|
-
}
|
|
2569
|
-
if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
|
|
2570
|
-
cssValue = cssValue * 100 + "%";
|
|
2571
3911
|
}
|
|
2572
|
-
return
|
|
3912
|
+
return createElement(
|
|
3913
|
+
type || "g",
|
|
3914
|
+
getNormalizedProps(props),
|
|
3915
|
+
resolvedStyle,
|
|
3916
|
+
childElements,
|
|
3917
|
+
props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
|
|
3918
|
+
);
|
|
2573
3919
|
}
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
3920
|
+
|
|
3921
|
+
// src/PxAnimatorTriggers.ts
|
|
3922
|
+
function setupAnimationTriggers(api, config) {
|
|
3923
|
+
const { startOn, outAction = "continue", scrollIntoViewThreshold = 0.5 } = config;
|
|
3924
|
+
const root = api.getRootElement();
|
|
3925
|
+
if (!root) {
|
|
3926
|
+
console.warn("setupAnimationTriggers: No root element found for animation.");
|
|
3927
|
+
return api;
|
|
3928
|
+
}
|
|
3929
|
+
const start = () => {
|
|
3930
|
+
api.play();
|
|
3931
|
+
};
|
|
3932
|
+
const handleEndAction = () => {
|
|
3933
|
+
switch (outAction) {
|
|
3934
|
+
case "pause":
|
|
3935
|
+
api.pause();
|
|
3936
|
+
break;
|
|
3937
|
+
case "reset":
|
|
3938
|
+
api.cancel();
|
|
3939
|
+
break;
|
|
3940
|
+
case "reverse":
|
|
3941
|
+
api.play();
|
|
3942
|
+
break;
|
|
3943
|
+
case "continue":
|
|
3944
|
+
default:
|
|
3945
|
+
break;
|
|
3946
|
+
}
|
|
3947
|
+
};
|
|
3948
|
+
switch (startOn) {
|
|
3949
|
+
case "load": {
|
|
3950
|
+
const startHandler = () => start();
|
|
3951
|
+
if (document.readyState === "complete") {
|
|
3952
|
+
startHandler();
|
|
3953
|
+
} else {
|
|
3954
|
+
window.addEventListener("load", startHandler, { once: true });
|
|
3955
|
+
}
|
|
3956
|
+
break;
|
|
3957
|
+
}
|
|
3958
|
+
case "mouseOver": {
|
|
3959
|
+
const mouseOverHandler = () => start();
|
|
3960
|
+
const mouseOutHandler = () => handleEndAction();
|
|
3961
|
+
root.addEventListener("mouseenter", mouseOverHandler);
|
|
3962
|
+
root.addEventListener("mouseleave", mouseOutHandler);
|
|
3963
|
+
break;
|
|
2580
3964
|
}
|
|
3965
|
+
case "click": {
|
|
3966
|
+
const clickHandler = () => {
|
|
3967
|
+
if (api.isPlaying()) {
|
|
3968
|
+
handleEndAction();
|
|
3969
|
+
} else {
|
|
3970
|
+
start();
|
|
3971
|
+
}
|
|
3972
|
+
};
|
|
3973
|
+
root.addEventListener("click", clickHandler);
|
|
3974
|
+
break;
|
|
3975
|
+
}
|
|
3976
|
+
case "scrollIntoView": {
|
|
3977
|
+
const observer = new IntersectionObserver(
|
|
3978
|
+
(entries) => {
|
|
3979
|
+
entries.forEach((entry) => {
|
|
3980
|
+
if (entry.isIntersecting && entry.intersectionRatio >= scrollIntoViewThreshold) {
|
|
3981
|
+
start();
|
|
3982
|
+
} else {
|
|
3983
|
+
handleEndAction();
|
|
3984
|
+
}
|
|
3985
|
+
});
|
|
3986
|
+
},
|
|
3987
|
+
{ threshold: scrollIntoViewThreshold }
|
|
3988
|
+
);
|
|
3989
|
+
observer.observe(root);
|
|
3990
|
+
break;
|
|
3991
|
+
}
|
|
3992
|
+
case "programmatic":
|
|
3993
|
+
break;
|
|
2581
3994
|
}
|
|
2582
|
-
return
|
|
3995
|
+
return api;
|
|
2583
3996
|
}
|
|
2584
3997
|
|
|
2585
3998
|
// src/PxAnimatorFrameLoop.ts
|
|
@@ -2588,7 +4001,7 @@ function getSelector(id) {
|
|
|
2588
4001
|
}
|
|
2589
4002
|
function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
2590
4003
|
const config = getAnimatorConfig(doc) || {};
|
|
2591
|
-
const bindings = getNormalisedBindings(doc);
|
|
4004
|
+
const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
|
|
2592
4005
|
const _iterations = config.iterations;
|
|
2593
4006
|
let iterations = 1;
|
|
2594
4007
|
if (typeof _iterations === "number") iterations = _iterations || 1;
|
|
@@ -2706,6 +4119,10 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
2706
4119
|
};
|
|
2707
4120
|
const startAnim = () => {
|
|
2708
4121
|
if (playing) return;
|
|
4122
|
+
if (Number.isFinite(totalDuration) && timeBeforeLastStartMs >= totalDuration) {
|
|
4123
|
+
timeBeforeLastStartMs = 0;
|
|
4124
|
+
finishCalled = false;
|
|
4125
|
+
}
|
|
2709
4126
|
playing = true;
|
|
2710
4127
|
lastStartedTs = Date.now();
|
|
2711
4128
|
loopAnim(true);
|
|
@@ -2938,7 +4355,6 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
|
|
|
2938
4355
|
function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs) {
|
|
2939
4356
|
var _a;
|
|
2940
4357
|
const config = getAnimatorConfig(doc) || {};
|
|
2941
|
-
const bindings = getNormalisedBindings(doc);
|
|
2942
4358
|
if (!rootElement) {
|
|
2943
4359
|
if (doc.id) {
|
|
2944
4360
|
const rootSelector = getSelector(doc.id);
|
|
@@ -2948,6 +4364,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
2948
4364
|
console.warn("createFrameLoopAnimator: No root element provided");
|
|
2949
4365
|
}
|
|
2950
4366
|
}
|
|
4367
|
+
const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);
|
|
2951
4368
|
const animations = [];
|
|
2952
4369
|
const _iterations = config.iterations;
|
|
2953
4370
|
let iterations;
|
|
@@ -3079,15 +4496,15 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
3079
4496
|
function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
|
|
3080
4497
|
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
3081
4498
|
let res;
|
|
3082
|
-
if (animatorConfig.mode ===
|
|
4499
|
+
if (animatorConfig.mode === PxAnimatorMode.frames) {
|
|
3083
4500
|
res = createFrameLoopAnimator(doc, adapter, callbacks, rootElement);
|
|
3084
4501
|
} else {
|
|
3085
4502
|
res = createWebApiAnimator(
|
|
3086
4503
|
doc,
|
|
3087
4504
|
callbacks,
|
|
3088
4505
|
rootElement,
|
|
3089
|
-
animatorConfig.mode ===
|
|
3090
|
-
//
|
|
4506
|
+
animatorConfig.mode === PxAnimatorMode.webapi
|
|
4507
|
+
// forcing webapi
|
|
3091
4508
|
) || createFrameLoopAnimator(doc, adapter, callbacks, rootElement);
|
|
3092
4509
|
}
|
|
3093
4510
|
if (animatorConfig.debugInstName) {
|
|
@@ -3209,9 +4626,10 @@ function replaceUrlRefs(value, idMap) {
|
|
|
3209
4626
|
function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
|
|
3210
4627
|
const effectsWarnings = validateNodeEffects(doc);
|
|
3211
4628
|
for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
|
|
3212
|
-
doc = applyPlayerEffects(doc).root;
|
|
3213
4629
|
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
3214
4630
|
animatorConfig.debug = true;
|
|
4631
|
+
const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi;
|
|
4632
|
+
doc = materialiseAllInTree(doc, engine);
|
|
3215
4633
|
let rootElement = null;
|
|
3216
4634
|
if (containerElement && doc.children) {
|
|
3217
4635
|
doc = generateNewIds(doc);
|
|
@@ -3388,10 +4806,10 @@ function evalScalar(animated, staticVal, fallback, t) {
|
|
|
3388
4806
|
}
|
|
3389
4807
|
var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
|
|
3390
4808
|
var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
|
|
3391
|
-
function
|
|
4809
|
+
function buildIdMap2(node, map) {
|
|
3392
4810
|
var _a;
|
|
3393
4811
|
if (typeof node.id === "string") map.set(node.id, node);
|
|
3394
|
-
(_a = node.children) == null ? void 0 : _a.forEach((c) =>
|
|
4812
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => buildIdMap2(c, map));
|
|
3395
4813
|
}
|
|
3396
4814
|
function num(v) {
|
|
3397
4815
|
return v === void 0 || v === null ? 0 : Number(v);
|
|
@@ -3468,7 +4886,7 @@ function collectSampleTimes(node, into) {
|
|
|
3468
4886
|
}
|
|
3469
4887
|
function visualModelAt(root, t) {
|
|
3470
4888
|
const idMap = /* @__PURE__ */ new Map();
|
|
3471
|
-
|
|
4889
|
+
buildIdMap2(root, idMap);
|
|
3472
4890
|
const out = [];
|
|
3473
4891
|
flatten(root, IDENTITY, t, idMap, out);
|
|
3474
4892
|
return out.sort();
|
|
@@ -3507,6 +4925,8 @@ export {
|
|
|
3507
4925
|
PxAnimatedSvgDocumentSchema,
|
|
3508
4926
|
PxAnimationDefinitionSchema,
|
|
3509
4927
|
PxAnimatorConfigSchema,
|
|
4928
|
+
PxAnimatorEngine,
|
|
4929
|
+
PxAnimatorMode,
|
|
3510
4930
|
PxAttrValueSchema,
|
|
3511
4931
|
PxBezierPathSchema,
|
|
3512
4932
|
PxBindingSchema,
|
|
@@ -3514,6 +4934,11 @@ export {
|
|
|
3514
4934
|
PxEasingOrRefSchema,
|
|
3515
4935
|
PxEffectsSchema,
|
|
3516
4936
|
PxElementAnimationSchema,
|
|
4937
|
+
PxFillGradientEffectSchema,
|
|
4938
|
+
PxGradientSpreadMethod,
|
|
4939
|
+
PxGradientStopSchema,
|
|
4940
|
+
PxGradientType,
|
|
4941
|
+
PxGradientUnits,
|
|
3517
4942
|
PxKeyframeSchema,
|
|
3518
4943
|
PxLoopSchema,
|
|
3519
4944
|
PxMaskedByEffectSchema,
|
|
@@ -3523,7 +4948,9 @@ export {
|
|
|
3523
4948
|
PxRefEffectSchema,
|
|
3524
4949
|
PxRepeaterEffectSchema,
|
|
3525
4950
|
PxRetimeEffectSchema,
|
|
4951
|
+
PxStrokeGradientEffectSchema,
|
|
3526
4952
|
PxSvgNodeExtra,
|
|
4953
|
+
PxTextAlongPathEffectSchema,
|
|
3527
4954
|
PxTransformPartsSchema,
|
|
3528
4955
|
PxTransformValueSchema,
|
|
3529
4956
|
PxTransformationEffectSchema,
|
|
@@ -3542,6 +4969,7 @@ export {
|
|
|
3542
4969
|
createWebApiAnimator,
|
|
3543
4970
|
describeSchema,
|
|
3544
4971
|
diffInEffect,
|
|
4972
|
+
evaluateMotionPathSegment,
|
|
3545
4973
|
generateNewIds,
|
|
3546
4974
|
getAnimatorConfig,
|
|
3547
4975
|
getBindings,
|
|
@@ -3551,7 +4979,14 @@ export {
|
|
|
3551
4979
|
isPxElementFileFormat,
|
|
3552
4980
|
isPxElementFileFormatDeep,
|
|
3553
4981
|
loadTagAnimators,
|
|
4982
|
+
materialiseAllInTree,
|
|
4983
|
+
materialiseAnimatedUseInstances,
|
|
4984
|
+
materialiseInternalLoopsInPropAnim,
|
|
4985
|
+
materialiseInternalLoopsInTree,
|
|
4986
|
+
materialiseMotionPathInPropAnim,
|
|
4987
|
+
materialiseMotionPathsInTree,
|
|
3554
4988
|
getNormalisedBindings as normalizeDocument,
|
|
4989
|
+
propAnimIsMotionPath,
|
|
3555
4990
|
px,
|
|
3556
4991
|
renderNode,
|
|
3557
4992
|
schemaKeys,
|