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