@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.js
CHANGED
|
@@ -4,6 +4,7 @@ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __pow = Math.pow;
|
|
7
8
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
9
|
var __spreadValues = (a, b) => {
|
|
9
10
|
for (var prop in b || (b = {}))
|
|
@@ -45,7 +46,7 @@ function readAnimatable(raw) {
|
|
|
45
46
|
if (typeof raw === "object") {
|
|
46
47
|
const obj = raw;
|
|
47
48
|
if (obj.keyframes) {
|
|
48
|
-
return { kind: "animated" /* Animated */, keyframes: obj.keyframes, autoOrient: obj.autoOrient };
|
|
49
|
+
return { kind: "animated" /* Animated */, keyframes: obj.keyframes, autoOrient: obj.autoOrient, loop: obj.loop };
|
|
49
50
|
}
|
|
50
51
|
if (obj.value !== void 0) return { kind: "static" /* Static */, value: obj.value };
|
|
51
52
|
}
|
|
@@ -135,6 +136,7 @@ function wrapTransformPart(inner, part, raw, ctx) {
|
|
|
135
136
|
if (v.kind === "animated" /* Animated */) {
|
|
136
137
|
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
|
|
137
138
|
if (v.autoOrient) animTr.autoOrient = true;
|
|
139
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
138
140
|
return {
|
|
139
141
|
type: "g",
|
|
140
142
|
animate: { transform: animTr },
|
|
@@ -153,9 +155,11 @@ function wrapOrigin(inner, raw, invert) {
|
|
|
153
155
|
return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
|
|
154
156
|
}
|
|
155
157
|
if (v.kind === "animated" /* Animated */) {
|
|
158
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) };
|
|
159
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
156
160
|
return {
|
|
157
161
|
type: "g",
|
|
158
|
-
animate: { transform:
|
|
162
|
+
animate: { transform: animTr },
|
|
159
163
|
children: [inner]
|
|
160
164
|
};
|
|
161
165
|
}
|
|
@@ -165,8 +169,8 @@ function wrapOrigin(inner, raw, invert) {
|
|
|
165
169
|
// src/effects/contentRefSplit.ts
|
|
166
170
|
function identifyContentRefTargets(node, ctx, allocator) {
|
|
167
171
|
var _a, _b, _c;
|
|
168
|
-
if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.
|
|
169
|
-
const baseId = node.effects.
|
|
172
|
+
if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.type) === "content") {
|
|
173
|
+
const baseId = node.effects.clone.baseId;
|
|
170
174
|
if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
|
|
171
175
|
ctx.contentRefInnerIds.set(baseId, allocator(baseId));
|
|
172
176
|
}
|
|
@@ -214,6 +218,8 @@ function liftBodyTranslate(node, transformation) {
|
|
|
214
218
|
});
|
|
215
219
|
const outerAnimTr = { keyframes: outerKfs };
|
|
216
220
|
if (animTr.autoOrient) outerAnimTr.autoOrient = true;
|
|
221
|
+
const srcLoop = animTr.loop;
|
|
222
|
+
if (srcLoop !== void 0) outerAnimTr.loop = srcLoop;
|
|
217
223
|
out.animate = { transform: outerAnimTr };
|
|
218
224
|
const innerHasPivotedPart = kfs.some((kf) => {
|
|
219
225
|
const v = kf.value || {};
|
|
@@ -235,7 +241,9 @@ function liftBodyTranslate(node, transformation) {
|
|
|
235
241
|
delete node.animate.transform;
|
|
236
242
|
if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;
|
|
237
243
|
} else {
|
|
238
|
-
|
|
244
|
+
const innerAnimTr = { keyframes: innerKfs };
|
|
245
|
+
if (srcLoop !== void 0) innerAnimTr.loop = srcLoop;
|
|
246
|
+
node.animate.transform = innerAnimTr;
|
|
239
247
|
}
|
|
240
248
|
didLiftAnimate = true;
|
|
241
249
|
}
|
|
@@ -899,10 +907,22 @@ var PxTriggerSchema = implementsInterface()(px.object({
|
|
|
899
907
|
outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
|
|
900
908
|
scrollIntoViewThreshold: px.number().optional()
|
|
901
909
|
}));
|
|
910
|
+
var PxGlyphSchema = implementsInterface()(px.object({
|
|
911
|
+
width: px.number(),
|
|
912
|
+
d: px.string()
|
|
913
|
+
}));
|
|
914
|
+
var PxGlyphFontSchema = implementsInterface()(px.object({
|
|
915
|
+
fFamily: px.string(),
|
|
916
|
+
style: px.string(),
|
|
917
|
+
ascent: px.number(),
|
|
918
|
+
unitsPerEm: px.number(),
|
|
919
|
+
glyphs: px.record(PxGlyphSchema)
|
|
920
|
+
}));
|
|
902
921
|
var PxDefsSchema = implementsInterface()(px.object({
|
|
903
922
|
easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
|
|
904
923
|
animations: px.record(PxAnimationDefinitionSchema).optional(),
|
|
905
|
-
styles: px.record(px.any()).optional()
|
|
924
|
+
styles: px.record(px.any()).optional(),
|
|
925
|
+
glyphs: px.record(PxGlyphFontSchema).optional()
|
|
906
926
|
}));
|
|
907
927
|
var PxAnimatorConfigSchema = implementsInterface()(px.object({
|
|
908
928
|
mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
|
|
@@ -975,9 +995,10 @@ var PxRetimeEffectSchema = implementsInterface()(px.object({
|
|
|
975
995
|
stretch: px.number().optional(),
|
|
976
996
|
timeCrop: px.tuple([px.number(), px.number()]).optional()
|
|
977
997
|
}));
|
|
978
|
-
var
|
|
998
|
+
var PxCloneEffectSchema = implementsInterface()(px.object({
|
|
999
|
+
type: px.string().optional(),
|
|
979
1000
|
baseId: px.string().optional(),
|
|
980
|
-
|
|
1001
|
+
retime: PxRetimeEffectSchema.optional()
|
|
981
1002
|
}));
|
|
982
1003
|
var PxGradientUnits = {
|
|
983
1004
|
userSpaceOnUse: "userSpaceOnUse",
|
|
@@ -1022,17 +1043,20 @@ var PxTextAlongPathEffectSchema = implementsInterface()(px.object({
|
|
|
1022
1043
|
startOffset: PxAnimatableNumberSchema.optional(),
|
|
1023
1044
|
textLength: PxAnimatableNumberSchema.optional()
|
|
1024
1045
|
}));
|
|
1046
|
+
var PxTextEffectSchema = implementsInterface()(px.object({
|
|
1047
|
+
useGlyphs: px.boolean().optional()
|
|
1048
|
+
}));
|
|
1025
1049
|
var PxEffectsSchema = implementsInterface()(px.object({
|
|
1026
1050
|
transformation: PxTransformationEffectSchema.optional(),
|
|
1027
1051
|
repeater: PxRepeaterEffectSchema.optional(),
|
|
1028
1052
|
maskedBy: PxMaskedByEffectSchema.optional(),
|
|
1029
1053
|
trimPath: PxTrimPathEffectSchema.optional(),
|
|
1030
|
-
|
|
1054
|
+
clone: PxCloneEffectSchema.optional(),
|
|
1031
1055
|
isCombinedShape: px.boolean().optional(),
|
|
1032
|
-
ref: PxRefEffectSchema.optional(),
|
|
1033
1056
|
fillGradient: PxFillGradientEffectSchema.optional(),
|
|
1034
1057
|
strokeGradient: PxStrokeGradientEffectSchema.optional(),
|
|
1035
|
-
textAlongPath: PxTextAlongPathEffectSchema.optional()
|
|
1058
|
+
textAlongPath: PxTextAlongPathEffectSchema.optional(),
|
|
1059
|
+
text: PxTextEffectSchema.optional()
|
|
1036
1060
|
}));
|
|
1037
1061
|
function validateNodeEffects(root, opts) {
|
|
1038
1062
|
const warnings = [];
|
|
@@ -1257,6 +1281,7 @@ function buildStopChildren(stops, ctx) {
|
|
|
1257
1281
|
const animBlock = stops;
|
|
1258
1282
|
const kfs = animBlock.keyframes;
|
|
1259
1283
|
if (!Array.isArray(kfs) || !kfs.length) return [];
|
|
1284
|
+
const loopFromSource = animBlock.loop;
|
|
1260
1285
|
let stopCount = 0;
|
|
1261
1286
|
for (const kf of kfs) {
|
|
1262
1287
|
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
@@ -1269,7 +1294,7 @@ function buildStopChildren(stops, ctx) {
|
|
|
1269
1294
|
const s = (_d = (_c = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _c : prevDefinedStop(kfs, 0, i)) != null ? _d : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
|
|
1270
1295
|
baselineStops.push({ offset: s.offset, color: s.color });
|
|
1271
1296
|
}
|
|
1272
|
-
return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx));
|
|
1297
|
+
return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
|
|
1273
1298
|
}
|
|
1274
1299
|
function staticStopNode(s) {
|
|
1275
1300
|
return {
|
|
@@ -1278,7 +1303,7 @@ function staticStopNode(s) {
|
|
|
1278
1303
|
stopColor: s.color
|
|
1279
1304
|
};
|
|
1280
1305
|
}
|
|
1281
|
-
function animatedStopNode(baseline, kfs, stopIdx, _ctx) {
|
|
1306
|
+
function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
|
|
1282
1307
|
var _a, _b, _c, _d, _e;
|
|
1283
1308
|
const colorKfs = [];
|
|
1284
1309
|
const offsetKfs = [];
|
|
@@ -1303,8 +1328,14 @@ function animatedStopNode(baseline, kfs, stopIdx, _ctx) {
|
|
|
1303
1328
|
stopColor: baseline.color
|
|
1304
1329
|
};
|
|
1305
1330
|
const animate = {};
|
|
1306
|
-
if (colorKfs.length)
|
|
1307
|
-
|
|
1331
|
+
if (colorKfs.length) {
|
|
1332
|
+
animate.stopColor = { keyframes: colorKfs };
|
|
1333
|
+
if (loop !== void 0) animate.stopColor.loop = loop;
|
|
1334
|
+
}
|
|
1335
|
+
if (offsetVaries && offsetKfs.length) {
|
|
1336
|
+
animate.offset = { keyframes: offsetKfs };
|
|
1337
|
+
if (loop !== void 0) animate.offset.loop = loop;
|
|
1338
|
+
}
|
|
1308
1339
|
if (Object.keys(animate).length) stop.animate = animate;
|
|
1309
1340
|
return stop;
|
|
1310
1341
|
}
|
|
@@ -1369,9 +1400,11 @@ function wrapInversePart(inner, part, raw, origin, ctx) {
|
|
|
1369
1400
|
return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
|
|
1370
1401
|
}
|
|
1371
1402
|
if (v.kind === "animated" /* Animated */) {
|
|
1403
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) };
|
|
1404
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
1372
1405
|
return {
|
|
1373
1406
|
type: "g",
|
|
1374
|
-
animate: { transform:
|
|
1407
|
+
animate: { transform: animTr },
|
|
1375
1408
|
children: [inner]
|
|
1376
1409
|
};
|
|
1377
1410
|
}
|
|
@@ -1408,10 +1441,16 @@ function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
|
|
|
1408
1441
|
scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
1409
1442
|
}
|
|
1410
1443
|
}
|
|
1444
|
+
const srcLoop = animTr == null ? void 0 : animTr.loop;
|
|
1445
|
+
const withLoop = (kfs2) => {
|
|
1446
|
+
const block = { keyframes: kfs2 };
|
|
1447
|
+
if (srcLoop !== void 0) block.loop = srcLoop;
|
|
1448
|
+
return block;
|
|
1449
|
+
};
|
|
1411
1450
|
let n = inner;
|
|
1412
|
-
if (translateKfs.length) n = { type: "g", animate: { transform:
|
|
1413
|
-
if (rotateKfs.length) n = { type: "g", animate: { transform:
|
|
1414
|
-
if (scaleKfs.length) n = { type: "g", animate: { transform:
|
|
1451
|
+
if (translateKfs.length) n = { type: "g", animate: { transform: withLoop(translateKfs) }, children: [n] };
|
|
1452
|
+
if (rotateKfs.length) n = { type: "g", animate: { transform: withLoop(rotateKfs) }, children: [n] };
|
|
1453
|
+
if (scaleKfs.length) n = { type: "g", animate: { transform: withLoop(scaleKfs) }, children: [n] };
|
|
1415
1454
|
return n;
|
|
1416
1455
|
}
|
|
1417
1456
|
function nodeHasBodyTransform(node) {
|
|
@@ -1645,16 +1684,18 @@ function parseTranslateOnlyFromString(s, ctx) {
|
|
|
1645
1684
|
|
|
1646
1685
|
// src/effects/refEffect.ts
|
|
1647
1686
|
var CONTENT_SUBREF = "content";
|
|
1648
|
-
function
|
|
1649
|
-
if (
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
const targetId = ref.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
|
|
1655
|
-
node.href = "#" + targetId;
|
|
1656
|
-
}
|
|
1687
|
+
function applyRefHref(node, clone2, ctx) {
|
|
1688
|
+
if (!clone2) return;
|
|
1689
|
+
const baseId = clone2.baseId;
|
|
1690
|
+
if (!baseId) {
|
|
1691
|
+
if (clone2.type === CONTENT_SUBREF) ctx.errors.push("clone: content ref missing baseId");
|
|
1692
|
+
return;
|
|
1657
1693
|
}
|
|
1694
|
+
const targetId = clone2.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
|
|
1695
|
+
node.href = "#" + targetId;
|
|
1696
|
+
}
|
|
1697
|
+
function applyRefAndTransformationEffect(node, clone2, transformation, ctx) {
|
|
1698
|
+
applyRefHref(node, clone2, ctx);
|
|
1658
1699
|
return applyTransformationEffect(node, transformation, ctx);
|
|
1659
1700
|
}
|
|
1660
1701
|
|
|
@@ -1765,22 +1806,32 @@ function concatRetime(child, parent) {
|
|
|
1765
1806
|
stretch: parent.stretch * child.stretch
|
|
1766
1807
|
};
|
|
1767
1808
|
}
|
|
1768
|
-
function
|
|
1809
|
+
function readCloneRetime(n) {
|
|
1810
|
+
var _a, _b;
|
|
1811
|
+
return (_b = (_a = n.effects) == null ? void 0 : _a.clone) == null ? void 0 : _b.retime;
|
|
1812
|
+
}
|
|
1813
|
+
function clearCloneRetime(n) {
|
|
1769
1814
|
var _a;
|
|
1815
|
+
const clone2 = (_a = n.effects) == null ? void 0 : _a.clone;
|
|
1816
|
+
if (!clone2) return;
|
|
1817
|
+
delete clone2.retime;
|
|
1818
|
+
if (Object.keys(clone2).length === 0) delete n.effects.clone;
|
|
1819
|
+
if (n.effects && Object.keys(n.effects).length === 0) delete n.effects;
|
|
1820
|
+
}
|
|
1821
|
+
function applyAllRetimeEffects(root, ctx) {
|
|
1770
1822
|
ctx.idMap.clear();
|
|
1771
1823
|
indexById(root, ctx.idMap);
|
|
1772
1824
|
const sites = [];
|
|
1773
1825
|
const collect = (n) => {
|
|
1774
|
-
var
|
|
1775
|
-
if ((
|
|
1776
|
-
(
|
|
1826
|
+
var _a;
|
|
1827
|
+
if (readCloneRetime(n)) sites.push(n);
|
|
1828
|
+
(_a = n.children) == null ? void 0 : _a.forEach(collect);
|
|
1777
1829
|
};
|
|
1778
1830
|
collect(root);
|
|
1779
1831
|
for (const useNode of sites) {
|
|
1780
|
-
const retime = (
|
|
1832
|
+
const retime = readCloneRetime(useNode);
|
|
1781
1833
|
if (!retime) continue;
|
|
1782
|
-
|
|
1783
|
-
if (Object.keys(useNode.effects).length === 0) delete useNode.effects;
|
|
1834
|
+
clearCloneRetime(useNode);
|
|
1784
1835
|
materialiseRetime(useNode, asRetime(retime), ctx);
|
|
1785
1836
|
}
|
|
1786
1837
|
}
|
|
@@ -1804,7 +1855,6 @@ function materialiseRetime(useNode, retime, ctx) {
|
|
|
1804
1855
|
}
|
|
1805
1856
|
}
|
|
1806
1857
|
function buildChainClone(targetId, accum, ctx, chain) {
|
|
1807
|
-
var _a, _b;
|
|
1808
1858
|
if (chain.has(targetId)) {
|
|
1809
1859
|
ctx.errors.push('retime: loop via "' + targetId + '"');
|
|
1810
1860
|
return void 0;
|
|
@@ -1821,25 +1871,43 @@ function buildChainClone(targetId, accum, ctx, chain) {
|
|
|
1821
1871
|
} else {
|
|
1822
1872
|
remapKeyframeTimes(cloneNode, accum.start, accum.stretch);
|
|
1823
1873
|
}
|
|
1824
|
-
|
|
1825
|
-
delete cloneNode.effects.retime;
|
|
1826
|
-
if (Object.keys(cloneNode.effects).length === 0) delete cloneNode.effects;
|
|
1827
|
-
}
|
|
1874
|
+
clearCloneRetime(cloneNode);
|
|
1828
1875
|
if (target.type === "use" && target.href) {
|
|
1829
1876
|
const subId = stripHash(target.href);
|
|
1830
1877
|
if (subId) {
|
|
1831
|
-
const innerRetime = (
|
|
1878
|
+
const innerRetime = readCloneRetime(target);
|
|
1832
1879
|
const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
|
|
1833
1880
|
const subChain = new Set(chain);
|
|
1834
1881
|
subChain.add(targetId);
|
|
1835
1882
|
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
1836
1883
|
if (subId2) cloneNode.href = "#" + subId2;
|
|
1837
1884
|
}
|
|
1885
|
+
} else {
|
|
1886
|
+
materialiseNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
|
|
1838
1887
|
}
|
|
1839
1888
|
ctx.defs.push(cloneNode);
|
|
1840
1889
|
if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
|
|
1841
1890
|
return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
|
|
1842
1891
|
}
|
|
1892
|
+
function materialiseNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
|
|
1893
|
+
const visit = (n) => {
|
|
1894
|
+
var _a;
|
|
1895
|
+
const retime = readCloneRetime(n);
|
|
1896
|
+
if (n.type === "use" && retime && n.href) {
|
|
1897
|
+
const subId = stripHash(n.href);
|
|
1898
|
+
if (subId) {
|
|
1899
|
+
const subAccum = concatRetime(asRetime(retime), accum);
|
|
1900
|
+
const subChain = new Set(chain);
|
|
1901
|
+
subChain.add(parentTargetId);
|
|
1902
|
+
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
1903
|
+
if (subId2) n.href = "#" + subId2;
|
|
1904
|
+
}
|
|
1905
|
+
clearCloneRetime(n);
|
|
1906
|
+
}
|
|
1907
|
+
(_a = n.children) == null ? void 0 : _a.forEach(visit);
|
|
1908
|
+
};
|
|
1909
|
+
visit(node);
|
|
1910
|
+
}
|
|
1843
1911
|
function remapKeyframeTimes(node, start, stretch) {
|
|
1844
1912
|
var _a;
|
|
1845
1913
|
remapKeyframeTimesOnly(node, start, stretch);
|
|
@@ -1884,12 +1952,14 @@ function applyAnimatableNumber(node, attrName, raw) {
|
|
|
1884
1952
|
node[attrName] = String(raw);
|
|
1885
1953
|
return;
|
|
1886
1954
|
}
|
|
1887
|
-
if (typeof raw === "object") {
|
|
1955
|
+
if (typeof raw === "object" && raw !== null) {
|
|
1888
1956
|
const obj = raw;
|
|
1889
1957
|
if (Array.isArray(obj.keyframes)) {
|
|
1890
1958
|
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
1891
1959
|
const animate = __spreadValues({}, prevAnimate || {});
|
|
1892
|
-
|
|
1960
|
+
const block = { keyframes: obj.keyframes };
|
|
1961
|
+
if (obj.loop !== void 0) block.loop = obj.loop;
|
|
1962
|
+
animate[attrName] = block;
|
|
1893
1963
|
node.animate = animate;
|
|
1894
1964
|
return;
|
|
1895
1965
|
}
|
|
@@ -1900,6 +1970,61 @@ function applyAnimatableNumber(node, attrName, raw) {
|
|
|
1900
1970
|
}
|
|
1901
1971
|
}
|
|
1902
1972
|
|
|
1973
|
+
// src/effects/elementFactory.ts
|
|
1974
|
+
var jsonElementFactory = (type, props, children) => {
|
|
1975
|
+
const node = { type };
|
|
1976
|
+
for (const k in props) if (props[k] !== void 0) node[k] = props[k];
|
|
1977
|
+
const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
|
|
1978
|
+
if (arr.length) node.children = arr;
|
|
1979
|
+
return node;
|
|
1980
|
+
};
|
|
1981
|
+
|
|
1982
|
+
// src/effects/glyphPathBake.ts
|
|
1983
|
+
function fmt(v, decimals) {
|
|
1984
|
+
return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
|
|
1985
|
+
}
|
|
1986
|
+
function pack(nums, decimals) {
|
|
1987
|
+
let s = "";
|
|
1988
|
+
for (let i = 0; i < nums.length; i++) {
|
|
1989
|
+
const str2 = fmt(nums[i], decimals);
|
|
1990
|
+
if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
|
|
1991
|
+
s += str2;
|
|
1992
|
+
}
|
|
1993
|
+
return s;
|
|
1994
|
+
}
|
|
1995
|
+
function apply(m, x, y) {
|
|
1996
|
+
return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
|
|
1997
|
+
}
|
|
1998
|
+
var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
|
|
1999
|
+
function transformPathData(d, m, decimals = 2) {
|
|
2000
|
+
const tokens = [];
|
|
2001
|
+
let match;
|
|
2002
|
+
TOKEN_RE.lastIndex = 0;
|
|
2003
|
+
while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
|
|
2004
|
+
let out = "";
|
|
2005
|
+
let i = 0;
|
|
2006
|
+
const num2 = () => parseFloat(tokens[i++]);
|
|
2007
|
+
while (i < tokens.length) {
|
|
2008
|
+
const cmd = tokens[i++];
|
|
2009
|
+
if (cmd === "M" || cmd === "L") {
|
|
2010
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2011
|
+
out += cmd + pack([x, y], decimals);
|
|
2012
|
+
} else if (cmd === "C") {
|
|
2013
|
+
const [x1, y1] = apply(m, num2(), num2());
|
|
2014
|
+
const [x2, y2] = apply(m, num2(), num2());
|
|
2015
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2016
|
+
out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
|
|
2017
|
+
} else if (cmd === "Q") {
|
|
2018
|
+
const [x1, y1] = apply(m, num2(), num2());
|
|
2019
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2020
|
+
out += "Q" + pack([x1, y1, x, y], decimals);
|
|
2021
|
+
} else if (cmd === "Z" || cmd === "z") {
|
|
2022
|
+
out += "Z";
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
return out;
|
|
2026
|
+
}
|
|
2027
|
+
|
|
1903
2028
|
// src/PxAnimatorUtil.ts
|
|
1904
2029
|
function bezierToSvgPath(path) {
|
|
1905
2030
|
var _a, _b, _c, _d;
|
|
@@ -2272,6 +2397,24 @@ function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
|
|
|
2272
2397
|
}
|
|
2273
2398
|
return { ts, ds };
|
|
2274
2399
|
}
|
|
2400
|
+
function bezier2D_tForDistance(lut, distance) {
|
|
2401
|
+
const { ts, ds } = lut;
|
|
2402
|
+
const last = ds.length - 1;
|
|
2403
|
+
if (distance <= 0) return ts[0];
|
|
2404
|
+
if (distance >= ds[last]) return ts[last];
|
|
2405
|
+
let lo = 1;
|
|
2406
|
+
let hi = last;
|
|
2407
|
+
while (lo < hi) {
|
|
2408
|
+
const mid = lo + hi >>> 1;
|
|
2409
|
+
if (ds[mid] < distance) lo = mid + 1;
|
|
2410
|
+
else hi = mid;
|
|
2411
|
+
}
|
|
2412
|
+
const dPrev = ds[hi - 1];
|
|
2413
|
+
const dCur = ds[hi];
|
|
2414
|
+
const span = dCur - dPrev;
|
|
2415
|
+
const frac = span > 0 ? (distance - dPrev) / span : 0;
|
|
2416
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
2417
|
+
}
|
|
2275
2418
|
function bezier2D_arcAtT(lut, t) {
|
|
2276
2419
|
const { ts, ds } = lut;
|
|
2277
2420
|
const last = ts.length - 1;
|
|
@@ -2294,6 +2437,437 @@ function invertEasing(easing) {
|
|
|
2294
2437
|
return cubicBezier(flipped);
|
|
2295
2438
|
}
|
|
2296
2439
|
|
|
2440
|
+
// src/effects/pathSampler.ts
|
|
2441
|
+
var LUT_STEPS = 48;
|
|
2442
|
+
var CMD_RE = /[MmLlHhVvCcSsQqTtAaZz]/;
|
|
2443
|
+
function tokenize(d) {
|
|
2444
|
+
const tokens = [];
|
|
2445
|
+
const re = /([MmLlHhVvCcSsQqTtAaZz])|(-?\d*\.?\d+(?:[eE][-+]?\d+)?)/g;
|
|
2446
|
+
let m;
|
|
2447
|
+
while ((m = re.exec(d)) !== null) tokens.push(m[0]);
|
|
2448
|
+
return tokens;
|
|
2449
|
+
}
|
|
2450
|
+
function quadToCubic(P0, Qc, P3) {
|
|
2451
|
+
return {
|
|
2452
|
+
P1: [P0[0] + 2 / 3 * (Qc[0] - P0[0]), P0[1] + 2 / 3 * (Qc[1] - P0[1])],
|
|
2453
|
+
P2: [P3[0] + 2 / 3 * (Qc[0] - P3[0]), P3[1] + 2 / 3 * (Qc[1] - P3[1])]
|
|
2454
|
+
};
|
|
2455
|
+
}
|
|
2456
|
+
function parseCubics(d) {
|
|
2457
|
+
const tokens = tokenize(d);
|
|
2458
|
+
const segs = [];
|
|
2459
|
+
let i = 0;
|
|
2460
|
+
let cx = 0, cy = 0;
|
|
2461
|
+
let sx = 0, sy = 0;
|
|
2462
|
+
let pcx = 0, pcy = 0;
|
|
2463
|
+
let pqx = 0, pqy = 0;
|
|
2464
|
+
let prevCmd = "";
|
|
2465
|
+
const num2 = () => parseFloat(tokens[i++]);
|
|
2466
|
+
const push = (P1, P2, P3) => {
|
|
2467
|
+
const P0 = [cx, cy];
|
|
2468
|
+
const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);
|
|
2469
|
+
segs.push({ P0, P1, P2, P3, lut, len: lut.ds[lut.ds.length - 1] });
|
|
2470
|
+
cx = P3[0];
|
|
2471
|
+
cy = P3[1];
|
|
2472
|
+
};
|
|
2473
|
+
const pushLine = (x, y) => {
|
|
2474
|
+
push(
|
|
2475
|
+
[cx + (x - cx) / 3, cy + (y - cy) / 3],
|
|
2476
|
+
[cx + 2 * (x - cx) / 3, cy + 2 * (y - cy) / 3],
|
|
2477
|
+
[x, y]
|
|
2478
|
+
);
|
|
2479
|
+
};
|
|
2480
|
+
while (i < tokens.length) {
|
|
2481
|
+
let cmd = tokens[i];
|
|
2482
|
+
if (CMD_RE.test(cmd)) i++;
|
|
2483
|
+
else cmd = prevCmd === "M" ? "L" : prevCmd === "m" ? "l" : prevCmd;
|
|
2484
|
+
const rel = cmd >= "a";
|
|
2485
|
+
const U = cmd.toUpperCase();
|
|
2486
|
+
if (U === "Z") {
|
|
2487
|
+
pushLine(sx, sy);
|
|
2488
|
+
cx = sx;
|
|
2489
|
+
cy = sy;
|
|
2490
|
+
prevCmd = cmd;
|
|
2491
|
+
continue;
|
|
2492
|
+
}
|
|
2493
|
+
if (U === "M") {
|
|
2494
|
+
const x = num2() + (rel ? cx : 0), y = num2() + (rel ? cy : 0);
|
|
2495
|
+
cx = x;
|
|
2496
|
+
cy = y;
|
|
2497
|
+
sx = x;
|
|
2498
|
+
sy = y;
|
|
2499
|
+
prevCmd = cmd;
|
|
2500
|
+
continue;
|
|
2501
|
+
}
|
|
2502
|
+
if (U === "L") {
|
|
2503
|
+
pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
|
|
2504
|
+
} else if (U === "H") {
|
|
2505
|
+
pushLine(num2() + (rel ? cx : 0), cy);
|
|
2506
|
+
} else if (U === "V") {
|
|
2507
|
+
pushLine(cx, num2() + (rel ? cy : 0));
|
|
2508
|
+
} else if (U === "C") {
|
|
2509
|
+
const p1 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2510
|
+
const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2511
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2512
|
+
pcx = p2[0];
|
|
2513
|
+
pcy = p2[1];
|
|
2514
|
+
push(p1, p2, p3);
|
|
2515
|
+
} else if (U === "S") {
|
|
2516
|
+
const smooth = prevCmd.toUpperCase() === "C" || prevCmd.toUpperCase() === "S";
|
|
2517
|
+
const p1 = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];
|
|
2518
|
+
const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2519
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2520
|
+
pcx = p2[0];
|
|
2521
|
+
pcy = p2[1];
|
|
2522
|
+
push(p1, p2, p3);
|
|
2523
|
+
} else if (U === "Q") {
|
|
2524
|
+
const qc = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2525
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2526
|
+
pqx = qc[0];
|
|
2527
|
+
pqy = qc[1];
|
|
2528
|
+
const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
|
|
2529
|
+
push(P1, P2, p3);
|
|
2530
|
+
} else if (U === "T") {
|
|
2531
|
+
const smooth = prevCmd.toUpperCase() === "Q" || prevCmd.toUpperCase() === "T";
|
|
2532
|
+
const qc = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];
|
|
2533
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2534
|
+
pqx = qc[0];
|
|
2535
|
+
pqy = qc[1];
|
|
2536
|
+
const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
|
|
2537
|
+
push(P1, P2, p3);
|
|
2538
|
+
} else if (U === "A") {
|
|
2539
|
+
i += 5;
|
|
2540
|
+
pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
|
|
2541
|
+
} else {
|
|
2542
|
+
i++;
|
|
2543
|
+
continue;
|
|
2544
|
+
}
|
|
2545
|
+
prevCmd = cmd;
|
|
2546
|
+
}
|
|
2547
|
+
return segs.length ? segs : null;
|
|
2548
|
+
}
|
|
2549
|
+
function clamp2(v, lo, hi) {
|
|
2550
|
+
return v < lo ? lo : v > hi ? hi : v;
|
|
2551
|
+
}
|
|
2552
|
+
function createPathSampler(d) {
|
|
2553
|
+
const segs = parseCubics(d);
|
|
2554
|
+
if (!segs) return null;
|
|
2555
|
+
const cum = new Float64Array(segs.length + 1);
|
|
2556
|
+
for (let k = 0; k < segs.length; k++) cum[k + 1] = cum[k] + segs[k].len;
|
|
2557
|
+
const totalLength = cum[segs.length];
|
|
2558
|
+
const start = segs[0].P0, end = segs[segs.length - 1].P3;
|
|
2559
|
+
const closed = Math.hypot(end[0] - start[0], end[1] - start[1]) < 1e-3;
|
|
2560
|
+
const sampleOn = (dist) => {
|
|
2561
|
+
let k = 0;
|
|
2562
|
+
while (k < segs.length - 1 && dist > cum[k + 1]) k++;
|
|
2563
|
+
const seg = segs[k];
|
|
2564
|
+
const local = dist - cum[k];
|
|
2565
|
+
const t = seg.len > 0 ? bezier2D_tForDistance(seg.lut, local) : 0;
|
|
2566
|
+
const [x, y] = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2567
|
+
const [dx, dy] = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2568
|
+
return { x, y, angle: Math.atan2(dy, dx) };
|
|
2569
|
+
};
|
|
2570
|
+
return {
|
|
2571
|
+
totalLength,
|
|
2572
|
+
sampleAtDistance(dist) {
|
|
2573
|
+
if (!closed && (dist < 0 || dist > totalLength)) {
|
|
2574
|
+
const edge = dist < 0 ? 0 : totalLength;
|
|
2575
|
+
const p = sampleOn(edge);
|
|
2576
|
+
const over = dist - edge;
|
|
2577
|
+
return { x: p.x + Math.cos(p.angle) * over, y: p.y + Math.sin(p.angle) * over, angle: p.angle };
|
|
2578
|
+
}
|
|
2579
|
+
return sampleOn(clamp2(dist, 0, totalLength));
|
|
2580
|
+
}
|
|
2581
|
+
};
|
|
2582
|
+
}
|
|
2583
|
+
|
|
2584
|
+
// src/effects/textGlyphsEffect.ts
|
|
2585
|
+
var DEFAULT_FONT_SIZE = 16;
|
|
2586
|
+
var TEXT_ATTR_KEYS = [
|
|
2587
|
+
"fontFamily",
|
|
2588
|
+
"fontSize",
|
|
2589
|
+
"fontWeight",
|
|
2590
|
+
"fontStyle",
|
|
2591
|
+
"textAnchor",
|
|
2592
|
+
"letterSpacing",
|
|
2593
|
+
"wordSpacing",
|
|
2594
|
+
"textDecoration",
|
|
2595
|
+
"textTransform",
|
|
2596
|
+
"whiteSpace",
|
|
2597
|
+
"x",
|
|
2598
|
+
"y",
|
|
2599
|
+
"dx",
|
|
2600
|
+
"dy",
|
|
2601
|
+
"lengthAdjust",
|
|
2602
|
+
"fill",
|
|
2603
|
+
"stroke",
|
|
2604
|
+
"strokeWidth",
|
|
2605
|
+
"effects",
|
|
2606
|
+
TEXT_ATTR,
|
|
2607
|
+
TEXT_CONTENT_ATTR,
|
|
2608
|
+
"xml:space"
|
|
2609
|
+
];
|
|
2610
|
+
function parseLen(v) {
|
|
2611
|
+
if (typeof v === "number") return v;
|
|
2612
|
+
if (typeof v === "string") {
|
|
2613
|
+
const n = parseFloat(v);
|
|
2614
|
+
return isNaN(n) ? void 0 : n;
|
|
2615
|
+
}
|
|
2616
|
+
return void 0;
|
|
2617
|
+
}
|
|
2618
|
+
function str(v) {
|
|
2619
|
+
return typeof v === "string" ? v : void 0;
|
|
2620
|
+
}
|
|
2621
|
+
function resolveStyle(node, parent) {
|
|
2622
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2623
|
+
return {
|
|
2624
|
+
fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
|
|
2625
|
+
fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
|
|
2626
|
+
fill: (_c = node.fill) != null ? _c : parent.fill,
|
|
2627
|
+
stroke: (_d = node.stroke) != null ? _d : parent.stroke,
|
|
2628
|
+
strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
|
|
2629
|
+
letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
|
|
2630
|
+
wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing
|
|
2631
|
+
};
|
|
2632
|
+
}
|
|
2633
|
+
function rootStyleOf(node) {
|
|
2634
|
+
var _a, _b, _c;
|
|
2635
|
+
return {
|
|
2636
|
+
fontFamily: str(node.fontFamily),
|
|
2637
|
+
fontSize: (_a = parseLen(node.fontSize)) != null ? _a : DEFAULT_FONT_SIZE,
|
|
2638
|
+
fill: node.fill,
|
|
2639
|
+
stroke: node.stroke,
|
|
2640
|
+
strokeWidth: node.strokeWidth,
|
|
2641
|
+
letterSpacing: (_b = parseLen(node.letterSpacing)) != null ? _b : 0,
|
|
2642
|
+
wordSpacing: (_c = parseLen(node.wordSpacing)) != null ? _c : 0
|
|
2643
|
+
};
|
|
2644
|
+
}
|
|
2645
|
+
function paintOf(s) {
|
|
2646
|
+
const p = {};
|
|
2647
|
+
if (s.fill !== void 0) p.fill = s.fill;
|
|
2648
|
+
if (s.stroke !== void 0) p.stroke = s.stroke;
|
|
2649
|
+
if (s.strokeWidth !== void 0) p.strokeWidth = s.strokeWidth;
|
|
2650
|
+
return p;
|
|
2651
|
+
}
|
|
2652
|
+
function glyphFontFor(s, glyphs, soleFont, warnings) {
|
|
2653
|
+
var _a;
|
|
2654
|
+
const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
|
|
2655
|
+
if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a = s.fontFamily) != null ? _a : "") + '"');
|
|
2656
|
+
return gf;
|
|
2657
|
+
}
|
|
2658
|
+
function soleFontOf(glyphs) {
|
|
2659
|
+
const names = Object.keys(glyphs);
|
|
2660
|
+
return names.length === 1 ? glyphs[names[0]] : void 0;
|
|
2661
|
+
}
|
|
2662
|
+
function materialiseGlyphTextHorizontal(node, opts) {
|
|
2663
|
+
var _a, _b, _c, _d;
|
|
2664
|
+
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
2665
|
+
const soleFont = soleFontOf(glyphs);
|
|
2666
|
+
const pen = { x: (_a = parseLen(node.x)) != null ? _a : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
|
|
2667
|
+
const placements = [];
|
|
2668
|
+
const lines = [{ start: pen.x, end: pen.x }];
|
|
2669
|
+
let line = 0;
|
|
2670
|
+
const renderChars = (content, s) => {
|
|
2671
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2672
|
+
if (!gf) return;
|
|
2673
|
+
const scale = s.fontSize / gf.unitsPerEm;
|
|
2674
|
+
const paint = paintOf(s);
|
|
2675
|
+
for (let i = 0; i < content.length; i++) {
|
|
2676
|
+
const ch = content.charAt(i);
|
|
2677
|
+
const g = gf.glyphs[ch];
|
|
2678
|
+
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 });
|
|
2679
|
+
pen.x += (g ? g.width : 0) * scale + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2680
|
+
lines[line].end = pen.x;
|
|
2681
|
+
}
|
|
2682
|
+
};
|
|
2683
|
+
const walk = (el, parentStyle) => {
|
|
2684
|
+
var _a2, _b2, _c2, _d2;
|
|
2685
|
+
const s = resolveStyle(el, parentStyle);
|
|
2686
|
+
const x = parseLen(el.x);
|
|
2687
|
+
const y = parseLen(el.y);
|
|
2688
|
+
if (x !== void 0) {
|
|
2689
|
+
pen.x = x;
|
|
2690
|
+
line = lines.length;
|
|
2691
|
+
lines.push({ start: pen.x, end: pen.x });
|
|
2692
|
+
}
|
|
2693
|
+
if (y !== void 0) pen.y = y;
|
|
2694
|
+
pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
|
|
2695
|
+
pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
|
|
2696
|
+
const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
|
|
2697
|
+
if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
|
|
2698
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2699
|
+
};
|
|
2700
|
+
const rootStyle = rootStyleOf(node);
|
|
2701
|
+
if (node.children) for (const ch of node.children) walk(ch, rootStyle);
|
|
2702
|
+
const rootContent = (_c = str(node[TEXT_ATTR])) != null ? _c : str(node[TEXT_CONTENT_ATTR]);
|
|
2703
|
+
if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
|
|
2704
|
+
const anchor = str(node.textAnchor);
|
|
2705
|
+
if (anchor === "middle" || anchor === "end") {
|
|
2706
|
+
for (const p of placements) {
|
|
2707
|
+
const w = lines[p.line].end - lines[p.line].start;
|
|
2708
|
+
const shift = anchor === "middle" ? -w / 2 : -w;
|
|
2709
|
+
p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
2713
|
+
}
|
|
2714
|
+
function collectAlongPathCells(node, glyphs, soleFont, warnings) {
|
|
2715
|
+
const cells = [];
|
|
2716
|
+
let adv = 0;
|
|
2717
|
+
const walk = (el, parentStyle) => {
|
|
2718
|
+
var _a, _b;
|
|
2719
|
+
const s = resolveStyle(el, parentStyle);
|
|
2720
|
+
const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
|
|
2721
|
+
if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
|
|
2722
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2723
|
+
if (gf) {
|
|
2724
|
+
const scale = s.fontSize / gf.unitsPerEm;
|
|
2725
|
+
const paint = paintOf(s);
|
|
2726
|
+
for (let i = 0; i < content.length; i++) {
|
|
2727
|
+
const ch = content.charAt(i);
|
|
2728
|
+
const g = gf.glyphs[ch];
|
|
2729
|
+
const glyphAdv = (g ? g.width : 0) * scale;
|
|
2730
|
+
if (g && g.d) cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
|
|
2731
|
+
adv += glyphAdv + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2736
|
+
};
|
|
2737
|
+
walk(node, rootStyleOf(node));
|
|
2738
|
+
return { cells, width: adv };
|
|
2739
|
+
}
|
|
2740
|
+
function alongAffine(sampler, dist, scale, widthEm) {
|
|
2741
|
+
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
2742
|
+
const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;
|
|
2743
|
+
return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw, y - scale * sin * hw];
|
|
2744
|
+
}
|
|
2745
|
+
function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength) {
|
|
2746
|
+
var _a;
|
|
2747
|
+
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
2748
|
+
const sampler = pathD ? createPathSampler(pathD) : null;
|
|
2749
|
+
if (!sampler) {
|
|
2750
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry");
|
|
2751
|
+
return null;
|
|
2752
|
+
}
|
|
2753
|
+
const soleFont = soleFontOf(glyphs);
|
|
2754
|
+
const { cells, width } = collectAlongPathCells(node, glyphs, soleFont, warnings);
|
|
2755
|
+
if (!cells.length) return toGroup(node, [], create);
|
|
2756
|
+
if (textLength && textLength > 0 && width > 0) {
|
|
2757
|
+
const k = textLength / width;
|
|
2758
|
+
for (const c of cells) c.midBase *= k;
|
|
2759
|
+
}
|
|
2760
|
+
const so = readAnimatable(startOffset);
|
|
2761
|
+
if (so.kind === "animated" /* Animated */ && so.keyframes.length >= 2) {
|
|
2762
|
+
return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create), create);
|
|
2763
|
+
}
|
|
2764
|
+
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;
|
|
2765
|
+
const placements = cells.map((c) => ({
|
|
2766
|
+
glyphD: c.glyphD,
|
|
2767
|
+
paint: c.paint,
|
|
2768
|
+
m: alongAffine(sampler, base + c.midBase, c.scale, c.widthEm)
|
|
2769
|
+
}));
|
|
2770
|
+
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
2771
|
+
}
|
|
2772
|
+
var ALONG_PATH_MAX_STEPS = 48;
|
|
2773
|
+
var ALONG_PATH_MAX_STEPS_PER_SEGMENT = 64;
|
|
2774
|
+
function roundN(v, n) {
|
|
2775
|
+
const f = __pow(10, n);
|
|
2776
|
+
return Math.round(v * f) / f;
|
|
2777
|
+
}
|
|
2778
|
+
function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create) {
|
|
2779
|
+
const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);
|
|
2780
|
+
const timeOf = (kf) => Number(kf.time) || 0;
|
|
2781
|
+
const offOf = (kf) => Number(kf.value) || 0;
|
|
2782
|
+
const out = [];
|
|
2783
|
+
for (const c of cells) {
|
|
2784
|
+
const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
|
|
2785
|
+
const d = transformPathData(c.glyphD, centred);
|
|
2786
|
+
const sampleKf = (dist, time) => {
|
|
2787
|
+
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
2788
|
+
return {
|
|
2789
|
+
time,
|
|
2790
|
+
value: {
|
|
2791
|
+
["translate" /* Translate */]: [roundN(x, 3), roundN(y, 3)],
|
|
2792
|
+
["rotate" /* Rotate */]: roundN(angle * 180 / Math.PI, 3)
|
|
2793
|
+
}
|
|
2794
|
+
};
|
|
2795
|
+
};
|
|
2796
|
+
const kfs = [sampleKf(offOf(sokfs[0]) + c.midBase, timeOf(sokfs[0]))];
|
|
2797
|
+
for (let k = 1; k < sokfs.length; k++) {
|
|
2798
|
+
const t0 = timeOf(sokfs[k - 1]), t1 = timeOf(sokfs[k]);
|
|
2799
|
+
const o0 = offOf(sokfs[k - 1]), o1 = offOf(sokfs[k]);
|
|
2800
|
+
const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(o1 - o0) / step)));
|
|
2801
|
+
for (let s = 1; s <= n; s++) {
|
|
2802
|
+
const f = s / n;
|
|
2803
|
+
kfs.push(sampleKf(o0 + f * (o1 - o0) + c.midBase, t0 + f * (t1 - t0)));
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
const transform = { keyframes: kfs };
|
|
2807
|
+
if (loop !== void 0) transform.loop = loop;
|
|
2808
|
+
out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate: { transform } }), []));
|
|
2809
|
+
}
|
|
2810
|
+
return out;
|
|
2811
|
+
}
|
|
2812
|
+
function paintProps(paint) {
|
|
2813
|
+
const p = {};
|
|
2814
|
+
if (paint.fill !== void 0) p.fill = paint.fill;
|
|
2815
|
+
if (paint.stroke !== void 0) p.stroke = paint.stroke;
|
|
2816
|
+
if (paint.strokeWidth !== void 0) p.strokeWidth = paint.strokeWidth;
|
|
2817
|
+
return p;
|
|
2818
|
+
}
|
|
2819
|
+
function buildPaths(placements, create, warnings) {
|
|
2820
|
+
var _a, _b, _c;
|
|
2821
|
+
if (!placements.length) {
|
|
2822
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
|
|
2823
|
+
return [];
|
|
2824
|
+
}
|
|
2825
|
+
const byPaint = /* @__PURE__ */ new Map();
|
|
2826
|
+
for (const p of placements) {
|
|
2827
|
+
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]);
|
|
2828
|
+
const baked = transformPathData(p.glyphD, p.m);
|
|
2829
|
+
const entry = byPaint.get(key);
|
|
2830
|
+
if (entry) entry.d += baked;
|
|
2831
|
+
else byPaint.set(key, { paint: p.paint, d: baked });
|
|
2832
|
+
}
|
|
2833
|
+
const out = [];
|
|
2834
|
+
for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues({ d }, paintProps(paint)), []));
|
|
2835
|
+
return out;
|
|
2836
|
+
}
|
|
2837
|
+
function toGroup(node, children, create) {
|
|
2838
|
+
const gProps = {};
|
|
2839
|
+
for (const k of Object.keys(node)) {
|
|
2840
|
+
if (k === "type" || k === "children" || TEXT_ATTR_KEYS.indexOf(k) !== -1) continue;
|
|
2841
|
+
gProps[k] = node[k];
|
|
2842
|
+
}
|
|
2843
|
+
if (gProps.style && typeof gProps.style === "object") {
|
|
2844
|
+
const style = __spreadValues({}, gProps.style);
|
|
2845
|
+
delete style["white-space"];
|
|
2846
|
+
if (Object.keys(style).length) gProps.style = style;
|
|
2847
|
+
else delete gProps.style;
|
|
2848
|
+
}
|
|
2849
|
+
return create("g", gProps, children);
|
|
2850
|
+
}
|
|
2851
|
+
function materialiseGlyphText(node, opts) {
|
|
2852
|
+
if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength);
|
|
2853
|
+
return materialiseGlyphTextHorizontal(node, opts);
|
|
2854
|
+
}
|
|
2855
|
+
function applyTextGlyphsEffect(node, fx, ctx) {
|
|
2856
|
+
if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
|
|
2857
|
+
if (!ctx.glyphs) {
|
|
2858
|
+
ctx.warnings.push("textGlyphs: no definitions.glyphs \u2014 left as native <text>");
|
|
2859
|
+
return node;
|
|
2860
|
+
}
|
|
2861
|
+
return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
|
|
2862
|
+
}
|
|
2863
|
+
function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength) {
|
|
2864
|
+
if (!ctx.glyphs) {
|
|
2865
|
+
ctx.warnings.push("textGlyphs: no definitions.glyphs");
|
|
2866
|
+
return null;
|
|
2867
|
+
}
|
|
2868
|
+
return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength);
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2297
2871
|
// src/PxMotionPath.ts
|
|
2298
2872
|
function getKfTranslate(kf) {
|
|
2299
2873
|
var _a;
|
|
@@ -2737,12 +3311,12 @@ function parseSvgPathToBezier(d) {
|
|
|
2737
3311
|
}
|
|
2738
3312
|
return res;
|
|
2739
3313
|
}
|
|
2740
|
-
function extractPathData(
|
|
2741
|
-
if (
|
|
2742
|
-
return
|
|
3314
|
+
function extractPathData(str2) {
|
|
3315
|
+
if (str2.startsWith("path(") && str2.endsWith(")")) {
|
|
3316
|
+
return str2.slice(5, -1);
|
|
2743
3317
|
}
|
|
2744
|
-
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(
|
|
2745
|
-
return
|
|
3318
|
+
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str2)) {
|
|
3319
|
+
return str2;
|
|
2746
3320
|
}
|
|
2747
3321
|
return void 0;
|
|
2748
3322
|
}
|
|
@@ -2952,16 +3526,67 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
|
2952
3526
|
looped.push(pushed);
|
|
2953
3527
|
}
|
|
2954
3528
|
}
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
3529
|
+
function appendRepTail(repStart, isReversed, tailFraction) {
|
|
3530
|
+
let entries;
|
|
3531
|
+
if (isReversed) {
|
|
3532
|
+
entries = [];
|
|
3533
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
3534
|
+
entries.push({
|
|
3535
|
+
relT: 1 - template[i].relT,
|
|
3536
|
+
v: template[i].v,
|
|
3537
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
3538
|
+
tangentIn: template[i].tangentOut,
|
|
3539
|
+
tangentOut: template[i].tangentIn
|
|
3540
|
+
});
|
|
3541
|
+
}
|
|
3542
|
+
} else {
|
|
3543
|
+
entries = template;
|
|
3544
|
+
}
|
|
3545
|
+
const startRelT = 1 - tailFraction;
|
|
3546
|
+
for (let i = 0; i < entries.length; i++) {
|
|
3547
|
+
const entry = entries[i];
|
|
3548
|
+
if (entry.relT < startRelT - 1e-9) continue;
|
|
3549
|
+
const prev = entries[i - 1];
|
|
3550
|
+
if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {
|
|
3551
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
3552
|
+
const localFrac = (startRelT - prev.relT) / intervalSpan;
|
|
3553
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
3554
|
+
const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
3555
|
+
const { right: rightEasing } = splitEasing(prev.e, localFrac);
|
|
3556
|
+
looped.push({ t: repStart, v: startValue, e: rightEasing });
|
|
3557
|
+
}
|
|
3558
|
+
const pushed = {
|
|
3559
|
+
t: repStart + (entry.relT - startRelT) * segDuration,
|
|
3560
|
+
v: entry.v,
|
|
3561
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
3562
|
+
};
|
|
3563
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
3564
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
3565
|
+
looped.push(pushed);
|
|
3566
|
+
}
|
|
2960
3567
|
}
|
|
2961
|
-
if (
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
3568
|
+
if (loop.before) {
|
|
3569
|
+
if (partialFraction > 1e-9) {
|
|
3570
|
+
const isReversed = !!loop.alternate && fullReps % 2 === 0;
|
|
3571
|
+
appendRepTail(fillStart, isReversed, partialFraction);
|
|
3572
|
+
}
|
|
3573
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
3574
|
+
const distFromBoundary = fullReps - 1 - rep;
|
|
3575
|
+
const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
|
|
3576
|
+
const repStart = fillStart + remainder + rep * segDuration;
|
|
3577
|
+
appendRep(repStart, isReversed);
|
|
3578
|
+
}
|
|
3579
|
+
} else {
|
|
3580
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
3581
|
+
const isReversed = !!loop.alternate && rep % 2 === 0;
|
|
3582
|
+
const repStart = fillStart + rep * segDuration;
|
|
3583
|
+
appendRep(repStart, isReversed);
|
|
3584
|
+
}
|
|
3585
|
+
if (partialFraction > 1e-9) {
|
|
3586
|
+
const isReversed = !!loop.alternate && fullReps % 2 === 0;
|
|
3587
|
+
const repStart = fillStart + fullReps * segDuration;
|
|
3588
|
+
appendRep(repStart, isReversed, partialFraction);
|
|
3589
|
+
}
|
|
2965
3590
|
}
|
|
2966
3591
|
if (loop.before) {
|
|
2967
3592
|
return [...looped, ...keyframes];
|
|
@@ -3280,7 +3905,6 @@ function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
|
|
|
3280
3905
|
if (!trimPath) return node;
|
|
3281
3906
|
const trimAllAsOne = !!trimPath.trimAllAsOne;
|
|
3282
3907
|
const leafEntries = [];
|
|
3283
|
-
let acc = 0;
|
|
3284
3908
|
const measure = (n) => {
|
|
3285
3909
|
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
3286
3910
|
for (const ch of n.children) measure(ch);
|
|
@@ -3292,15 +3916,22 @@ function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
|
|
|
3292
3916
|
if (!subpaths.length) return;
|
|
3293
3917
|
const entry = { leaf: n, subpaths: [] };
|
|
3294
3918
|
for (const sp of subpaths) {
|
|
3295
|
-
if (!trimAllAsOne) acc = 0;
|
|
3296
3919
|
const lengthPx = pxBezierPathLength(sp);
|
|
3297
|
-
entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx:
|
|
3298
|
-
acc += lengthPx;
|
|
3920
|
+
entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: 0 });
|
|
3299
3921
|
}
|
|
3300
3922
|
leafEntries.push(entry);
|
|
3301
3923
|
};
|
|
3302
3924
|
measure(node);
|
|
3303
3925
|
if (!leafEntries.length) return node;
|
|
3926
|
+
let acc = 0;
|
|
3927
|
+
const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;
|
|
3928
|
+
for (const entry of iterOrder) {
|
|
3929
|
+
for (const sp of entry.subpaths) {
|
|
3930
|
+
if (!trimAllAsOne) acc = 0;
|
|
3931
|
+
sp.startOffsetPx = acc;
|
|
3932
|
+
acc += sp.lengthPx;
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3304
3935
|
const chainLengthPx = acc;
|
|
3305
3936
|
if (trimAllAsOne && chainLengthPx < 1e-3) return node;
|
|
3306
3937
|
const offsetReadRaw = readAnimatable(trimPath.offset);
|
|
@@ -3427,10 +4058,12 @@ function computeAnimAttr(read, map) {
|
|
|
3427
4058
|
value: map((_c = kf.value) != null ? _c : kf.v),
|
|
3428
4059
|
easing: (_d = kf.easing) != null ? _d : kf.e
|
|
3429
4060
|
};
|
|
3430
|
-
})
|
|
4061
|
+
}),
|
|
4062
|
+
loop: read.loop
|
|
3431
4063
|
};
|
|
3432
4064
|
}
|
|
3433
4065
|
function applyAttr(node, attrName, attr) {
|
|
4066
|
+
var _a, _b;
|
|
3434
4067
|
if (!attr) return;
|
|
3435
4068
|
if (attr.kind === "static" /* Static */) {
|
|
3436
4069
|
node[attrName] = attr.value;
|
|
@@ -3438,9 +4071,16 @@ function applyAttr(node, attrName, attr) {
|
|
|
3438
4071
|
}
|
|
3439
4072
|
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
3440
4073
|
const animate = __spreadValues({}, prevAnimate || {});
|
|
3441
|
-
|
|
4074
|
+
const block = { keyframes: attr.keyframes };
|
|
4075
|
+
if (attr.loop !== void 0) block.loop = attr.loop;
|
|
4076
|
+
animate[attrName] = block;
|
|
3442
4077
|
node.animate = animate;
|
|
4078
|
+
const firstKf = attr.keyframes[0];
|
|
4079
|
+
if (firstKf && ((_a = firstKf.value) != null ? _a : firstKf.v) !== void 0) {
|
|
4080
|
+
node[attrName] = (_b = firstKf.value) != null ? _b : firstKf.v;
|
|
4081
|
+
}
|
|
3443
4082
|
}
|
|
4083
|
+
var OPACITY_STEP_MS = 10;
|
|
3444
4084
|
function computeOpacityFromRange(rangeRead) {
|
|
3445
4085
|
var _a, _b, _c, _d, _e, _f;
|
|
3446
4086
|
const hide = (v) => v[0] === v[1];
|
|
@@ -3466,9 +4106,9 @@ function computeOpacityFromRange(rangeRead) {
|
|
|
3466
4106
|
const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
|
|
3467
4107
|
if (prevHide && !nextHide) {
|
|
3468
4108
|
out.push({ time: t, value: 0 });
|
|
3469
|
-
out.push({ time: t +
|
|
4109
|
+
out.push({ time: t + OPACITY_STEP_MS, value: 1 });
|
|
3470
4110
|
} else if (!prevHide && nextHide) {
|
|
3471
|
-
out.push({ time: t -
|
|
4111
|
+
out.push({ time: t - OPACITY_STEP_MS, value: 1 });
|
|
3472
4112
|
out.push({ time: t, value: 0 });
|
|
3473
4113
|
}
|
|
3474
4114
|
}
|
|
@@ -3601,6 +4241,7 @@ function rectToPathD(node) {
|
|
|
3601
4241
|
|
|
3602
4242
|
// src/effects/PlayerEffectsUtil.ts
|
|
3603
4243
|
function applyPlayerEffects(root) {
|
|
4244
|
+
var _a, _b;
|
|
3604
4245
|
const ctx = {
|
|
3605
4246
|
defs: [],
|
|
3606
4247
|
warnings: [],
|
|
@@ -3608,7 +4249,11 @@ function applyPlayerEffects(root) {
|
|
|
3608
4249
|
idMap: /* @__PURE__ */ new Map(),
|
|
3609
4250
|
nextId: 0,
|
|
3610
4251
|
contentRefInnerIds: /* @__PURE__ */ new Map(),
|
|
3611
|
-
maskAncestorChains: /* @__PURE__ */ new Map()
|
|
4252
|
+
maskAncestorChains: /* @__PURE__ */ new Map(),
|
|
4253
|
+
// Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →
|
|
4254
|
+
// webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
|
|
4255
|
+
engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi,
|
|
4256
|
+
glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
|
|
3612
4257
|
};
|
|
3613
4258
|
const working = clone(root);
|
|
3614
4259
|
indexById(working, ctx.idMap);
|
|
@@ -3620,27 +4265,46 @@ function applyPlayerEffects(root) {
|
|
|
3620
4265
|
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
3621
4266
|
}
|
|
3622
4267
|
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
4268
|
+
var _a;
|
|
3623
4269
|
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
3624
4270
|
const fx = node.effects;
|
|
3625
4271
|
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
3626
4272
|
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
3627
4273
|
if (!fx && !innerIdForContentRef) return node;
|
|
3628
|
-
const { transformation, repeater, maskedBy, trimPath,
|
|
4274
|
+
const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textAlongPath, text } = fx != null ? fx : {};
|
|
3629
4275
|
const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
|
|
3630
4276
|
if (fx) delete node.effects;
|
|
3631
4277
|
let n = node;
|
|
3632
|
-
|
|
4278
|
+
let consumedByGlyphs = false;
|
|
4279
|
+
if (text == null ? void 0 : text.useGlyphs) {
|
|
4280
|
+
if (textAlongPath) {
|
|
4281
|
+
const pathNode = typeof textAlongPath.href === "string" ? ctx.idMap.get(textAlongPath.href) : void 0;
|
|
4282
|
+
const pathD = pathNode && typeof pathNode.d === "string" ? pathNode.d : void 0;
|
|
4283
|
+
const rawTL = textAlongPath.textLength;
|
|
4284
|
+
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;
|
|
4285
|
+
const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textAlongPath.startOffset, textLength);
|
|
4286
|
+
if (glyphed) {
|
|
4287
|
+
n = glyphed;
|
|
4288
|
+
consumedByGlyphs = true;
|
|
4289
|
+
}
|
|
4290
|
+
} else {
|
|
4291
|
+
n = applyTextGlyphsEffect(n, text, ctx);
|
|
4292
|
+
consumedByGlyphs = true;
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
4295
|
+
if (!consumedByGlyphs) n = applyTextAlongPathEffect(n, textAlongPath, ctx);
|
|
3633
4296
|
n = applyFillGradientEffect(n, fillGradient, ctx);
|
|
3634
4297
|
n = applyStrokeGradientEffect(n, strokeGradient, ctx);
|
|
3635
4298
|
n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
|
|
3636
4299
|
n = applyRepeaterEffect(n, repeater, ctx);
|
|
3637
4300
|
n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
|
|
3638
4301
|
if (innerIdForContentRef) {
|
|
4302
|
+
applyRefHref(n, cloneFx, ctx);
|
|
3639
4303
|
n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
|
|
3640
4304
|
} else {
|
|
3641
|
-
n = applyRefAndTransformationEffect(n,
|
|
4305
|
+
n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);
|
|
3642
4306
|
}
|
|
3643
|
-
if (retime) node.effects = { retime };
|
|
4307
|
+
if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
|
|
3644
4308
|
if (originalId) ctx.idMap.set(originalId, n);
|
|
3645
4309
|
return n;
|
|
3646
4310
|
}
|
|
@@ -3657,13 +4321,30 @@ function materialiseAnimatedUseInstances(root) {
|
|
|
3657
4321
|
if (animatedIds.size === 0) return root;
|
|
3658
4322
|
let idCounter = 0;
|
|
3659
4323
|
const genId3 = () => "_lw_use_mat_" + ++idCounter;
|
|
4324
|
+
const rootViewport = readRootViewport(root);
|
|
3660
4325
|
const defsCollector = [];
|
|
3661
|
-
const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector);
|
|
4326
|
+
const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
3662
4327
|
if (defsCollector.length === 0) return walked;
|
|
3663
4328
|
const defsNode = { type: "defs", children: defsCollector };
|
|
3664
4329
|
const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
|
|
3665
4330
|
return __spreadProps(__spreadValues({}, walked), { children: newChildren });
|
|
3666
4331
|
}
|
|
4332
|
+
function readRootViewport(root) {
|
|
4333
|
+
const vb = parseViewBox(root.viewBox);
|
|
4334
|
+
if (vb) return [vb[2], vb[3]];
|
|
4335
|
+
const w = numericAttr(root.width);
|
|
4336
|
+
const h = numericAttr(root.height);
|
|
4337
|
+
if (w !== void 0 && h !== void 0) return [w, h];
|
|
4338
|
+
return [1, 1];
|
|
4339
|
+
}
|
|
4340
|
+
function numericAttr(v) {
|
|
4341
|
+
if (typeof v === "number") return v;
|
|
4342
|
+
if (typeof v === "string") {
|
|
4343
|
+
const n = parseFloat(v);
|
|
4344
|
+
return Number.isFinite(n) ? n : void 0;
|
|
4345
|
+
}
|
|
4346
|
+
return void 0;
|
|
4347
|
+
}
|
|
3667
4348
|
function buildIdMap(root) {
|
|
3668
4349
|
const map = /* @__PURE__ */ new Map();
|
|
3669
4350
|
const visit = (n) => {
|
|
@@ -3715,16 +4396,22 @@ function stripHash2(href) {
|
|
|
3715
4396
|
if (typeof href !== "string") return void 0;
|
|
3716
4397
|
return href.startsWith("#") ? href.slice(1) : href;
|
|
3717
4398
|
}
|
|
3718
|
-
function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector) {
|
|
4399
|
+
function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
|
|
4400
|
+
var _a, _b, _c, _d;
|
|
3719
4401
|
const clone2 = deepClonePxNode(target);
|
|
3720
4402
|
regenerateIdsAndRewriteRefs(clone2, genId3);
|
|
3721
|
-
const
|
|
3722
|
-
const
|
|
4403
|
+
const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
|
|
4404
|
+
const useW = (_b = (_a = numericAttr(useNode.width)) != null ? _a : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
|
|
4405
|
+
const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
|
|
4406
|
+
const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
|
|
4407
|
+
const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
3723
4408
|
const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materialisedClone] });
|
|
3724
4409
|
delete newNode.href;
|
|
4410
|
+
delete newNode.width;
|
|
4411
|
+
delete newNode.height;
|
|
3725
4412
|
return applyUseOffsetToG(newNode);
|
|
3726
4413
|
}
|
|
3727
|
-
function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector) {
|
|
4414
|
+
function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector, useW, useH) {
|
|
3728
4415
|
const viewBox = parseViewBox(symbolNode.viewBox);
|
|
3729
4416
|
const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
|
|
3730
4417
|
delete g.viewBox;
|
|
@@ -3733,9 +4420,14 @@ function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector) {
|
|
|
3733
4420
|
delete g.height;
|
|
3734
4421
|
if (!viewBox) return g;
|
|
3735
4422
|
const [vbX, vbY, vbW, vbH] = viewBox;
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
4423
|
+
const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;
|
|
4424
|
+
const xOff = (useW - vbW * scale) / 2;
|
|
4425
|
+
const yOff = (useH - vbH * scale) / 2;
|
|
4426
|
+
const parts = [];
|
|
4427
|
+
if (xOff !== 0 || yOff !== 0) parts.push("translate(" + xOff + "," + yOff + ")");
|
|
4428
|
+
if (scale !== 1) parts.push("scale(" + scale + ")");
|
|
4429
|
+
if (vbX !== 0 || vbY !== 0) parts.push("translate(" + -vbX + "," + -vbY + ")");
|
|
4430
|
+
if (parts.length) g.transform = parts.join("");
|
|
3739
4431
|
const clipId = genId3();
|
|
3740
4432
|
defsCollector.push({
|
|
3741
4433
|
type: "clipPath",
|
|
@@ -3751,18 +4443,18 @@ function parseViewBox(v) {
|
|
|
3751
4443
|
if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
|
|
3752
4444
|
return [parts[0], parts[1], parts[2], parts[3]];
|
|
3753
4445
|
}
|
|
3754
|
-
function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector) {
|
|
4446
|
+
function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
|
|
3755
4447
|
if (node.type === "use" && typeof node.href === "string") {
|
|
3756
4448
|
const targetId = stripHash2(node.href);
|
|
3757
4449
|
if (targetId && animatedIds.has(targetId)) {
|
|
3758
4450
|
const target = idMap.get(targetId);
|
|
3759
|
-
if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector);
|
|
4451
|
+
if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
3760
4452
|
}
|
|
3761
4453
|
}
|
|
3762
4454
|
if (!node.children) return node;
|
|
3763
4455
|
let changed = false;
|
|
3764
4456
|
const newChildren = node.children.map((ch) => {
|
|
3765
|
-
const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector);
|
|
4457
|
+
const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
3766
4458
|
if (m !== ch) changed = true;
|
|
3767
4459
|
return m;
|
|
3768
4460
|
});
|
|
@@ -3778,6 +4470,36 @@ function materialiseAllInTree(doc, engine, opts) {
|
|
|
3778
4470
|
if (engine === PxAnimatorEngine.webapi) {
|
|
3779
4471
|
root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
|
|
3780
4472
|
root = materialiseAnimatedUseInstances(root);
|
|
4473
|
+
root = pruneUnreferencedDefs(root);
|
|
4474
|
+
}
|
|
4475
|
+
return root;
|
|
4476
|
+
}
|
|
4477
|
+
function pruneUnreferencedDefs(root) {
|
|
4478
|
+
const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
|
|
4479
|
+
const walk = (n, fn) => {
|
|
4480
|
+
var _a;
|
|
4481
|
+
fn(n);
|
|
4482
|
+
(_a = n.children) == null ? void 0 : _a.forEach((c) => walk(c, fn));
|
|
4483
|
+
};
|
|
4484
|
+
let changed = true;
|
|
4485
|
+
while (changed) {
|
|
4486
|
+
changed = false;
|
|
4487
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
4488
|
+
walk(root, (n) => {
|
|
4489
|
+
if (n.type === "use" && typeof n.href === "string") referenced.add(stripHash3(n.href));
|
|
4490
|
+
});
|
|
4491
|
+
walk(root, (n) => {
|
|
4492
|
+
if (!n.children) return;
|
|
4493
|
+
let kept = n.children;
|
|
4494
|
+
if (n.type === "defs") {
|
|
4495
|
+
kept = kept.filter((c) => !((c.type === "g" || c.type === "symbol") && typeof c.id === "string" && !referenced.has(c.id)));
|
|
4496
|
+
}
|
|
4497
|
+
kept = kept.filter((c) => !(c.type === "defs" && (!c.children || c.children.length === 0)));
|
|
4498
|
+
if (kept.length !== n.children.length) {
|
|
4499
|
+
n.children = kept;
|
|
4500
|
+
changed = true;
|
|
4501
|
+
}
|
|
4502
|
+
});
|
|
3781
4503
|
}
|
|
3782
4504
|
return root;
|
|
3783
4505
|
}
|
|
@@ -3810,6 +4532,13 @@ var URL_VALUE_ATTRS_LOWER = /* @__PURE__ */ new Set([
|
|
|
3810
4532
|
]);
|
|
3811
4533
|
var IMAGE_REF_ATTRS_LOWER = /* @__PURE__ */ new Set(["href", "xlink:href", "src"]);
|
|
3812
4534
|
var DATA_RASTER_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,/i;
|
|
4535
|
+
var DATA_SVG_IMAGE_RE = /^data:image\/svg\+xml(?:;[^,]*)?,/i;
|
|
4536
|
+
var DATA_IMAGE_BASE64_PAYLOAD_RE = /^data:image\/[^;,]*;base64,([A-Za-z0-9+/]{8})/i;
|
|
4537
|
+
var BASE64_RASTER_MAGICS = ["iVBORw0K", "/9j/", "R0lGOD", "UklGR", "Qk"];
|
|
4538
|
+
function isContentSniffedRasterImage(str2) {
|
|
4539
|
+
const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(str2);
|
|
4540
|
+
return !!m && BASE64_RASTER_MAGICS.some((magic) => m[1].startsWith(magic));
|
|
4541
|
+
}
|
|
3813
4542
|
function isDangerousAttrName(nameLower) {
|
|
3814
4543
|
if (nameLower.startsWith("on")) return true;
|
|
3815
4544
|
return false;
|
|
@@ -3821,19 +4550,19 @@ function sanitiseAttributeValue(name, value) {
|
|
|
3821
4550
|
return void 0;
|
|
3822
4551
|
}
|
|
3823
4552
|
if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
|
|
3824
|
-
const
|
|
3825
|
-
if (
|
|
4553
|
+
const str2 = String(value);
|
|
4554
|
+
if (str2.includes("url(") && !/^url\(#[^)]+\)$/.test(str2)) {
|
|
3826
4555
|
console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
|
|
3827
4556
|
return void 0;
|
|
3828
4557
|
}
|
|
3829
4558
|
return value;
|
|
3830
4559
|
}
|
|
3831
4560
|
if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
|
|
3832
|
-
const
|
|
3833
|
-
if (
|
|
3834
|
-
if (/^url\(#[^)]+\)$/.test(
|
|
3835
|
-
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && DATA_RASTER_IMAGE_RE.test(
|
|
3836
|
-
console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or
|
|
4561
|
+
const str2 = String(value);
|
|
4562
|
+
if (str2.startsWith("#")) return value;
|
|
4563
|
+
if (/^url\(#[^)]+\)$/.test(str2)) return value;
|
|
4564
|
+
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(str2) || DATA_SVG_IMAGE_RE.test(str2) || isContentSniffedRasterImage(str2))) return value;
|
|
4565
|
+
console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or data:image/\u2026 URI, got:', value);
|
|
3837
4566
|
return void 0;
|
|
3838
4567
|
}
|
|
3839
4568
|
return value;
|
|
@@ -3862,7 +4591,7 @@ function createElement(tagName, normalisedProps, style, children, textContent) {
|
|
|
3862
4591
|
if (textContent) element.textContent = textContent;
|
|
3863
4592
|
return element;
|
|
3864
4593
|
}
|
|
3865
|
-
function
|
|
4594
|
+
function resolveStyle2(style, defs) {
|
|
3866
4595
|
var _a;
|
|
3867
4596
|
if (!style) return void 0;
|
|
3868
4597
|
if (typeof style === "string") {
|
|
@@ -3898,7 +4627,7 @@ function renderNode(node, defs) {
|
|
|
3898
4627
|
if (!node) return null;
|
|
3899
4628
|
const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
|
|
3900
4629
|
const nodeDefs = getDefs(node) || defs;
|
|
3901
|
-
const resolvedStyle =
|
|
4630
|
+
const resolvedStyle = resolveStyle2(style, nodeDefs);
|
|
3902
4631
|
let childElements;
|
|
3903
4632
|
if (children) {
|
|
3904
4633
|
for (const ch of children) {
|
|
@@ -4930,6 +5659,7 @@ export {
|
|
|
4930
5659
|
PxAttrValueSchema,
|
|
4931
5660
|
PxBezierPathSchema,
|
|
4932
5661
|
PxBindingSchema,
|
|
5662
|
+
PxCloneEffectSchema,
|
|
4933
5663
|
PxDefsSchema,
|
|
4934
5664
|
PxEasingOrRefSchema,
|
|
4935
5665
|
PxEffectsSchema,
|
|
@@ -4945,12 +5675,12 @@ export {
|
|
|
4945
5675
|
PxNodeBase,
|
|
4946
5676
|
PxNodeSchema,
|
|
4947
5677
|
PxPropertyAnimationSchema,
|
|
4948
|
-
PxRefEffectSchema,
|
|
4949
5678
|
PxRepeaterEffectSchema,
|
|
4950
5679
|
PxRetimeEffectSchema,
|
|
4951
5680
|
PxStrokeGradientEffectSchema,
|
|
4952
5681
|
PxSvgNodeExtra,
|
|
4953
5682
|
PxTextAlongPathEffectSchema,
|
|
5683
|
+
PxTextEffectSchema,
|
|
4954
5684
|
PxTransformPartsSchema,
|
|
4955
5685
|
PxTransformValueSchema,
|
|
4956
5686
|
PxTransformationEffectSchema,
|
|
@@ -4978,9 +5708,13 @@ export {
|
|
|
4978
5708
|
getNormalizedProps,
|
|
4979
5709
|
isPxElementFileFormat,
|
|
4980
5710
|
isPxElementFileFormatDeep,
|
|
5711
|
+
jsonElementFactory,
|
|
4981
5712
|
loadTagAnimators,
|
|
4982
5713
|
materialiseAllInTree,
|
|
4983
5714
|
materialiseAnimatedUseInstances,
|
|
5715
|
+
materialiseGlyphText,
|
|
5716
|
+
materialiseGlyphTextAlongPath,
|
|
5717
|
+
materialiseGlyphTextHorizontal,
|
|
4984
5718
|
materialiseInternalLoopsInPropAnim,
|
|
4985
5719
|
materialiseInternalLoopsInTree,
|
|
4986
5720
|
materialiseMotionPathInPropAnim,
|