@pixodesk/svg-animator-web 1.0.16 → 1.0.18
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/README.md +27 -0
- package/dist/index.cjs +831 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +275 -64
- package/dist/index.d.ts +275 -64
- package/dist/index.js +825 -91
- 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 +825 -91
- 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,6 +7,7 @@ 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;
|
|
10
11
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
12
|
var __spreadValues = (a, b) => {
|
|
12
13
|
for (var prop in b || (b = {}))
|
|
@@ -62,6 +63,7 @@ __export(index_exports, {
|
|
|
62
63
|
PxAttrValueSchema: () => PxAttrValueSchema,
|
|
63
64
|
PxBezierPathSchema: () => PxBezierPathSchema,
|
|
64
65
|
PxBindingSchema: () => PxBindingSchema,
|
|
66
|
+
PxCloneEffectSchema: () => PxCloneEffectSchema,
|
|
65
67
|
PxDefsSchema: () => PxDefsSchema,
|
|
66
68
|
PxEasingOrRefSchema: () => PxEasingOrRefSchema,
|
|
67
69
|
PxEffectsSchema: () => PxEffectsSchema,
|
|
@@ -77,12 +79,12 @@ __export(index_exports, {
|
|
|
77
79
|
PxNodeBase: () => PxNodeBase,
|
|
78
80
|
PxNodeSchema: () => PxNodeSchema,
|
|
79
81
|
PxPropertyAnimationSchema: () => PxPropertyAnimationSchema,
|
|
80
|
-
PxRefEffectSchema: () => PxRefEffectSchema,
|
|
81
82
|
PxRepeaterEffectSchema: () => PxRepeaterEffectSchema,
|
|
82
83
|
PxRetimeEffectSchema: () => PxRetimeEffectSchema,
|
|
83
84
|
PxStrokeGradientEffectSchema: () => PxStrokeGradientEffectSchema,
|
|
84
85
|
PxSvgNodeExtra: () => PxSvgNodeExtra,
|
|
85
86
|
PxTextAlongPathEffectSchema: () => PxTextAlongPathEffectSchema,
|
|
87
|
+
PxTextEffectSchema: () => PxTextEffectSchema,
|
|
86
88
|
PxTransformPartsSchema: () => PxTransformPartsSchema,
|
|
87
89
|
PxTransformValueSchema: () => PxTransformValueSchema,
|
|
88
90
|
PxTransformationEffectSchema: () => PxTransformationEffectSchema,
|
|
@@ -110,9 +112,13 @@ __export(index_exports, {
|
|
|
110
112
|
getNormalizedProps: () => getNormalizedProps,
|
|
111
113
|
isPxElementFileFormat: () => isPxElementFileFormat,
|
|
112
114
|
isPxElementFileFormatDeep: () => isPxElementFileFormatDeep,
|
|
115
|
+
jsonElementFactory: () => jsonElementFactory,
|
|
113
116
|
loadTagAnimators: () => loadTagAnimators,
|
|
114
117
|
materialiseAllInTree: () => materialiseAllInTree,
|
|
115
118
|
materialiseAnimatedUseInstances: () => materialiseAnimatedUseInstances,
|
|
119
|
+
materialiseGlyphText: () => materialiseGlyphText,
|
|
120
|
+
materialiseGlyphTextAlongPath: () => materialiseGlyphTextAlongPath,
|
|
121
|
+
materialiseGlyphTextHorizontal: () => materialiseGlyphTextHorizontal,
|
|
116
122
|
materialiseInternalLoopsInPropAnim: () => materialiseInternalLoopsInPropAnim,
|
|
117
123
|
materialiseInternalLoopsInTree: () => materialiseInternalLoopsInTree,
|
|
118
124
|
materialiseMotionPathInPropAnim: () => materialiseMotionPathInPropAnim,
|
|
@@ -144,7 +150,7 @@ function readAnimatable(raw) {
|
|
|
144
150
|
if (typeof raw === "object") {
|
|
145
151
|
const obj = raw;
|
|
146
152
|
if (obj.keyframes) {
|
|
147
|
-
return { kind: "animated" /* Animated */, keyframes: obj.keyframes, autoOrient: obj.autoOrient };
|
|
153
|
+
return { kind: "animated" /* Animated */, keyframes: obj.keyframes, autoOrient: obj.autoOrient, loop: obj.loop };
|
|
148
154
|
}
|
|
149
155
|
if (obj.value !== void 0) return { kind: "static" /* Static */, value: obj.value };
|
|
150
156
|
}
|
|
@@ -234,6 +240,7 @@ function wrapTransformPart(inner, part, raw, ctx) {
|
|
|
234
240
|
if (v.kind === "animated" /* Animated */) {
|
|
235
241
|
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
|
|
236
242
|
if (v.autoOrient) animTr.autoOrient = true;
|
|
243
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
237
244
|
return {
|
|
238
245
|
type: "g",
|
|
239
246
|
animate: { transform: animTr },
|
|
@@ -252,9 +259,11 @@ function wrapOrigin(inner, raw, invert) {
|
|
|
252
259
|
return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
|
|
253
260
|
}
|
|
254
261
|
if (v.kind === "animated" /* Animated */) {
|
|
262
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) };
|
|
263
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
255
264
|
return {
|
|
256
265
|
type: "g",
|
|
257
|
-
animate: { transform:
|
|
266
|
+
animate: { transform: animTr },
|
|
258
267
|
children: [inner]
|
|
259
268
|
};
|
|
260
269
|
}
|
|
@@ -264,8 +273,8 @@ function wrapOrigin(inner, raw, invert) {
|
|
|
264
273
|
// src/effects/contentRefSplit.ts
|
|
265
274
|
function identifyContentRefTargets(node, ctx, allocator) {
|
|
266
275
|
var _a, _b, _c;
|
|
267
|
-
if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.
|
|
268
|
-
const baseId = node.effects.
|
|
276
|
+
if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
|
|
277
|
+
const baseId = node.effects.clone.baseId;
|
|
269
278
|
if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
|
|
270
279
|
ctx.contentRefInnerIds.set(baseId, allocator(baseId));
|
|
271
280
|
}
|
|
@@ -313,6 +322,8 @@ function liftBodyTranslate(node, transformation) {
|
|
|
313
322
|
});
|
|
314
323
|
const outerAnimTr = { keyframes: outerKfs };
|
|
315
324
|
if (animTr.autoOrient) outerAnimTr.autoOrient = true;
|
|
325
|
+
const srcLoop = animTr.loop;
|
|
326
|
+
if (srcLoop !== void 0) outerAnimTr.loop = srcLoop;
|
|
316
327
|
out.animate = { transform: outerAnimTr };
|
|
317
328
|
const innerHasPivotedPart = kfs.some((kf) => {
|
|
318
329
|
const v = kf.value || {};
|
|
@@ -334,7 +345,9 @@ function liftBodyTranslate(node, transformation) {
|
|
|
334
345
|
delete node.animate.transform;
|
|
335
346
|
if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;
|
|
336
347
|
} else {
|
|
337
|
-
|
|
348
|
+
const innerAnimTr = { keyframes: innerKfs };
|
|
349
|
+
if (srcLoop !== void 0) innerAnimTr.loop = srcLoop;
|
|
350
|
+
node.animate.transform = innerAnimTr;
|
|
338
351
|
}
|
|
339
352
|
didLiftAnimate = true;
|
|
340
353
|
}
|
|
@@ -998,10 +1011,22 @@ var PxTriggerSchema = implementsInterface()(px.object({
|
|
|
998
1011
|
outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
|
|
999
1012
|
scrollIntoViewThreshold: px.number().optional()
|
|
1000
1013
|
}));
|
|
1014
|
+
var PxGlyphSchema = implementsInterface()(px.object({
|
|
1015
|
+
width: px.number(),
|
|
1016
|
+
d: px.string()
|
|
1017
|
+
}));
|
|
1018
|
+
var PxGlyphFontSchema = implementsInterface()(px.object({
|
|
1019
|
+
fFamily: px.string(),
|
|
1020
|
+
style: px.string(),
|
|
1021
|
+
ascent: px.number(),
|
|
1022
|
+
unitsPerEm: px.number(),
|
|
1023
|
+
glyphs: px.record(PxGlyphSchema)
|
|
1024
|
+
}));
|
|
1001
1025
|
var PxDefsSchema = implementsInterface()(px.object({
|
|
1002
1026
|
easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
|
|
1003
1027
|
animations: px.record(PxAnimationDefinitionSchema).optional(),
|
|
1004
|
-
styles: px.record(px.any()).optional()
|
|
1028
|
+
styles: px.record(px.any()).optional(),
|
|
1029
|
+
glyphs: px.record(PxGlyphFontSchema).optional()
|
|
1005
1030
|
}));
|
|
1006
1031
|
var PxAnimatorConfigSchema = implementsInterface()(px.object({
|
|
1007
1032
|
mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
|
|
@@ -1074,9 +1099,10 @@ var PxRetimeEffectSchema = implementsInterface()(px.object({
|
|
|
1074
1099
|
stretch: px.number().optional(),
|
|
1075
1100
|
timeCrop: px.tuple([px.number(), px.number()]).optional()
|
|
1076
1101
|
}));
|
|
1077
|
-
var
|
|
1102
|
+
var PxCloneEffectSchema = implementsInterface()(px.object({
|
|
1103
|
+
type: px.string().optional(),
|
|
1078
1104
|
baseId: px.string().optional(),
|
|
1079
|
-
|
|
1105
|
+
retime: PxRetimeEffectSchema.optional()
|
|
1080
1106
|
}));
|
|
1081
1107
|
var PxGradientUnits = {
|
|
1082
1108
|
userSpaceOnUse: "userSpaceOnUse",
|
|
@@ -1121,17 +1147,20 @@ var PxTextAlongPathEffectSchema = implementsInterface()(px.object({
|
|
|
1121
1147
|
startOffset: PxAnimatableNumberSchema.optional(),
|
|
1122
1148
|
textLength: PxAnimatableNumberSchema.optional()
|
|
1123
1149
|
}));
|
|
1150
|
+
var PxTextEffectSchema = implementsInterface()(px.object({
|
|
1151
|
+
useGlyphs: px.boolean().optional()
|
|
1152
|
+
}));
|
|
1124
1153
|
var PxEffectsSchema = implementsInterface()(px.object({
|
|
1125
1154
|
transformation: PxTransformationEffectSchema.optional(),
|
|
1126
1155
|
repeater: PxRepeaterEffectSchema.optional(),
|
|
1127
1156
|
maskedBy: PxMaskedByEffectSchema.optional(),
|
|
1128
1157
|
trimPath: PxTrimPathEffectSchema.optional(),
|
|
1129
|
-
|
|
1158
|
+
clone: PxCloneEffectSchema.optional(),
|
|
1130
1159
|
isCombinedShape: px.boolean().optional(),
|
|
1131
|
-
ref: PxRefEffectSchema.optional(),
|
|
1132
1160
|
fillGradient: PxFillGradientEffectSchema.optional(),
|
|
1133
1161
|
strokeGradient: PxStrokeGradientEffectSchema.optional(),
|
|
1134
|
-
textAlongPath: PxTextAlongPathEffectSchema.optional()
|
|
1162
|
+
textAlongPath: PxTextAlongPathEffectSchema.optional(),
|
|
1163
|
+
text: PxTextEffectSchema.optional()
|
|
1135
1164
|
}));
|
|
1136
1165
|
function validateNodeEffects(root, opts) {
|
|
1137
1166
|
const warnings = [];
|
|
@@ -1356,6 +1385,7 @@ function buildStopChildren(stops, ctx) {
|
|
|
1356
1385
|
const animBlock = stops;
|
|
1357
1386
|
const kfs = animBlock.keyframes;
|
|
1358
1387
|
if (!Array.isArray(kfs) || !kfs.length) return [];
|
|
1388
|
+
const loopFromSource = animBlock.loop;
|
|
1359
1389
|
let stopCount = 0;
|
|
1360
1390
|
for (const kf of kfs) {
|
|
1361
1391
|
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
@@ -1368,7 +1398,7 @@ function buildStopChildren(stops, ctx) {
|
|
|
1368
1398
|
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
1399
|
baselineStops.push({ offset: s.offset, color: s.color });
|
|
1370
1400
|
}
|
|
1371
|
-
return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx));
|
|
1401
|
+
return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
|
|
1372
1402
|
}
|
|
1373
1403
|
function staticStopNode(s) {
|
|
1374
1404
|
return {
|
|
@@ -1377,7 +1407,7 @@ function staticStopNode(s) {
|
|
|
1377
1407
|
stopColor: s.color
|
|
1378
1408
|
};
|
|
1379
1409
|
}
|
|
1380
|
-
function animatedStopNode(baseline, kfs, stopIdx, _ctx) {
|
|
1410
|
+
function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
|
|
1381
1411
|
var _a, _b, _c, _d, _e;
|
|
1382
1412
|
const colorKfs = [];
|
|
1383
1413
|
const offsetKfs = [];
|
|
@@ -1402,8 +1432,14 @@ function animatedStopNode(baseline, kfs, stopIdx, _ctx) {
|
|
|
1402
1432
|
stopColor: baseline.color
|
|
1403
1433
|
};
|
|
1404
1434
|
const animate = {};
|
|
1405
|
-
if (colorKfs.length)
|
|
1406
|
-
|
|
1435
|
+
if (colorKfs.length) {
|
|
1436
|
+
animate.stopColor = { keyframes: colorKfs };
|
|
1437
|
+
if (loop !== void 0) animate.stopColor.loop = loop;
|
|
1438
|
+
}
|
|
1439
|
+
if (offsetVaries && offsetKfs.length) {
|
|
1440
|
+
animate.offset = { keyframes: offsetKfs };
|
|
1441
|
+
if (loop !== void 0) animate.offset.loop = loop;
|
|
1442
|
+
}
|
|
1407
1443
|
if (Object.keys(animate).length) stop.animate = animate;
|
|
1408
1444
|
return stop;
|
|
1409
1445
|
}
|
|
@@ -1468,9 +1504,11 @@ function wrapInversePart(inner, part, raw, origin, ctx) {
|
|
|
1468
1504
|
return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
|
|
1469
1505
|
}
|
|
1470
1506
|
if (v.kind === "animated" /* Animated */) {
|
|
1507
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) };
|
|
1508
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
1471
1509
|
return {
|
|
1472
1510
|
type: "g",
|
|
1473
|
-
animate: { transform:
|
|
1511
|
+
animate: { transform: animTr },
|
|
1474
1512
|
children: [inner]
|
|
1475
1513
|
};
|
|
1476
1514
|
}
|
|
@@ -1507,10 +1545,16 @@ function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
|
|
|
1507
1545
|
scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
1508
1546
|
}
|
|
1509
1547
|
}
|
|
1548
|
+
const srcLoop = animTr == null ? void 0 : animTr.loop;
|
|
1549
|
+
const withLoop = (kfs2) => {
|
|
1550
|
+
const block = { keyframes: kfs2 };
|
|
1551
|
+
if (srcLoop !== void 0) block.loop = srcLoop;
|
|
1552
|
+
return block;
|
|
1553
|
+
};
|
|
1510
1554
|
let n = inner;
|
|
1511
|
-
if (translateKfs.length) n = { type: "g", animate: { transform:
|
|
1512
|
-
if (rotateKfs.length) n = { type: "g", animate: { transform:
|
|
1513
|
-
if (scaleKfs.length) n = { type: "g", animate: { transform:
|
|
1555
|
+
if (translateKfs.length) n = { type: "g", animate: { transform: withLoop(translateKfs) }, children: [n] };
|
|
1556
|
+
if (rotateKfs.length) n = { type: "g", animate: { transform: withLoop(rotateKfs) }, children: [n] };
|
|
1557
|
+
if (scaleKfs.length) n = { type: "g", animate: { transform: withLoop(scaleKfs) }, children: [n] };
|
|
1514
1558
|
return n;
|
|
1515
1559
|
}
|
|
1516
1560
|
function nodeHasBodyTransform(node) {
|
|
@@ -1744,16 +1788,18 @@ function parseTranslateOnlyFromString(s, ctx) {
|
|
|
1744
1788
|
|
|
1745
1789
|
// src/effects/refEffect.ts
|
|
1746
1790
|
var CONTENT_SUBREF = "content";
|
|
1747
|
-
function
|
|
1748
|
-
if (
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
const targetId = ref.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
|
|
1754
|
-
node.href = "#" + targetId;
|
|
1755
|
-
}
|
|
1791
|
+
function applyRefHref(node, clone2, ctx) {
|
|
1792
|
+
if (!clone2) return;
|
|
1793
|
+
const baseId = clone2.baseId;
|
|
1794
|
+
if (!baseId) {
|
|
1795
|
+
if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing baseId");
|
|
1796
|
+
return;
|
|
1756
1797
|
}
|
|
1798
|
+
const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
|
|
1799
|
+
node.href = "#" + targetId;
|
|
1800
|
+
}
|
|
1801
|
+
function applyRefAndTransformationEffect(node, clone2, transformation, ctx) {
|
|
1802
|
+
applyRefHref(node, clone2, ctx);
|
|
1757
1803
|
return applyTransformationEffect(node, transformation, ctx);
|
|
1758
1804
|
}
|
|
1759
1805
|
|
|
@@ -1864,22 +1910,32 @@ function concatRetime(child, parent) {
|
|
|
1864
1910
|
stretch: parent.stretch * child.stretch
|
|
1865
1911
|
};
|
|
1866
1912
|
}
|
|
1867
|
-
function
|
|
1913
|
+
function readCloneRetime(n) {
|
|
1914
|
+
var _a, _b;
|
|
1915
|
+
return (_b = (_a = n.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.retime;
|
|
1916
|
+
}
|
|
1917
|
+
function clearCloneRetime(n) {
|
|
1868
1918
|
var _a;
|
|
1919
|
+
const clone2 = (_a = n.effects) == null ? void 0 : _a.clone;
|
|
1920
|
+
if (!clone2) return;
|
|
1921
|
+
delete clone2.retime;
|
|
1922
|
+
if (Object.keys(clone2).length === 0) delete n.effects.clone;
|
|
1923
|
+
if (n.effects && Object.keys(n.effects).length === 0) delete n.effects;
|
|
1924
|
+
}
|
|
1925
|
+
function applyAllRetimeEffects(root, ctx) {
|
|
1869
1926
|
ctx.idMap.clear();
|
|
1870
1927
|
indexById(root, ctx.idMap);
|
|
1871
1928
|
const sites = [];
|
|
1872
1929
|
const collect = (n) => {
|
|
1873
|
-
var
|
|
1874
|
-
if ((
|
|
1875
|
-
(
|
|
1930
|
+
var _a;
|
|
1931
|
+
if (readCloneRetime(n)) sites.push(n);
|
|
1932
|
+
(_a = n.children) == null ? void 0 : _a.forEach(collect);
|
|
1876
1933
|
};
|
|
1877
1934
|
collect(root);
|
|
1878
1935
|
for (const useNode of sites) {
|
|
1879
|
-
const retime = (
|
|
1936
|
+
const retime = readCloneRetime(useNode);
|
|
1880
1937
|
if (!retime) continue;
|
|
1881
|
-
|
|
1882
|
-
if (Object.keys(useNode.effects).length === 0) delete useNode.effects;
|
|
1938
|
+
clearCloneRetime(useNode);
|
|
1883
1939
|
materialiseRetime(useNode, asRetime(retime), ctx);
|
|
1884
1940
|
}
|
|
1885
1941
|
}
|
|
@@ -1903,7 +1959,6 @@ function materialiseRetime(useNode, retime, ctx) {
|
|
|
1903
1959
|
}
|
|
1904
1960
|
}
|
|
1905
1961
|
function buildChainClone(targetId, accum, ctx, chain) {
|
|
1906
|
-
var _a, _b;
|
|
1907
1962
|
if (chain.has(targetId)) {
|
|
1908
1963
|
ctx.errors.push('retime: loop via "' + targetId + '"');
|
|
1909
1964
|
return void 0;
|
|
@@ -1920,25 +1975,43 @@ function buildChainClone(targetId, accum, ctx, chain) {
|
|
|
1920
1975
|
} else {
|
|
1921
1976
|
remapKeyframeTimes(cloneNode, accum.start, accum.stretch);
|
|
1922
1977
|
}
|
|
1923
|
-
|
|
1924
|
-
delete cloneNode.effects.retime;
|
|
1925
|
-
if (Object.keys(cloneNode.effects).length === 0) delete cloneNode.effects;
|
|
1926
|
-
}
|
|
1978
|
+
clearCloneRetime(cloneNode);
|
|
1927
1979
|
if (target.type === "use" && target.href) {
|
|
1928
1980
|
const subId = stripHash(target.href);
|
|
1929
1981
|
if (subId) {
|
|
1930
|
-
const innerRetime = (
|
|
1982
|
+
const innerRetime = readCloneRetime(target);
|
|
1931
1983
|
const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
|
|
1932
1984
|
const subChain = new Set(chain);
|
|
1933
1985
|
subChain.add(targetId);
|
|
1934
1986
|
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
1935
1987
|
if (subId2) cloneNode.href = "#" + subId2;
|
|
1936
1988
|
}
|
|
1989
|
+
} else {
|
|
1990
|
+
materialiseNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
|
|
1937
1991
|
}
|
|
1938
1992
|
ctx.defs.push(cloneNode);
|
|
1939
1993
|
if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
|
|
1940
1994
|
return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
|
|
1941
1995
|
}
|
|
1996
|
+
function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
|
|
1997
|
+
const visit = (n) => {
|
|
1998
|
+
var _a;
|
|
1999
|
+
const retime = readCloneRetime(n);
|
|
2000
|
+
if (n.type === "use" && retime && n.href) {
|
|
2001
|
+
const subId = stripHash(n.href);
|
|
2002
|
+
if (subId) {
|
|
2003
|
+
const subAccum = concatRetime(asRetime(retime), accum);
|
|
2004
|
+
const subChain = new Set(chain);
|
|
2005
|
+
subChain.add(parentTargetId);
|
|
2006
|
+
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
2007
|
+
if (subId2) n.href = "#" + subId2;
|
|
2008
|
+
}
|
|
2009
|
+
clearCloneRetime(n);
|
|
2010
|
+
}
|
|
2011
|
+
(_a = n.children) == null ? void 0 : _a.forEach(visit);
|
|
2012
|
+
};
|
|
2013
|
+
visit(node);
|
|
2014
|
+
}
|
|
1942
2015
|
function remapKeyframeTimes(node, start, stretch) {
|
|
1943
2016
|
var _a;
|
|
1944
2017
|
remapKeyframeTimesOnly(node, start, stretch);
|
|
@@ -1983,12 +2056,14 @@ function applyAnimatableNumber(node, attrName, raw) {
|
|
|
1983
2056
|
node[attrName] = String(raw);
|
|
1984
2057
|
return;
|
|
1985
2058
|
}
|
|
1986
|
-
if (typeof raw === "object") {
|
|
2059
|
+
if (typeof raw === "object" && raw !== null) {
|
|
1987
2060
|
const obj = raw;
|
|
1988
2061
|
if (Array.isArray(obj.keyframes)) {
|
|
1989
2062
|
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
1990
2063
|
const animate = __spreadValues({}, prevAnimate || {});
|
|
1991
|
-
|
|
2064
|
+
const block = { keyframes: obj.keyframes };
|
|
2065
|
+
if (obj.loop !== void 0) block.loop = obj.loop;
|
|
2066
|
+
animate[attrName] = block;
|
|
1992
2067
|
node.animate = animate;
|
|
1993
2068
|
return;
|
|
1994
2069
|
}
|
|
@@ -1999,6 +2074,61 @@ function applyAnimatableNumber(node, attrName, raw) {
|
|
|
1999
2074
|
}
|
|
2000
2075
|
}
|
|
2001
2076
|
|
|
2077
|
+
// src/effects/elementFactory.ts
|
|
2078
|
+
var jsonElementFactory = (type, props, children) => {
|
|
2079
|
+
const node = { type };
|
|
2080
|
+
for (const k in props) if (props[k] !== void 0) node[k] = props[k];
|
|
2081
|
+
const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
|
|
2082
|
+
if (arr.length) node.children = arr;
|
|
2083
|
+
return node;
|
|
2084
|
+
};
|
|
2085
|
+
|
|
2086
|
+
// src/effects/glyphPathBake.ts
|
|
2087
|
+
function fmt(v, decimals) {
|
|
2088
|
+
return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
|
|
2089
|
+
}
|
|
2090
|
+
function pack(nums, decimals) {
|
|
2091
|
+
let s = "";
|
|
2092
|
+
for (let i = 0; i < nums.length; i++) {
|
|
2093
|
+
const str2 = fmt(nums[i], decimals);
|
|
2094
|
+
if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
|
|
2095
|
+
s += str2;
|
|
2096
|
+
}
|
|
2097
|
+
return s;
|
|
2098
|
+
}
|
|
2099
|
+
function apply(m, x, y) {
|
|
2100
|
+
return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
|
|
2101
|
+
}
|
|
2102
|
+
var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
|
|
2103
|
+
function transformPathData(d, m, decimals = 2) {
|
|
2104
|
+
const tokens = [];
|
|
2105
|
+
let match;
|
|
2106
|
+
TOKEN_RE.lastIndex = 0;
|
|
2107
|
+
while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
|
|
2108
|
+
let out = "";
|
|
2109
|
+
let i = 0;
|
|
2110
|
+
const num2 = () => parseFloat(tokens[i++]);
|
|
2111
|
+
while (i < tokens.length) {
|
|
2112
|
+
const cmd = tokens[i++];
|
|
2113
|
+
if (cmd === "M" || cmd === "L") {
|
|
2114
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2115
|
+
out += cmd + pack([x, y], decimals);
|
|
2116
|
+
} else if (cmd === "C") {
|
|
2117
|
+
const [x1, y1] = apply(m, num2(), num2());
|
|
2118
|
+
const [x2, y2] = apply(m, num2(), num2());
|
|
2119
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2120
|
+
out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
|
|
2121
|
+
} else if (cmd === "Q") {
|
|
2122
|
+
const [x1, y1] = apply(m, num2(), num2());
|
|
2123
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2124
|
+
out += "Q" + pack([x1, y1, x, y], decimals);
|
|
2125
|
+
} else if (cmd === "Z" || cmd === "z") {
|
|
2126
|
+
out += "Z";
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
return out;
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2002
2132
|
// src/PxAnimatorUtil.ts
|
|
2003
2133
|
function bezierToSvgPath(path) {
|
|
2004
2134
|
var _a, _b, _c, _d;
|
|
@@ -2371,6 +2501,24 @@ function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
|
|
|
2371
2501
|
}
|
|
2372
2502
|
return { ts, ds };
|
|
2373
2503
|
}
|
|
2504
|
+
function bezier2D_tForDistance(lut, distance) {
|
|
2505
|
+
const { ts, ds } = lut;
|
|
2506
|
+
const last = ds.length - 1;
|
|
2507
|
+
if (distance <= 0) return ts[0];
|
|
2508
|
+
if (distance >= ds[last]) return ts[last];
|
|
2509
|
+
let lo = 1;
|
|
2510
|
+
let hi = last;
|
|
2511
|
+
while (lo < hi) {
|
|
2512
|
+
const mid = lo + hi >>> 1;
|
|
2513
|
+
if (ds[mid] < distance) lo = mid + 1;
|
|
2514
|
+
else hi = mid;
|
|
2515
|
+
}
|
|
2516
|
+
const dPrev = ds[hi - 1];
|
|
2517
|
+
const dCur = ds[hi];
|
|
2518
|
+
const span = dCur - dPrev;
|
|
2519
|
+
const frac = span > 0 ? (distance - dPrev) / span : 0;
|
|
2520
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
2521
|
+
}
|
|
2374
2522
|
function bezier2D_arcAtT(lut, t) {
|
|
2375
2523
|
const { ts, ds } = lut;
|
|
2376
2524
|
const last = ts.length - 1;
|
|
@@ -2393,6 +2541,437 @@ function invertEasing(easing) {
|
|
|
2393
2541
|
return cubicBezier(flipped);
|
|
2394
2542
|
}
|
|
2395
2543
|
|
|
2544
|
+
// src/effects/pathSampler.ts
|
|
2545
|
+
var LUT_STEPS = 48;
|
|
2546
|
+
var CMD_RE = /[MmLlHhVvCcSsQqTtAaZz]/;
|
|
2547
|
+
function tokenize(d) {
|
|
2548
|
+
const tokens = [];
|
|
2549
|
+
const re = /([MmLlHhVvCcSsQqTtAaZz])|(-?\d*\.?\d+(?:[eE][-+]?\d+)?)/g;
|
|
2550
|
+
let m;
|
|
2551
|
+
while ((m = re.exec(d)) !== null) tokens.push(m[0]);
|
|
2552
|
+
return tokens;
|
|
2553
|
+
}
|
|
2554
|
+
function quadToCubic(P0, Qc, P3) {
|
|
2555
|
+
return {
|
|
2556
|
+
P1: [P0[0] + 2 / 3 * (Qc[0] - P0[0]), P0[1] + 2 / 3 * (Qc[1] - P0[1])],
|
|
2557
|
+
P2: [P3[0] + 2 / 3 * (Qc[0] - P3[0]), P3[1] + 2 / 3 * (Qc[1] - P3[1])]
|
|
2558
|
+
};
|
|
2559
|
+
}
|
|
2560
|
+
function parseCubics(d) {
|
|
2561
|
+
const tokens = tokenize(d);
|
|
2562
|
+
const segs = [];
|
|
2563
|
+
let i = 0;
|
|
2564
|
+
let cx = 0, cy = 0;
|
|
2565
|
+
let sx = 0, sy = 0;
|
|
2566
|
+
let pcx = 0, pcy = 0;
|
|
2567
|
+
let pqx = 0, pqy = 0;
|
|
2568
|
+
let prevCmd = "";
|
|
2569
|
+
const num2 = () => parseFloat(tokens[i++]);
|
|
2570
|
+
const push = (P1, P2, P3) => {
|
|
2571
|
+
const P0 = [cx, cy];
|
|
2572
|
+
const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);
|
|
2573
|
+
segs.push({ P0, P1, P2, P3, lut, len: lut.ds[lut.ds.length - 1] });
|
|
2574
|
+
cx = P3[0];
|
|
2575
|
+
cy = P3[1];
|
|
2576
|
+
};
|
|
2577
|
+
const pushLine = (x, y) => {
|
|
2578
|
+
push(
|
|
2579
|
+
[cx + (x - cx) / 3, cy + (y - cy) / 3],
|
|
2580
|
+
[cx + 2 * (x - cx) / 3, cy + 2 * (y - cy) / 3],
|
|
2581
|
+
[x, y]
|
|
2582
|
+
);
|
|
2583
|
+
};
|
|
2584
|
+
while (i < tokens.length) {
|
|
2585
|
+
let cmd = tokens[i];
|
|
2586
|
+
if (CMD_RE.test(cmd)) i++;
|
|
2587
|
+
else cmd = prevCmd === "M" ? "L" : prevCmd === "m" ? "l" : prevCmd;
|
|
2588
|
+
const rel = cmd >= "a";
|
|
2589
|
+
const U = cmd.toUpperCase();
|
|
2590
|
+
if (U === "Z") {
|
|
2591
|
+
pushLine(sx, sy);
|
|
2592
|
+
cx = sx;
|
|
2593
|
+
cy = sy;
|
|
2594
|
+
prevCmd = cmd;
|
|
2595
|
+
continue;
|
|
2596
|
+
}
|
|
2597
|
+
if (U === "M") {
|
|
2598
|
+
const x = num2() + (rel ? cx : 0), y = num2() + (rel ? cy : 0);
|
|
2599
|
+
cx = x;
|
|
2600
|
+
cy = y;
|
|
2601
|
+
sx = x;
|
|
2602
|
+
sy = y;
|
|
2603
|
+
prevCmd = cmd;
|
|
2604
|
+
continue;
|
|
2605
|
+
}
|
|
2606
|
+
if (U === "L") {
|
|
2607
|
+
pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
|
|
2608
|
+
} else if (U === "H") {
|
|
2609
|
+
pushLine(num2() + (rel ? cx : 0), cy);
|
|
2610
|
+
} else if (U === "V") {
|
|
2611
|
+
pushLine(cx, num2() + (rel ? cy : 0));
|
|
2612
|
+
} else if (U === "C") {
|
|
2613
|
+
const p1 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2614
|
+
const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2615
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2616
|
+
pcx = p2[0];
|
|
2617
|
+
pcy = p2[1];
|
|
2618
|
+
push(p1, p2, p3);
|
|
2619
|
+
} else if (U === "S") {
|
|
2620
|
+
const smooth = prevCmd.toUpperCase() === "C" || prevCmd.toUpperCase() === "S";
|
|
2621
|
+
const p1 = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];
|
|
2622
|
+
const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2623
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2624
|
+
pcx = p2[0];
|
|
2625
|
+
pcy = p2[1];
|
|
2626
|
+
push(p1, p2, p3);
|
|
2627
|
+
} else if (U === "Q") {
|
|
2628
|
+
const qc = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2629
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2630
|
+
pqx = qc[0];
|
|
2631
|
+
pqy = qc[1];
|
|
2632
|
+
const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
|
|
2633
|
+
push(P1, P2, p3);
|
|
2634
|
+
} else if (U === "T") {
|
|
2635
|
+
const smooth = prevCmd.toUpperCase() === "Q" || prevCmd.toUpperCase() === "T";
|
|
2636
|
+
const qc = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];
|
|
2637
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2638
|
+
pqx = qc[0];
|
|
2639
|
+
pqy = qc[1];
|
|
2640
|
+
const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
|
|
2641
|
+
push(P1, P2, p3);
|
|
2642
|
+
} else if (U === "A") {
|
|
2643
|
+
i += 5;
|
|
2644
|
+
pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
|
|
2645
|
+
} else {
|
|
2646
|
+
i++;
|
|
2647
|
+
continue;
|
|
2648
|
+
}
|
|
2649
|
+
prevCmd = cmd;
|
|
2650
|
+
}
|
|
2651
|
+
return segs.length ? segs : null;
|
|
2652
|
+
}
|
|
2653
|
+
function clamp2(v, lo, hi) {
|
|
2654
|
+
return v < lo ? lo : v > hi ? hi : v;
|
|
2655
|
+
}
|
|
2656
|
+
function createPathSampler(d) {
|
|
2657
|
+
const segs = parseCubics(d);
|
|
2658
|
+
if (!segs) return null;
|
|
2659
|
+
const cum = new Float64Array(segs.length + 1);
|
|
2660
|
+
for (let k = 0; k < segs.length; k++) cum[k + 1] = cum[k] + segs[k].len;
|
|
2661
|
+
const totalLength = cum[segs.length];
|
|
2662
|
+
const start = segs[0].P0, end = segs[segs.length - 1].P3;
|
|
2663
|
+
const closed = Math.hypot(end[0] - start[0], end[1] - start[1]) < 1e-3;
|
|
2664
|
+
const sampleOn = (dist) => {
|
|
2665
|
+
let k = 0;
|
|
2666
|
+
while (k < segs.length - 1 && dist > cum[k + 1]) k++;
|
|
2667
|
+
const seg = segs[k];
|
|
2668
|
+
const local = dist - cum[k];
|
|
2669
|
+
const t = seg.len > 0 ? bezier2D_tForDistance(seg.lut, local) : 0;
|
|
2670
|
+
const [x, y] = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2671
|
+
const [dx, dy] = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2672
|
+
return { x, y, angle: Math.atan2(dy, dx) };
|
|
2673
|
+
};
|
|
2674
|
+
return {
|
|
2675
|
+
totalLength,
|
|
2676
|
+
sampleAtDistance(dist) {
|
|
2677
|
+
if (!closed && (dist < 0 || dist > totalLength)) {
|
|
2678
|
+
const edge = dist < 0 ? 0 : totalLength;
|
|
2679
|
+
const p = sampleOn(edge);
|
|
2680
|
+
const over = dist - edge;
|
|
2681
|
+
return { x: p.x + Math.cos(p.angle) * over, y: p.y + Math.sin(p.angle) * over, angle: p.angle };
|
|
2682
|
+
}
|
|
2683
|
+
return sampleOn(clamp2(dist, 0, totalLength));
|
|
2684
|
+
}
|
|
2685
|
+
};
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
// src/effects/textGlyphsEffect.ts
|
|
2689
|
+
var DEFAULT_FONT_SIZE = 16;
|
|
2690
|
+
var TEXT_ATTR_KEYS = [
|
|
2691
|
+
"fontFamily",
|
|
2692
|
+
"fontSize",
|
|
2693
|
+
"fontWeight",
|
|
2694
|
+
"fontStyle",
|
|
2695
|
+
"textAnchor",
|
|
2696
|
+
"letterSpacing",
|
|
2697
|
+
"wordSpacing",
|
|
2698
|
+
"textDecoration",
|
|
2699
|
+
"textTransform",
|
|
2700
|
+
"whiteSpace",
|
|
2701
|
+
"x",
|
|
2702
|
+
"y",
|
|
2703
|
+
"dx",
|
|
2704
|
+
"dy",
|
|
2705
|
+
"lengthAdjust",
|
|
2706
|
+
"fill",
|
|
2707
|
+
"stroke",
|
|
2708
|
+
"strokeWidth",
|
|
2709
|
+
"effects",
|
|
2710
|
+
TEXT_ATTR,
|
|
2711
|
+
TEXT_CONTENT_ATTR,
|
|
2712
|
+
"xml:space"
|
|
2713
|
+
];
|
|
2714
|
+
function parseLen(v) {
|
|
2715
|
+
if (typeof v === "number") return v;
|
|
2716
|
+
if (typeof v === "string") {
|
|
2717
|
+
const n = parseFloat(v);
|
|
2718
|
+
return isNaN(n) ? void 0 : n;
|
|
2719
|
+
}
|
|
2720
|
+
return void 0;
|
|
2721
|
+
}
|
|
2722
|
+
function str(v) {
|
|
2723
|
+
return typeof v === "string" ? v : void 0;
|
|
2724
|
+
}
|
|
2725
|
+
function resolveStyle(node, parent) {
|
|
2726
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2727
|
+
return {
|
|
2728
|
+
fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
|
|
2729
|
+
fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
|
|
2730
|
+
fill: (_c = node.fill) != null ? _c : parent.fill,
|
|
2731
|
+
stroke: (_d = node.stroke) != null ? _d : parent.stroke,
|
|
2732
|
+
strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
|
|
2733
|
+
letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
|
|
2734
|
+
wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing
|
|
2735
|
+
};
|
|
2736
|
+
}
|
|
2737
|
+
function rootStyleOf(node) {
|
|
2738
|
+
var _a, _b, _c;
|
|
2739
|
+
return {
|
|
2740
|
+
fontFamily: str(node.fontFamily),
|
|
2741
|
+
fontSize: (_a = parseLen(node.fontSize)) != null ? _a : DEFAULT_FONT_SIZE,
|
|
2742
|
+
fill: node.fill,
|
|
2743
|
+
stroke: node.stroke,
|
|
2744
|
+
strokeWidth: node.strokeWidth,
|
|
2745
|
+
letterSpacing: (_b = parseLen(node.letterSpacing)) != null ? _b : 0,
|
|
2746
|
+
wordSpacing: (_c = parseLen(node.wordSpacing)) != null ? _c : 0
|
|
2747
|
+
};
|
|
2748
|
+
}
|
|
2749
|
+
function paintOf(s) {
|
|
2750
|
+
const p = {};
|
|
2751
|
+
if (s.fill !== void 0) p.fill = s.fill;
|
|
2752
|
+
if (s.stroke !== void 0) p.stroke = s.stroke;
|
|
2753
|
+
if (s.strokeWidth !== void 0) p.strokeWidth = s.strokeWidth;
|
|
2754
|
+
return p;
|
|
2755
|
+
}
|
|
2756
|
+
function glyphFontFor(s, glyphs, soleFont, warnings) {
|
|
2757
|
+
var _a;
|
|
2758
|
+
const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
|
|
2759
|
+
if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a = s.fontFamily) != null ? _a : "") + '"');
|
|
2760
|
+
return gf;
|
|
2761
|
+
}
|
|
2762
|
+
function soleFontOf(glyphs) {
|
|
2763
|
+
const names = Object.keys(glyphs);
|
|
2764
|
+
return names.length === 1 ? glyphs[names[0]] : void 0;
|
|
2765
|
+
}
|
|
2766
|
+
function materialiseGlyphTextHorizontal(node, opts) {
|
|
2767
|
+
var _a, _b, _c, _d;
|
|
2768
|
+
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
2769
|
+
const soleFont = soleFontOf(glyphs);
|
|
2770
|
+
const pen = { x: (_a = parseLen(node.x)) != null ? _a : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
|
|
2771
|
+
const placements = [];
|
|
2772
|
+
const lines = [{ start: pen.x, end: pen.x }];
|
|
2773
|
+
let line = 0;
|
|
2774
|
+
const renderChars = (content, s) => {
|
|
2775
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2776
|
+
if (!gf) return;
|
|
2777
|
+
const scale = s.fontSize / gf.unitsPerEm;
|
|
2778
|
+
const paint = paintOf(s);
|
|
2779
|
+
for (let i = 0; i < content.length; i++) {
|
|
2780
|
+
const ch = content.charAt(i);
|
|
2781
|
+
const g = gf.glyphs[ch];
|
|
2782
|
+
if (g && g.d) placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
|
|
2783
|
+
pen.x += (g ? g.width : 0) * scale + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2784
|
+
lines[line].end = pen.x;
|
|
2785
|
+
}
|
|
2786
|
+
};
|
|
2787
|
+
const walk = (el, parentStyle) => {
|
|
2788
|
+
var _a2, _b2, _c2, _d2;
|
|
2789
|
+
const s = resolveStyle(el, parentStyle);
|
|
2790
|
+
const x = parseLen(el.x);
|
|
2791
|
+
const y = parseLen(el.y);
|
|
2792
|
+
if (x !== void 0) {
|
|
2793
|
+
pen.x = x;
|
|
2794
|
+
line = lines.length;
|
|
2795
|
+
lines.push({ start: pen.x, end: pen.x });
|
|
2796
|
+
}
|
|
2797
|
+
if (y !== void 0) pen.y = y;
|
|
2798
|
+
pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
|
|
2799
|
+
pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
|
|
2800
|
+
const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
|
|
2801
|
+
if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
|
|
2802
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2803
|
+
};
|
|
2804
|
+
const rootStyle = rootStyleOf(node);
|
|
2805
|
+
if (node.children) for (const ch of node.children) walk(ch, rootStyle);
|
|
2806
|
+
const rootContent = (_c = str(node[TEXT_ATTR])) != null ? _c : str(node[TEXT_CONTENT_ATTR]);
|
|
2807
|
+
if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
|
|
2808
|
+
const anchor = str(node.textAnchor);
|
|
2809
|
+
if (anchor === "middle" || anchor === "end") {
|
|
2810
|
+
for (const p of placements) {
|
|
2811
|
+
const w = lines[p.line].end - lines[p.line].start;
|
|
2812
|
+
const shift = anchor === "middle" ? -w / 2 : -w;
|
|
2813
|
+
p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
2817
|
+
}
|
|
2818
|
+
function collectAlongPathCells(node, glyphs, soleFont, warnings) {
|
|
2819
|
+
const cells = [];
|
|
2820
|
+
let adv = 0;
|
|
2821
|
+
const walk = (el, parentStyle) => {
|
|
2822
|
+
var _a, _b;
|
|
2823
|
+
const s = resolveStyle(el, parentStyle);
|
|
2824
|
+
const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
|
|
2825
|
+
if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
|
|
2826
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2827
|
+
if (gf) {
|
|
2828
|
+
const scale = s.fontSize / gf.unitsPerEm;
|
|
2829
|
+
const paint = paintOf(s);
|
|
2830
|
+
for (let i = 0; i < content.length; i++) {
|
|
2831
|
+
const ch = content.charAt(i);
|
|
2832
|
+
const g = gf.glyphs[ch];
|
|
2833
|
+
const glyphAdv = (g ? g.width : 0) * scale;
|
|
2834
|
+
if (g && g.d) cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
|
|
2835
|
+
adv += glyphAdv + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2840
|
+
};
|
|
2841
|
+
walk(node, rootStyleOf(node));
|
|
2842
|
+
return { cells, width: adv };
|
|
2843
|
+
}
|
|
2844
|
+
function alongAffine(sampler, dist, scale, widthEm) {
|
|
2845
|
+
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
2846
|
+
const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;
|
|
2847
|
+
return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw, y - scale * sin * hw];
|
|
2848
|
+
}
|
|
2849
|
+
function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength) {
|
|
2850
|
+
var _a;
|
|
2851
|
+
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
2852
|
+
const sampler = pathD ? createPathSampler(pathD) : null;
|
|
2853
|
+
if (!sampler) {
|
|
2854
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry");
|
|
2855
|
+
return null;
|
|
2856
|
+
}
|
|
2857
|
+
const soleFont = soleFontOf(glyphs);
|
|
2858
|
+
const { cells, width } = collectAlongPathCells(node, glyphs, soleFont, warnings);
|
|
2859
|
+
if (!cells.length) return toGroup(node, [], create);
|
|
2860
|
+
if (textLength && textLength > 0 && width > 0) {
|
|
2861
|
+
const k = textLength / width;
|
|
2862
|
+
for (const c of cells) c.midBase *= k;
|
|
2863
|
+
}
|
|
2864
|
+
const so = readAnimatable(startOffset);
|
|
2865
|
+
if (so.kind === "animated" /* Animated */ && so.keyframes.length >= 2) {
|
|
2866
|
+
return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create), create);
|
|
2867
|
+
}
|
|
2868
|
+
const base = so.kind === "animated" /* Animated */ ? Number((_a = so.keyframes[0]) == null ? void 0 : _a.value) || 0 : so.kind === "static" /* Static */ ? Number(so.value) || 0 : 0;
|
|
2869
|
+
const placements = cells.map((c) => ({
|
|
2870
|
+
glyphD: c.glyphD,
|
|
2871
|
+
paint: c.paint,
|
|
2872
|
+
m: alongAffine(sampler, base + c.midBase, c.scale, c.widthEm)
|
|
2873
|
+
}));
|
|
2874
|
+
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
2875
|
+
}
|
|
2876
|
+
var ALONG_PATH_MAX_STEPS = 48;
|
|
2877
|
+
var ALONG_PATH_MAX_STEPS_PER_SEGMENT = 64;
|
|
2878
|
+
function roundN(v, n) {
|
|
2879
|
+
const f = __pow(10, n);
|
|
2880
|
+
return Math.round(v * f) / f;
|
|
2881
|
+
}
|
|
2882
|
+
function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create) {
|
|
2883
|
+
const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);
|
|
2884
|
+
const timeOf = (kf) => Number(kf.time) || 0;
|
|
2885
|
+
const offOf = (kf) => Number(kf.value) || 0;
|
|
2886
|
+
const out = [];
|
|
2887
|
+
for (const c of cells) {
|
|
2888
|
+
const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
|
|
2889
|
+
const d = transformPathData(c.glyphD, centred);
|
|
2890
|
+
const sampleKf = (dist, time) => {
|
|
2891
|
+
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
2892
|
+
return {
|
|
2893
|
+
time,
|
|
2894
|
+
value: {
|
|
2895
|
+
["translate" /* Translate */]: [roundN(x, 3), roundN(y, 3)],
|
|
2896
|
+
["rotate" /* Rotate */]: roundN(angle * 180 / Math.PI, 3)
|
|
2897
|
+
}
|
|
2898
|
+
};
|
|
2899
|
+
};
|
|
2900
|
+
const kfs = [sampleKf(offOf(sokfs[0]) + c.midBase, timeOf(sokfs[0]))];
|
|
2901
|
+
for (let k = 1; k < sokfs.length; k++) {
|
|
2902
|
+
const t0 = timeOf(sokfs[k - 1]), t1 = timeOf(sokfs[k]);
|
|
2903
|
+
const o0 = offOf(sokfs[k - 1]), o1 = offOf(sokfs[k]);
|
|
2904
|
+
const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(o1 - o0) / step)));
|
|
2905
|
+
for (let s = 1; s <= n; s++) {
|
|
2906
|
+
const f = s / n;
|
|
2907
|
+
kfs.push(sampleKf(o0 + f * (o1 - o0) + c.midBase, t0 + f * (t1 - t0)));
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
const transform = { keyframes: kfs };
|
|
2911
|
+
if (loop !== void 0) transform.loop = loop;
|
|
2912
|
+
out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate: { transform } }), []));
|
|
2913
|
+
}
|
|
2914
|
+
return out;
|
|
2915
|
+
}
|
|
2916
|
+
function paintProps(paint) {
|
|
2917
|
+
const p = {};
|
|
2918
|
+
if (paint.fill !== void 0) p.fill = paint.fill;
|
|
2919
|
+
if (paint.stroke !== void 0) p.stroke = paint.stroke;
|
|
2920
|
+
if (paint.strokeWidth !== void 0) p.strokeWidth = paint.strokeWidth;
|
|
2921
|
+
return p;
|
|
2922
|
+
}
|
|
2923
|
+
function buildPaths(placements, create, warnings) {
|
|
2924
|
+
var _a, _b, _c;
|
|
2925
|
+
if (!placements.length) {
|
|
2926
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
|
|
2927
|
+
return [];
|
|
2928
|
+
}
|
|
2929
|
+
const byPaint = /* @__PURE__ */ new Map();
|
|
2930
|
+
for (const p of placements) {
|
|
2931
|
+
const key = JSON.stringify([(_a = p.paint.fill) != null ? _a : null, (_b = p.paint.stroke) != null ? _b : null, (_c = p.paint.strokeWidth) != null ? _c : null]);
|
|
2932
|
+
const baked = transformPathData(p.glyphD, p.m);
|
|
2933
|
+
const entry = byPaint.get(key);
|
|
2934
|
+
if (entry) entry.d += baked;
|
|
2935
|
+
else byPaint.set(key, { paint: p.paint, d: baked });
|
|
2936
|
+
}
|
|
2937
|
+
const out = [];
|
|
2938
|
+
for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues({ d }, paintProps(paint)), []));
|
|
2939
|
+
return out;
|
|
2940
|
+
}
|
|
2941
|
+
function toGroup(node, children, create) {
|
|
2942
|
+
const gProps = {};
|
|
2943
|
+
for (const k of Object.keys(node)) {
|
|
2944
|
+
if (k === "type" || k === "children" || TEXT_ATTR_KEYS.indexOf(k) !== -1) continue;
|
|
2945
|
+
gProps[k] = node[k];
|
|
2946
|
+
}
|
|
2947
|
+
if (gProps.style && typeof gProps.style === "object") {
|
|
2948
|
+
const style = __spreadValues({}, gProps.style);
|
|
2949
|
+
delete style["white-space"];
|
|
2950
|
+
if (Object.keys(style).length) gProps.style = style;
|
|
2951
|
+
else delete gProps.style;
|
|
2952
|
+
}
|
|
2953
|
+
return create("g", gProps, children);
|
|
2954
|
+
}
|
|
2955
|
+
function materialiseGlyphText(node, opts) {
|
|
2956
|
+
if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength);
|
|
2957
|
+
return materialiseGlyphTextHorizontal(node, opts);
|
|
2958
|
+
}
|
|
2959
|
+
function applyTextGlyphsEffect(node, fx, ctx) {
|
|
2960
|
+
if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
|
|
2961
|
+
if (!ctx.glyphs) {
|
|
2962
|
+
ctx.warnings.push("textGlyphs: no definitions.glyphs \u2014 left as native <text>");
|
|
2963
|
+
return node;
|
|
2964
|
+
}
|
|
2965
|
+
return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
|
|
2966
|
+
}
|
|
2967
|
+
function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength) {
|
|
2968
|
+
if (!ctx.glyphs) {
|
|
2969
|
+
ctx.warnings.push("textGlyphs: no definitions.glyphs");
|
|
2970
|
+
return null;
|
|
2971
|
+
}
|
|
2972
|
+
return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength);
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2396
2975
|
// src/PxMotionPath.ts
|
|
2397
2976
|
function getKfTranslate(kf) {
|
|
2398
2977
|
var _a;
|
|
@@ -2836,12 +3415,12 @@ function parseSvgPathToBezier(d) {
|
|
|
2836
3415
|
}
|
|
2837
3416
|
return res;
|
|
2838
3417
|
}
|
|
2839
|
-
function extractPathData(
|
|
2840
|
-
if (
|
|
2841
|
-
return
|
|
3418
|
+
function extractPathData(str2) {
|
|
3419
|
+
if (str2.startsWith("path(") && str2.endsWith(")")) {
|
|
3420
|
+
return str2.slice(5, -1);
|
|
2842
3421
|
}
|
|
2843
|
-
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(
|
|
2844
|
-
return
|
|
3422
|
+
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str2)) {
|
|
3423
|
+
return str2;
|
|
2845
3424
|
}
|
|
2846
3425
|
return void 0;
|
|
2847
3426
|
}
|
|
@@ -3051,16 +3630,67 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
|
3051
3630
|
looped.push(pushed);
|
|
3052
3631
|
}
|
|
3053
3632
|
}
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3633
|
+
function appendRepTail(repStart, isReversed, tailFraction) {
|
|
3634
|
+
let entries;
|
|
3635
|
+
if (isReversed) {
|
|
3636
|
+
entries = [];
|
|
3637
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
3638
|
+
entries.push({
|
|
3639
|
+
relT: 1 - template[i].relT,
|
|
3640
|
+
v: template[i].v,
|
|
3641
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
3642
|
+
tangentIn: template[i].tangentOut,
|
|
3643
|
+
tangentOut: template[i].tangentIn
|
|
3644
|
+
});
|
|
3645
|
+
}
|
|
3646
|
+
} else {
|
|
3647
|
+
entries = template;
|
|
3648
|
+
}
|
|
3649
|
+
const startRelT = 1 - tailFraction;
|
|
3650
|
+
for (let i = 0; i < entries.length; i++) {
|
|
3651
|
+
const entry = entries[i];
|
|
3652
|
+
if (entry.relT < startRelT - 1e-9) continue;
|
|
3653
|
+
const prev = entries[i - 1];
|
|
3654
|
+
if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {
|
|
3655
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
3656
|
+
const localFrac = (startRelT - prev.relT) / intervalSpan;
|
|
3657
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
3658
|
+
const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
3659
|
+
const { right: rightEasing } = splitEasing(prev.e, localFrac);
|
|
3660
|
+
looped.push({ t: repStart, v: startValue, e: rightEasing });
|
|
3661
|
+
}
|
|
3662
|
+
const pushed = {
|
|
3663
|
+
t: repStart + (entry.relT - startRelT) * segDuration,
|
|
3664
|
+
v: entry.v,
|
|
3665
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
3666
|
+
};
|
|
3667
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
3668
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
3669
|
+
looped.push(pushed);
|
|
3670
|
+
}
|
|
3059
3671
|
}
|
|
3060
|
-
if (
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3672
|
+
if (loop.before) {
|
|
3673
|
+
if (partialFraction > 1e-9) {
|
|
3674
|
+
const isReversed = !!loop.alternate && fullReps % 2 === 0;
|
|
3675
|
+
appendRepTail(fillStart, isReversed, partialFraction);
|
|
3676
|
+
}
|
|
3677
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
3678
|
+
const distFromBoundary = fullReps - 1 - rep;
|
|
3679
|
+
const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
|
|
3680
|
+
const repStart = fillStart + remainder + rep * segDuration;
|
|
3681
|
+
appendRep(repStart, isReversed);
|
|
3682
|
+
}
|
|
3683
|
+
} else {
|
|
3684
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
3685
|
+
const isReversed = !!loop.alternate && rep % 2 === 0;
|
|
3686
|
+
const repStart = fillStart + rep * segDuration;
|
|
3687
|
+
appendRep(repStart, isReversed);
|
|
3688
|
+
}
|
|
3689
|
+
if (partialFraction > 1e-9) {
|
|
3690
|
+
const isReversed = !!loop.alternate && fullReps % 2 === 0;
|
|
3691
|
+
const repStart = fillStart + fullReps * segDuration;
|
|
3692
|
+
appendRep(repStart, isReversed, partialFraction);
|
|
3693
|
+
}
|
|
3064
3694
|
}
|
|
3065
3695
|
if (loop.before) {
|
|
3066
3696
|
return [...looped, ...keyframes];
|
|
@@ -3379,7 +4009,6 @@ function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
|
|
|
3379
4009
|
if (!trimPath) return node;
|
|
3380
4010
|
const trimAllAsOne = !!trimPath.trimAllAsOne;
|
|
3381
4011
|
const leafEntries = [];
|
|
3382
|
-
let acc = 0;
|
|
3383
4012
|
const measure = (n) => {
|
|
3384
4013
|
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
3385
4014
|
for (const ch of n.children) measure(ch);
|
|
@@ -3391,15 +4020,22 @@ function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
|
|
|
3391
4020
|
if (!subpaths.length) return;
|
|
3392
4021
|
const entry = { leaf: n, subpaths: [] };
|
|
3393
4022
|
for (const sp of subpaths) {
|
|
3394
|
-
if (!trimAllAsOne) acc = 0;
|
|
3395
4023
|
const lengthPx = pxBezierPathLength(sp);
|
|
3396
|
-
entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx:
|
|
3397
|
-
acc += lengthPx;
|
|
4024
|
+
entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: 0 });
|
|
3398
4025
|
}
|
|
3399
4026
|
leafEntries.push(entry);
|
|
3400
4027
|
};
|
|
3401
4028
|
measure(node);
|
|
3402
4029
|
if (!leafEntries.length) return node;
|
|
4030
|
+
let acc = 0;
|
|
4031
|
+
const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;
|
|
4032
|
+
for (const entry of iterOrder) {
|
|
4033
|
+
for (const sp of entry.subpaths) {
|
|
4034
|
+
if (!trimAllAsOne) acc = 0;
|
|
4035
|
+
sp.startOffsetPx = acc;
|
|
4036
|
+
acc += sp.lengthPx;
|
|
4037
|
+
}
|
|
4038
|
+
}
|
|
3403
4039
|
const chainLengthPx = acc;
|
|
3404
4040
|
if (trimAllAsOne && chainLengthPx < 1e-3) return node;
|
|
3405
4041
|
const offsetReadRaw = readAnimatable(trimPath.offset);
|
|
@@ -3526,10 +4162,12 @@ function computeAnimAttr(read, map) {
|
|
|
3526
4162
|
value: map((_c = kf.value) != null ? _c : kf.v),
|
|
3527
4163
|
easing: (_d = kf.easing) != null ? _d : kf.e
|
|
3528
4164
|
};
|
|
3529
|
-
})
|
|
4165
|
+
}),
|
|
4166
|
+
loop: read.loop
|
|
3530
4167
|
};
|
|
3531
4168
|
}
|
|
3532
4169
|
function applyAttr(node, attrName, attr) {
|
|
4170
|
+
var _a, _b;
|
|
3533
4171
|
if (!attr) return;
|
|
3534
4172
|
if (attr.kind === "static" /* Static */) {
|
|
3535
4173
|
node[attrName] = attr.value;
|
|
@@ -3537,9 +4175,16 @@ function applyAttr(node, attrName, attr) {
|
|
|
3537
4175
|
}
|
|
3538
4176
|
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
3539
4177
|
const animate = __spreadValues({}, prevAnimate || {});
|
|
3540
|
-
|
|
4178
|
+
const block = { keyframes: attr.keyframes };
|
|
4179
|
+
if (attr.loop !== void 0) block.loop = attr.loop;
|
|
4180
|
+
animate[attrName] = block;
|
|
3541
4181
|
node.animate = animate;
|
|
4182
|
+
const firstKf = attr.keyframes[0];
|
|
4183
|
+
if (firstKf && ((_a = firstKf.value) != null ? _a : firstKf.v) !== void 0) {
|
|
4184
|
+
node[attrName] = (_b = firstKf.value) != null ? _b : firstKf.v;
|
|
4185
|
+
}
|
|
3542
4186
|
}
|
|
4187
|
+
var OPACITY_STEP_MS = 10;
|
|
3543
4188
|
function computeOpacityFromRange(rangeRead) {
|
|
3544
4189
|
var _a, _b, _c, _d, _e, _f;
|
|
3545
4190
|
const hide = (v) => v[0] === v[1];
|
|
@@ -3565,9 +4210,9 @@ function computeOpacityFromRange(rangeRead) {
|
|
|
3565
4210
|
const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
|
|
3566
4211
|
if (prevHide && !nextHide) {
|
|
3567
4212
|
out.push({ time: t, value: 0 });
|
|
3568
|
-
out.push({ time: t +
|
|
4213
|
+
out.push({ time: t + OPACITY_STEP_MS, value: 1 });
|
|
3569
4214
|
} else if (!prevHide && nextHide) {
|
|
3570
|
-
out.push({ time: t -
|
|
4215
|
+
out.push({ time: t - OPACITY_STEP_MS, value: 1 });
|
|
3571
4216
|
out.push({ time: t, value: 0 });
|
|
3572
4217
|
}
|
|
3573
4218
|
}
|
|
@@ -3700,6 +4345,7 @@ function rectToPathD(node) {
|
|
|
3700
4345
|
|
|
3701
4346
|
// src/effects/PlayerEffectsUtil.ts
|
|
3702
4347
|
function applyPlayerEffects(root) {
|
|
4348
|
+
var _a, _b;
|
|
3703
4349
|
const ctx = {
|
|
3704
4350
|
defs: [],
|
|
3705
4351
|
warnings: [],
|
|
@@ -3707,7 +4353,11 @@ function applyPlayerEffects(root) {
|
|
|
3707
4353
|
idMap: /* @__PURE__ */ new Map(),
|
|
3708
4354
|
nextId: 0,
|
|
3709
4355
|
contentRefInnerIds: /* @__PURE__ */ new Map(),
|
|
3710
|
-
maskAncestorChains: /* @__PURE__ */ new Map()
|
|
4356
|
+
maskAncestorChains: /* @__PURE__ */ new Map(),
|
|
4357
|
+
// Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →
|
|
4358
|
+
// webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
|
|
4359
|
+
engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi,
|
|
4360
|
+
glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
|
|
3711
4361
|
};
|
|
3712
4362
|
const working = clone(root);
|
|
3713
4363
|
indexById(working, ctx.idMap);
|
|
@@ -3719,27 +4369,46 @@ function applyPlayerEffects(root) {
|
|
|
3719
4369
|
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
3720
4370
|
}
|
|
3721
4371
|
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
4372
|
+
var _a;
|
|
3722
4373
|
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
3723
4374
|
const fx = node.effects;
|
|
3724
4375
|
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
3725
4376
|
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
3726
4377
|
if (!fx && !innerIdForContentRef) return node;
|
|
3727
|
-
const { transformation, repeater, maskedBy, trimPath,
|
|
4378
|
+
const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textAlongPath, text } = fx != null ? fx : {};
|
|
3728
4379
|
const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
|
|
3729
4380
|
if (fx) delete node.effects;
|
|
3730
4381
|
let n = node;
|
|
3731
|
-
|
|
4382
|
+
let consumedByGlyphs = false;
|
|
4383
|
+
if (text == null ? void 0 : text.useGlyphs) {
|
|
4384
|
+
if (textAlongPath) {
|
|
4385
|
+
const pathNode = typeof textAlongPath.href === "string" ? ctx.idMap.get(textAlongPath.href) : void 0;
|
|
4386
|
+
const pathD = pathNode && typeof pathNode.d === "string" ? pathNode.d : void 0;
|
|
4387
|
+
const rawTL = textAlongPath.textLength;
|
|
4388
|
+
const textLength = typeof rawTL === "number" ? rawTL : rawTL && typeof rawTL === "object" ? typeof rawTL.value === "number" ? rawTL.value : Array.isArray(rawTL.keyframes) && rawTL.keyframes.length ? Number((_a = rawTL.keyframes[0]) == null ? void 0 : _a.value) : void 0 : void 0;
|
|
4389
|
+
const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textAlongPath.startOffset, textLength);
|
|
4390
|
+
if (glyphed) {
|
|
4391
|
+
n = glyphed;
|
|
4392
|
+
consumedByGlyphs = true;
|
|
4393
|
+
}
|
|
4394
|
+
} else {
|
|
4395
|
+
n = applyTextGlyphsEffect(n, text, ctx);
|
|
4396
|
+
consumedByGlyphs = true;
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
if (!consumedByGlyphs) n = applyTextAlongPathEffect(n, textAlongPath, ctx);
|
|
3732
4400
|
n = applyFillGradientEffect(n, fillGradient, ctx);
|
|
3733
4401
|
n = applyStrokeGradientEffect(n, strokeGradient, ctx);
|
|
3734
4402
|
n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
|
|
3735
4403
|
n = applyRepeaterEffect(n, repeater, ctx);
|
|
3736
4404
|
n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
|
|
3737
4405
|
if (innerIdForContentRef) {
|
|
4406
|
+
applyRefHref(n, cloneFx, ctx);
|
|
3738
4407
|
n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
|
|
3739
4408
|
} else {
|
|
3740
|
-
n = applyRefAndTransformationEffect(n,
|
|
4409
|
+
n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);
|
|
3741
4410
|
}
|
|
3742
|
-
if (retime) node.effects = { retime };
|
|
4411
|
+
if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
|
|
3743
4412
|
if (originalId) ctx.idMap.set(originalId, n);
|
|
3744
4413
|
return n;
|
|
3745
4414
|
}
|
|
@@ -3756,13 +4425,30 @@ function materialiseAnimatedUseInstances(root) {
|
|
|
3756
4425
|
if (animatedIds.size === 0) return root;
|
|
3757
4426
|
let idCounter = 0;
|
|
3758
4427
|
const genId3 = () => "_lw_use_mat_" + ++idCounter;
|
|
4428
|
+
const rootViewport = readRootViewport(root);
|
|
3759
4429
|
const defsCollector = [];
|
|
3760
|
-
const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector);
|
|
4430
|
+
const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
3761
4431
|
if (defsCollector.length === 0) return walked;
|
|
3762
4432
|
const defsNode = { type: "defs", children: defsCollector };
|
|
3763
4433
|
const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
|
|
3764
4434
|
return __spreadProps(__spreadValues({}, walked), { children: newChildren });
|
|
3765
4435
|
}
|
|
4436
|
+
function readRootViewport(root) {
|
|
4437
|
+
const vb = parseViewBox(root.viewBox);
|
|
4438
|
+
if (vb) return [vb[2], vb[3]];
|
|
4439
|
+
const w = numericAttr(root.width);
|
|
4440
|
+
const h = numericAttr(root.height);
|
|
4441
|
+
if (w !== void 0 && h !== void 0) return [w, h];
|
|
4442
|
+
return [1, 1];
|
|
4443
|
+
}
|
|
4444
|
+
function numericAttr(v) {
|
|
4445
|
+
if (typeof v === "number") return v;
|
|
4446
|
+
if (typeof v === "string") {
|
|
4447
|
+
const n = parseFloat(v);
|
|
4448
|
+
return Number.isFinite(n) ? n : void 0;
|
|
4449
|
+
}
|
|
4450
|
+
return void 0;
|
|
4451
|
+
}
|
|
3766
4452
|
function buildIdMap(root) {
|
|
3767
4453
|
const map = /* @__PURE__ */ new Map();
|
|
3768
4454
|
const visit = (n) => {
|
|
@@ -3814,16 +4500,22 @@ function stripHash2(href) {
|
|
|
3814
4500
|
if (typeof href !== "string") return void 0;
|
|
3815
4501
|
return href.startsWith("#") ? href.slice(1) : href;
|
|
3816
4502
|
}
|
|
3817
|
-
function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector) {
|
|
4503
|
+
function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
|
|
4504
|
+
var _a, _b, _c, _d;
|
|
3818
4505
|
const clone2 = deepClonePxNode(target);
|
|
3819
4506
|
regenerateIdsAndRewriteRefs(clone2, genId3);
|
|
3820
|
-
const
|
|
3821
|
-
const
|
|
4507
|
+
const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
|
|
4508
|
+
const useW = (_b = (_a = numericAttr(useNode.width)) != null ? _a : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
|
|
4509
|
+
const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
|
|
4510
|
+
const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
|
|
4511
|
+
const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
3822
4512
|
const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materialisedClone] });
|
|
3823
4513
|
delete newNode.href;
|
|
4514
|
+
delete newNode.width;
|
|
4515
|
+
delete newNode.height;
|
|
3824
4516
|
return applyUseOffsetToG(newNode);
|
|
3825
4517
|
}
|
|
3826
|
-
function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector) {
|
|
4518
|
+
function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector, useW, useH) {
|
|
3827
4519
|
const viewBox = parseViewBox(symbolNode.viewBox);
|
|
3828
4520
|
const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
|
|
3829
4521
|
delete g.viewBox;
|
|
@@ -3832,9 +4524,14 @@ function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector) {
|
|
|
3832
4524
|
delete g.height;
|
|
3833
4525
|
if (!viewBox) return g;
|
|
3834
4526
|
const [vbX, vbY, vbW, vbH] = viewBox;
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
4527
|
+
const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;
|
|
4528
|
+
const xOff = (useW - vbW * scale) / 2;
|
|
4529
|
+
const yOff = (useH - vbH * scale) / 2;
|
|
4530
|
+
const parts = [];
|
|
4531
|
+
if (xOff !== 0 || yOff !== 0) parts.push("translate(" + xOff + "," + yOff + ")");
|
|
4532
|
+
if (scale !== 1) parts.push("scale(" + scale + ")");
|
|
4533
|
+
if (vbX !== 0 || vbY !== 0) parts.push("translate(" + -vbX + "," + -vbY + ")");
|
|
4534
|
+
if (parts.length) g.transform = parts.join("");
|
|
3838
4535
|
const clipId = genId3();
|
|
3839
4536
|
defsCollector.push({
|
|
3840
4537
|
type: "clipPath",
|
|
@@ -3850,18 +4547,18 @@ function parseViewBox(v) {
|
|
|
3850
4547
|
if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
|
|
3851
4548
|
return [parts[0], parts[1], parts[2], parts[3]];
|
|
3852
4549
|
}
|
|
3853
|
-
function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector) {
|
|
4550
|
+
function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
|
|
3854
4551
|
if (node.type === "use" && typeof node.href === "string") {
|
|
3855
4552
|
const targetId = stripHash2(node.href);
|
|
3856
4553
|
if (targetId && animatedIds.has(targetId)) {
|
|
3857
4554
|
const target = idMap.get(targetId);
|
|
3858
|
-
if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector);
|
|
4555
|
+
if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
3859
4556
|
}
|
|
3860
4557
|
}
|
|
3861
4558
|
if (!node.children) return node;
|
|
3862
4559
|
let changed = false;
|
|
3863
4560
|
const newChildren = node.children.map((ch) => {
|
|
3864
|
-
const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector);
|
|
4561
|
+
const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
3865
4562
|
if (m !== ch) changed = true;
|
|
3866
4563
|
return m;
|
|
3867
4564
|
});
|
|
@@ -3877,6 +4574,36 @@ function materialiseAllInTree(doc, engine, opts) {
|
|
|
3877
4574
|
if (engine === PxAnimatorEngine.webapi) {
|
|
3878
4575
|
root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
|
|
3879
4576
|
root = materialiseAnimatedUseInstances(root);
|
|
4577
|
+
root = pruneUnreferencedDefs(root);
|
|
4578
|
+
}
|
|
4579
|
+
return root;
|
|
4580
|
+
}
|
|
4581
|
+
function pruneUnreferencedDefs(root) {
|
|
4582
|
+
const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
|
|
4583
|
+
const walk = (n, fn) => {
|
|
4584
|
+
var _a;
|
|
4585
|
+
fn(n);
|
|
4586
|
+
(_a = n.children) == null ? void 0 : _a.forEach((c) => walk(c, fn));
|
|
4587
|
+
};
|
|
4588
|
+
let changed = true;
|
|
4589
|
+
while (changed) {
|
|
4590
|
+
changed = false;
|
|
4591
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
4592
|
+
walk(root, (n) => {
|
|
4593
|
+
if (n.type === "use" && typeof n.href === "string") referenced.add(stripHash3(n.href));
|
|
4594
|
+
});
|
|
4595
|
+
walk(root, (n) => {
|
|
4596
|
+
if (!n.children) return;
|
|
4597
|
+
let kept = n.children;
|
|
4598
|
+
if (n.type === "defs") {
|
|
4599
|
+
kept = kept.filter((c) => !((c.type === "g" || c.type === "symbol") && typeof c.id === "string" && !referenced.has(c.id)));
|
|
4600
|
+
}
|
|
4601
|
+
kept = kept.filter((c) => !(c.type === "defs" && (!c.children || c.children.length === 0)));
|
|
4602
|
+
if (kept.length !== n.children.length) {
|
|
4603
|
+
n.children = kept;
|
|
4604
|
+
changed = true;
|
|
4605
|
+
}
|
|
4606
|
+
});
|
|
3880
4607
|
}
|
|
3881
4608
|
return root;
|
|
3882
4609
|
}
|
|
@@ -3909,6 +4636,13 @@ var URL_VALUE_ATTRS_LOWER = /* @__PURE__ */ new Set([
|
|
|
3909
4636
|
]);
|
|
3910
4637
|
var IMAGE_REF_ATTRS_LOWER = /* @__PURE__ */ new Set(["href", "xlink:href", "src"]);
|
|
3911
4638
|
var DATA_RASTER_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,/i;
|
|
4639
|
+
var DATA_SVG_IMAGE_RE = /^data:image\/svg\+xml(?:;[^,]*)?,/i;
|
|
4640
|
+
var DATA_IMAGE_BASE64_PAYLOAD_RE = /^data:image\/[^;,]*;base64,([A-Za-z0-9+/]{8})/i;
|
|
4641
|
+
var BASE64_RASTER_MAGICS = ["iVBORw0K", "/9j/", "R0lGOD", "UklGR", "Qk"];
|
|
4642
|
+
function isContentSniffedRasterImage(str2) {
|
|
4643
|
+
const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(str2);
|
|
4644
|
+
return !!m && BASE64_RASTER_MAGICS.some((magic) => m[1].startsWith(magic));
|
|
4645
|
+
}
|
|
3912
4646
|
function isDangerousAttrName(nameLower) {
|
|
3913
4647
|
if (nameLower.startsWith("on")) return true;
|
|
3914
4648
|
return false;
|
|
@@ -3920,19 +4654,19 @@ function sanitiseAttributeValue(name, value) {
|
|
|
3920
4654
|
return void 0;
|
|
3921
4655
|
}
|
|
3922
4656
|
if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
|
|
3923
|
-
const
|
|
3924
|
-
if (
|
|
4657
|
+
const str2 = String(value);
|
|
4658
|
+
if (str2.includes("url(") && !/^url\(#[^)]+\)$/.test(str2)) {
|
|
3925
4659
|
console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
|
|
3926
4660
|
return void 0;
|
|
3927
4661
|
}
|
|
3928
4662
|
return value;
|
|
3929
4663
|
}
|
|
3930
4664
|
if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
|
|
3931
|
-
const
|
|
3932
|
-
if (
|
|
3933
|
-
if (/^url\(#[^)]+\)$/.test(
|
|
3934
|
-
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && DATA_RASTER_IMAGE_RE.test(
|
|
3935
|
-
console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or
|
|
4665
|
+
const str2 = String(value);
|
|
4666
|
+
if (str2.startsWith("#")) return value;
|
|
4667
|
+
if (/^url\(#[^)]+\)$/.test(str2)) return value;
|
|
4668
|
+
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(str2) || DATA_SVG_IMAGE_RE.test(str2) || isContentSniffedRasterImage(str2))) return value;
|
|
4669
|
+
console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or data:image/\u2026 URI, got:', value);
|
|
3936
4670
|
return void 0;
|
|
3937
4671
|
}
|
|
3938
4672
|
return value;
|
|
@@ -3961,7 +4695,7 @@ function createElement(tagName, normalisedProps, style, children, textContent) {
|
|
|
3961
4695
|
if (textContent) element.textContent = textContent;
|
|
3962
4696
|
return element;
|
|
3963
4697
|
}
|
|
3964
|
-
function
|
|
4698
|
+
function resolveStyle2(style, defs) {
|
|
3965
4699
|
var _a;
|
|
3966
4700
|
if (!style) return void 0;
|
|
3967
4701
|
if (typeof style === "string") {
|
|
@@ -3997,7 +4731,7 @@ function renderNode(node, defs) {
|
|
|
3997
4731
|
if (!node) return null;
|
|
3998
4732
|
const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
|
|
3999
4733
|
const nodeDefs = getDefs(node) || defs;
|
|
4000
|
-
const resolvedStyle =
|
|
4734
|
+
const resolvedStyle = resolveStyle2(style, nodeDefs);
|
|
4001
4735
|
let childElements;
|
|
4002
4736
|
if (children) {
|
|
4003
4737
|
for (const ch of children) {
|
|
@@ -5030,6 +5764,7 @@ function subtractMultiset(a, b) {
|
|
|
5030
5764
|
PxAttrValueSchema,
|
|
5031
5765
|
PxBezierPathSchema,
|
|
5032
5766
|
PxBindingSchema,
|
|
5767
|
+
PxCloneEffectSchema,
|
|
5033
5768
|
PxDefsSchema,
|
|
5034
5769
|
PxEasingOrRefSchema,
|
|
5035
5770
|
PxEffectsSchema,
|
|
@@ -5045,12 +5780,12 @@ function subtractMultiset(a, b) {
|
|
|
5045
5780
|
PxNodeBase,
|
|
5046
5781
|
PxNodeSchema,
|
|
5047
5782
|
PxPropertyAnimationSchema,
|
|
5048
|
-
PxRefEffectSchema,
|
|
5049
5783
|
PxRepeaterEffectSchema,
|
|
5050
5784
|
PxRetimeEffectSchema,
|
|
5051
5785
|
PxStrokeGradientEffectSchema,
|
|
5052
5786
|
PxSvgNodeExtra,
|
|
5053
5787
|
PxTextAlongPathEffectSchema,
|
|
5788
|
+
PxTextEffectSchema,
|
|
5054
5789
|
PxTransformPartsSchema,
|
|
5055
5790
|
PxTransformValueSchema,
|
|
5056
5791
|
PxTransformationEffectSchema,
|
|
@@ -5078,9 +5813,13 @@ function subtractMultiset(a, b) {
|
|
|
5078
5813
|
getNormalizedProps,
|
|
5079
5814
|
isPxElementFileFormat,
|
|
5080
5815
|
isPxElementFileFormatDeep,
|
|
5816
|
+
jsonElementFactory,
|
|
5081
5817
|
loadTagAnimators,
|
|
5082
5818
|
materialiseAllInTree,
|
|
5083
5819
|
materialiseAnimatedUseInstances,
|
|
5820
|
+
materialiseGlyphText,
|
|
5821
|
+
materialiseGlyphTextAlongPath,
|
|
5822
|
+
materialiseGlyphTextHorizontal,
|
|
5084
5823
|
materialiseInternalLoopsInPropAnim,
|
|
5085
5824
|
materialiseInternalLoopsInTree,
|
|
5086
5825
|
materialiseMotionPathInPropAnim,
|