@pixodesk/svg-animator-core 1.0.44 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PxDocumentDiagnostic-n8yiyL0k.d.cts → PxDocumentDiagnostic-CBhVyNEi.d.cts} +22 -22
- package/dist/{PxDocumentDiagnostic-n8yiyL0k.d.ts → PxDocumentDiagnostic-CBhVyNEi.d.ts} +22 -22
- package/dist/chunk-5HEVTP2N.min.js +1 -0
- package/dist/{chunk-EFQLDGFY.js → chunk-YVKMPBHE.js} +1969 -64
- package/dist/chunk-YVKMPBHE.js.map +1 -0
- package/dist/index.cjs +116 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -1873
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/internal.cjs +3209 -139
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +60 -3
- package/dist/internal.d.ts +60 -3
- package/dist/internal.js +53 -1
- package/dist/internal.js.map +1 -1
- package/dist/internal.min.cjs +1 -1
- package/dist/internal.min.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-EFQLDGFY.js.map +0 -1
- package/dist/chunk-YWBPS6E4.min.js +0 -1
package/dist/internal.cjs
CHANGED
|
@@ -85,7 +85,9 @@ __export(internal_exports, {
|
|
|
85
85
|
materializeMotionPathInPropAnim: () => materializeMotionPathInPropAnim,
|
|
86
86
|
mergeStaticTransformIntoAnimDef: () => mergeStaticTransformIntoAnimDef,
|
|
87
87
|
planSchemaRelease: () => planSchemaRelease,
|
|
88
|
+
prepareDocumentForRender: () => prepareDocumentForRender,
|
|
88
89
|
releaseLogProblems: () => releaseLogProblems,
|
|
90
|
+
renderPxTree: () => renderPxTree,
|
|
89
91
|
reportDocumentDiagnostics: () => reportDocumentDiagnostics,
|
|
90
92
|
reverseEasing: () => reverseEasing,
|
|
91
93
|
sanitizeAttributeValue: () => sanitizeAttributeValue,
|
|
@@ -711,6 +713,9 @@ var PxTimelineEngine = {
|
|
|
711
713
|
var PxTimelineEngineSetting = __spreadProps(__spreadValues({}, PxTimelineEngine), {
|
|
712
714
|
auto: "auto"
|
|
713
715
|
});
|
|
716
|
+
function resolveTimelineEngine(engine) {
|
|
717
|
+
return engine === PxTimelineEngineSetting.js ? PxTimelineEngine.js : PxTimelineEngine.native;
|
|
718
|
+
}
|
|
714
719
|
var PX_TRIGGER_DEFAULTS = {
|
|
715
720
|
start: "load",
|
|
716
721
|
offScreen: "pause",
|
|
@@ -767,6 +772,16 @@ var PxStrokeTrimSubPaths = {
|
|
|
767
772
|
var PX_TEXT_CONTENT_ATTR = "textContent";
|
|
768
773
|
var CLASS_ATTR = "class";
|
|
769
774
|
var TRANSFORM_ATTR = "transform";
|
|
775
|
+
var OFFSET_DISTANCE_ATTR = "offsetDistance";
|
|
776
|
+
var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
|
|
777
|
+
"type",
|
|
778
|
+
"children",
|
|
779
|
+
"animator",
|
|
780
|
+
"meta",
|
|
781
|
+
"animate",
|
|
782
|
+
"effects",
|
|
783
|
+
PX_TEXT_CONTENT_ATTR
|
|
784
|
+
]);
|
|
770
785
|
var TRANSFORM_PART = {
|
|
771
786
|
translate: "translate",
|
|
772
787
|
rotate: "rotate",
|
|
@@ -847,6 +862,16 @@ function flattenAnimatorTimeline(cfg) {
|
|
|
847
862
|
flattenMemo.set(cfg, flat);
|
|
848
863
|
return flat;
|
|
849
864
|
}
|
|
865
|
+
function getDefinitions(doc) {
|
|
866
|
+
var _a2;
|
|
867
|
+
if (!doc) return void 0;
|
|
868
|
+
return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
|
|
869
|
+
}
|
|
870
|
+
function getBindings(doc) {
|
|
871
|
+
var _a2;
|
|
872
|
+
if (!doc) return void 0;
|
|
873
|
+
return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.bindings;
|
|
874
|
+
}
|
|
850
875
|
|
|
851
876
|
// src/version/PxSchemaVersion.ts
|
|
852
877
|
var PX_WIRE_SCHEMA_VERSION = "1.2";
|
|
@@ -1407,6 +1432,11 @@ function interpolateBezier(path1, path2, progress) {
|
|
|
1407
1432
|
}
|
|
1408
1433
|
return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
|
|
1409
1434
|
}
|
|
1435
|
+
function remap(value, inMin, inMax, outMin, outMax) {
|
|
1436
|
+
if (inMax === inMin) return outMin;
|
|
1437
|
+
const t = (value - inMin) / (inMax - inMin);
|
|
1438
|
+
return outMin + t * (outMax - outMin);
|
|
1439
|
+
}
|
|
1410
1440
|
function solveCubicBezierX(p1x, p2x, x) {
|
|
1411
1441
|
if (x <= 0) return 0;
|
|
1412
1442
|
if (x >= 1) return 1;
|
|
@@ -1511,6 +1541,43 @@ function toRGBA(color) {
|
|
|
1511
1541
|
const b = Math.round(color[2] * 255);
|
|
1512
1542
|
return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
|
|
1513
1543
|
}
|
|
1544
|
+
function parseRgba(s) {
|
|
1545
|
+
var _a2;
|
|
1546
|
+
const inner = (_a2 = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a2[1];
|
|
1547
|
+
if (!inner) throw new Error("Invalid rgb/rgba format");
|
|
1548
|
+
const parts = inner.split(",").map((v) => +v.trim());
|
|
1549
|
+
return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
|
|
1550
|
+
}
|
|
1551
|
+
function parseHex(s) {
|
|
1552
|
+
const hex = s.slice(1);
|
|
1553
|
+
const isShort = hex.length <= 4;
|
|
1554
|
+
const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
|
|
1555
|
+
const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
|
|
1556
|
+
const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
|
|
1557
|
+
const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
|
|
1558
|
+
const result = [
|
|
1559
|
+
parseInt(r, 16) / 255,
|
|
1560
|
+
parseInt(g, 16) / 255,
|
|
1561
|
+
parseInt(b, 16) / 255
|
|
1562
|
+
];
|
|
1563
|
+
if (a !== null) {
|
|
1564
|
+
result.push(parseInt(a, 16) / 255);
|
|
1565
|
+
}
|
|
1566
|
+
return result;
|
|
1567
|
+
}
|
|
1568
|
+
function parseColor(s) {
|
|
1569
|
+
if (!s) return void 0;
|
|
1570
|
+
if (Array.isArray(s)) return s;
|
|
1571
|
+
if (typeof s !== "string") return void 0;
|
|
1572
|
+
if (s.startsWith("#")) {
|
|
1573
|
+
return parseHex(s);
|
|
1574
|
+
} else if (s.startsWith("rgb")) {
|
|
1575
|
+
return parseRgba(s);
|
|
1576
|
+
} else {
|
|
1577
|
+
console.warn("Unsupported color format: " + s);
|
|
1578
|
+
}
|
|
1579
|
+
return void 0;
|
|
1580
|
+
}
|
|
1514
1581
|
var PX_COLOR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
|
|
1515
1582
|
var PX_TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
|
|
1516
1583
|
var PX_PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
@@ -1571,6 +1638,9 @@ var PX_DEFAULT_DURATION_MS = 1e3;
|
|
|
1571
1638
|
function kebabToCamelCaseWord(kebab) {
|
|
1572
1639
|
return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
|
|
1573
1640
|
}
|
|
1641
|
+
function isCamelCaseWord(word) {
|
|
1642
|
+
return !word.includes("-") && /[a-z][A-Z]/.test(word);
|
|
1643
|
+
}
|
|
1574
1644
|
var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
|
|
1575
1645
|
// Transform/positioning
|
|
1576
1646
|
"viewBox",
|
|
@@ -1726,6 +1796,38 @@ function invertEasing(easing) {
|
|
|
1726
1796
|
return cubicBezier(flipped);
|
|
1727
1797
|
}
|
|
1728
1798
|
|
|
1799
|
+
// src/animation/PxStaticTransformMerge.ts
|
|
1800
|
+
function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
|
|
1801
|
+
if (!animDef) return animDef;
|
|
1802
|
+
const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
|
|
1803
|
+
if (!staticParts || !Object.keys(staticParts).length) return animDef;
|
|
1804
|
+
const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues(__spreadValues({}, staticParts), v) : v;
|
|
1805
|
+
const transformAnim = animDef[TRANSFORM_ATTR];
|
|
1806
|
+
if (transformAnim && typeof transformAnim === "object") {
|
|
1807
|
+
const anim = transformAnim;
|
|
1808
|
+
if (Array.isArray(anim.keyframes)) {
|
|
1809
|
+
const out = __spreadProps(__spreadValues({}, anim), {
|
|
1810
|
+
keyframes: anim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: mergeKfValue(kf.value) }))
|
|
1811
|
+
});
|
|
1812
|
+
if (out.value !== void 0) out.value = mergeKfValue(out.value);
|
|
1813
|
+
return __spreadProps(__spreadValues({}, animDef), { transform: out });
|
|
1814
|
+
}
|
|
1815
|
+
return animDef;
|
|
1816
|
+
}
|
|
1817
|
+
const channels = Object.keys(animDef).filter((k) => PX_TRANSFORM_FN_NAMES.has(k));
|
|
1818
|
+
if (channels.length !== 1) return animDef;
|
|
1819
|
+
const ch = channels[0];
|
|
1820
|
+
const chAnim = animDef[ch];
|
|
1821
|
+
if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
|
|
1822
|
+
const lifted = __spreadProps(__spreadValues({}, chAnim), {
|
|
1823
|
+
keyframes: chAnim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: __spreadProps(__spreadValues({}, staticParts), { [ch]: kf.value }) }))
|
|
1824
|
+
});
|
|
1825
|
+
if (lifted.value !== void 0) lifted.value = __spreadProps(__spreadValues({}, staticParts), { [ch]: lifted.value });
|
|
1826
|
+
const rest = __spreadValues({}, animDef);
|
|
1827
|
+
delete rest[ch];
|
|
1828
|
+
return __spreadProps(__spreadValues({}, rest), { transform: lifted });
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1729
1831
|
// src/materialize/PxMotionPath.ts
|
|
1730
1832
|
function getKfTranslate(kf) {
|
|
1731
1833
|
const v = keyframeValue(kf);
|
|
@@ -1777,6 +1879,33 @@ function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
|
|
|
1777
1879
|
byNext.set(nextKf, entry);
|
|
1778
1880
|
return entry;
|
|
1779
1881
|
}
|
|
1882
|
+
function evaluateMotionPathSegment(prevKf, nextKf, prevPos, nextPos, localProgress, autoOrient) {
|
|
1883
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
1884
|
+
const t = seg.totalArc === 0 ? localProgress : tFromArcFraction(seg.lut, localProgress);
|
|
1885
|
+
const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
1886
|
+
if (!autoOrient) return { translate: point };
|
|
1887
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
1888
|
+
const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
1889
|
+
return { translate: point, rotateDeg };
|
|
1890
|
+
}
|
|
1891
|
+
function tFromArcFraction(lut, arcFrac) {
|
|
1892
|
+
const total = lut.ds[lut.ds.length - 1];
|
|
1893
|
+
const target = arcFrac * total;
|
|
1894
|
+
const { ts, ds } = lut;
|
|
1895
|
+
const last = ds.length - 1;
|
|
1896
|
+
if (target <= 0) return ts[0];
|
|
1897
|
+
if (target >= ds[last]) return ts[last];
|
|
1898
|
+
let lo = 1, hi = last;
|
|
1899
|
+
while (lo < hi) {
|
|
1900
|
+
const mid = lo + hi >>> 1;
|
|
1901
|
+
if (ds[mid] < target) lo = mid + 1;
|
|
1902
|
+
else hi = mid;
|
|
1903
|
+
}
|
|
1904
|
+
const dPrev = ds[hi - 1];
|
|
1905
|
+
const span = ds[hi] - dPrev;
|
|
1906
|
+
const frac = span > 0 ? (target - dPrev) / span : 0;
|
|
1907
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
1908
|
+
}
|
|
1780
1909
|
var DEFAULT_FLATNESS_TOL = 0.5;
|
|
1781
1910
|
var DEFAULT_ROTATION_TOL = 5;
|
|
1782
1911
|
var DEFAULT_MAX_SAMPLES = 32;
|
|
@@ -2049,9 +2178,211 @@ function perpDist(q, pA, pB) {
|
|
|
2049
2178
|
const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
|
|
2050
2179
|
return Math.abs(cross) / Math.sqrt(len2);
|
|
2051
2180
|
}
|
|
2181
|
+
function materializeMotionPathsInTree(root, opts) {
|
|
2182
|
+
const out = walkAndMaterialize(root, opts);
|
|
2183
|
+
return out != null ? out : root;
|
|
2184
|
+
}
|
|
2185
|
+
function walkAndMaterialize(node, opts) {
|
|
2186
|
+
let newChildren;
|
|
2187
|
+
if (node.children) {
|
|
2188
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2189
|
+
const ch = node.children[i];
|
|
2190
|
+
const ret = walkAndMaterialize(ch, opts);
|
|
2191
|
+
if (ret !== null) {
|
|
2192
|
+
if (!newChildren) newChildren = node.children.slice();
|
|
2193
|
+
newChildren[i] = ret;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
let newAnimate;
|
|
2198
|
+
const animBucket = node.animate;
|
|
2199
|
+
if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
|
|
2200
|
+
const animDef = mergeStaticTransformIntoAnimDef(animBucket, node.transform);
|
|
2201
|
+
const transformAnim = animDef.transform;
|
|
2202
|
+
if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
|
|
2203
|
+
const materialized = materializeMotionPathInPropAnim(transformAnim, opts);
|
|
2204
|
+
if (materialized !== transformAnim) {
|
|
2205
|
+
newAnimate = __spreadProps(__spreadValues({}, animDef), { transform: materialized });
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
if (!newChildren && !newAnimate) return null;
|
|
2210
|
+
const cloned = __spreadValues({}, node);
|
|
2211
|
+
if (newChildren) cloned.children = newChildren;
|
|
2212
|
+
if (newAnimate) cloned.animate = newAnimate;
|
|
2213
|
+
return cloned;
|
|
2214
|
+
}
|
|
2052
2215
|
|
|
2053
2216
|
// src/animation/PxDefinitions.ts
|
|
2054
2217
|
var PX_LOOP_JUMP_SHIFT_MS = 1;
|
|
2218
|
+
function deepEqualValue(a, b) {
|
|
2219
|
+
if (a === b) return true;
|
|
2220
|
+
if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
|
|
2221
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
2222
|
+
const ka = Object.keys(a);
|
|
2223
|
+
const kb = Object.keys(b);
|
|
2224
|
+
if (ka.length !== kb.length) return false;
|
|
2225
|
+
return ka.every((k) => deepEqualValue(a[k], b[k]));
|
|
2226
|
+
}
|
|
2227
|
+
function parsePathCommands(d) {
|
|
2228
|
+
const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
|
|
2229
|
+
const commands = [];
|
|
2230
|
+
let currentCommand = null;
|
|
2231
|
+
for (const token of tokens) {
|
|
2232
|
+
if (/[MLCZmlcz]/.test(token)) {
|
|
2233
|
+
currentCommand = { type: token, values: [] };
|
|
2234
|
+
commands.push(currentCommand);
|
|
2235
|
+
} else if (currentCommand) {
|
|
2236
|
+
const value = +token;
|
|
2237
|
+
currentCommand.values.push(Number.isNaN(value) ? 0 : value);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
return commands;
|
|
2241
|
+
}
|
|
2242
|
+
function parseSvgPathToBezier(d) {
|
|
2243
|
+
const res = [];
|
|
2244
|
+
let currentPath;
|
|
2245
|
+
const commands = parsePathCommands(d);
|
|
2246
|
+
for (const command of commands) {
|
|
2247
|
+
const type = command.type;
|
|
2248
|
+
const values = command.values;
|
|
2249
|
+
if (type === "M" || type === "m") {
|
|
2250
|
+
const x = values[0] || 0;
|
|
2251
|
+
const y = values[1] || 0;
|
|
2252
|
+
currentPath = {
|
|
2253
|
+
v: [[x, y]],
|
|
2254
|
+
i: [[x, y]],
|
|
2255
|
+
o: [[x, y]],
|
|
2256
|
+
c: false
|
|
2257
|
+
};
|
|
2258
|
+
res.push(currentPath);
|
|
2259
|
+
continue;
|
|
2260
|
+
}
|
|
2261
|
+
if (!currentPath) {
|
|
2262
|
+
currentPath = {
|
|
2263
|
+
v: [[0, 0]],
|
|
2264
|
+
i: [[0, 0]],
|
|
2265
|
+
o: [[0, 0]],
|
|
2266
|
+
c: false
|
|
2267
|
+
};
|
|
2268
|
+
res.push(currentPath);
|
|
2269
|
+
}
|
|
2270
|
+
if (type === "L") {
|
|
2271
|
+
const x = values[0] || 0;
|
|
2272
|
+
const y = values[1] || 0;
|
|
2273
|
+
currentPath.v.push([x, y]);
|
|
2274
|
+
currentPath.i.push([x, y]);
|
|
2275
|
+
currentPath.o.push([x, y]);
|
|
2276
|
+
} else if (type === "C") {
|
|
2277
|
+
const outX = values[0] || 0;
|
|
2278
|
+
const outY = values[1] || 0;
|
|
2279
|
+
const inX2 = values[2] || 0;
|
|
2280
|
+
const inY2 = values[3] || 0;
|
|
2281
|
+
const x2 = values[4] || 0;
|
|
2282
|
+
const y2 = values[5] || 0;
|
|
2283
|
+
currentPath.o[currentPath.o.length - 1] = [outX, outY];
|
|
2284
|
+
currentPath.v.push([x2, y2]);
|
|
2285
|
+
currentPath.i.push([inX2, inY2]);
|
|
2286
|
+
currentPath.o.push([x2, y2]);
|
|
2287
|
+
} else if (type === "Z" || type === "z") {
|
|
2288
|
+
currentPath.c = true;
|
|
2289
|
+
} else {
|
|
2290
|
+
console.warn('Unsupported path command "' + type + '"');
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
return res;
|
|
2294
|
+
}
|
|
2295
|
+
function extractPathData(str2) {
|
|
2296
|
+
if (str2.startsWith("path(") && str2.endsWith(")")) {
|
|
2297
|
+
return str2.slice(5, -1);
|
|
2298
|
+
}
|
|
2299
|
+
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str2)) {
|
|
2300
|
+
return str2;
|
|
2301
|
+
}
|
|
2302
|
+
return void 0;
|
|
2303
|
+
}
|
|
2304
|
+
function isPathString(value) {
|
|
2305
|
+
return typeof value === "string" && extractPathData(value) !== void 0;
|
|
2306
|
+
}
|
|
2307
|
+
function normalizePathValue(value) {
|
|
2308
|
+
if (value && typeof value === "object" && typeof value.pathData === "string") {
|
|
2309
|
+
const d = extractPathData(value.pathData);
|
|
2310
|
+
return d ? { paths: parseSvgPathToBezier(d) } : value;
|
|
2311
|
+
}
|
|
2312
|
+
if (value && typeof value === "object" && "paths" in value) {
|
|
2313
|
+
const pathsArray = value.paths;
|
|
2314
|
+
if (Array.isArray(pathsArray) && pathsArray.length > 0) {
|
|
2315
|
+
if (isPathString(pathsArray[0])) {
|
|
2316
|
+
const paths = [];
|
|
2317
|
+
for (const pathStr2 of pathsArray) {
|
|
2318
|
+
const d = extractPathData(pathStr2);
|
|
2319
|
+
if (d) {
|
|
2320
|
+
paths.push(...parseSvgPathToBezier(d));
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
return { paths };
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
return value;
|
|
2327
|
+
}
|
|
2328
|
+
if (Array.isArray(value)) {
|
|
2329
|
+
if (value.length > 0 && isPathString(value[0])) {
|
|
2330
|
+
const paths = [];
|
|
2331
|
+
for (const pathStr2 of value) {
|
|
2332
|
+
const d = extractPathData(pathStr2);
|
|
2333
|
+
if (d) {
|
|
2334
|
+
paths.push(...parseSvgPathToBezier(d));
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
return { paths };
|
|
2338
|
+
}
|
|
2339
|
+
return { paths: value };
|
|
2340
|
+
}
|
|
2341
|
+
if (isPathString(value)) {
|
|
2342
|
+
const d = extractPathData(value);
|
|
2343
|
+
return { paths: parseSvgPathToBezier(d) };
|
|
2344
|
+
}
|
|
2345
|
+
return value;
|
|
2346
|
+
}
|
|
2347
|
+
function resolveEasing(easing, defs) {
|
|
2348
|
+
var _a2;
|
|
2349
|
+
if (!easing) return void 0;
|
|
2350
|
+
if (Array.isArray(easing)) {
|
|
2351
|
+
return easing;
|
|
2352
|
+
}
|
|
2353
|
+
if ((_a2 = defs == null ? void 0 : defs.easings) == null ? void 0 : _a2[easing]) {
|
|
2354
|
+
return defs.easings[easing];
|
|
2355
|
+
}
|
|
2356
|
+
console.warn("Unknown easing name: " + easing);
|
|
2357
|
+
return void 0;
|
|
2358
|
+
}
|
|
2359
|
+
function resolveAnimation(animRef, defs) {
|
|
2360
|
+
var _a2;
|
|
2361
|
+
if (typeof animRef === "string") {
|
|
2362
|
+
const resolved = (_a2 = defs == null ? void 0 : defs.animations) == null ? void 0 : _a2[animRef];
|
|
2363
|
+
if (!resolved) {
|
|
2364
|
+
console.warn("Unknown animation name: " + animRef);
|
|
2365
|
+
}
|
|
2366
|
+
return resolved;
|
|
2367
|
+
}
|
|
2368
|
+
return animRef;
|
|
2369
|
+
}
|
|
2370
|
+
function resolveElementAnimation(animate, defs) {
|
|
2371
|
+
if (!animate) return [];
|
|
2372
|
+
const results = [];
|
|
2373
|
+
if (typeof animate === "string") {
|
|
2374
|
+
const resolved = resolveAnimation(animate, defs);
|
|
2375
|
+
if (resolved) results.push(resolved);
|
|
2376
|
+
} else if (Array.isArray(animate)) {
|
|
2377
|
+
for (const item of animate) {
|
|
2378
|
+
const resolved = resolveAnimation(item, defs);
|
|
2379
|
+
if (resolved) results.push(resolved);
|
|
2380
|
+
}
|
|
2381
|
+
} else {
|
|
2382
|
+
results.push(animate);
|
|
2383
|
+
}
|
|
2384
|
+
return results;
|
|
2385
|
+
}
|
|
2055
2386
|
function interpolateValue(propName, a, b, t) {
|
|
2056
2387
|
var _a2, _b;
|
|
2057
2388
|
if (propName === "d") {
|
|
@@ -2090,35 +2421,498 @@ function interpolateTransformParts(a, b, t) {
|
|
|
2090
2421
|
}
|
|
2091
2422
|
return out;
|
|
2092
2423
|
}
|
|
2093
|
-
function
|
|
2094
|
-
|
|
2095
|
-
const
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2424
|
+
function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
2425
|
+
var _a2, _b, _c, _d, _e;
|
|
2426
|
+
const totalIntervals = keyframes.length - 1;
|
|
2427
|
+
const segCount = clamp((_a2 = loop.segmentCount) != null ? _a2 : totalIntervals, 1, totalIntervals);
|
|
2428
|
+
let segKfs;
|
|
2429
|
+
if (loop.repeatAt === PxLoopRepeatAt.start) {
|
|
2430
|
+
segKfs = keyframes.slice(0, segCount + 1);
|
|
2431
|
+
} else {
|
|
2432
|
+
segKfs = keyframes.slice(totalIntervals - segCount);
|
|
2433
|
+
}
|
|
2434
|
+
const firstT = (_b = keyframes[0].t) != null ? _b : 0;
|
|
2435
|
+
const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
|
|
2436
|
+
let fillStart, fillEnd;
|
|
2437
|
+
if (loop.repeatAt === PxLoopRepeatAt.start) {
|
|
2438
|
+
fillStart = 0;
|
|
2439
|
+
fillEnd = firstT;
|
|
2440
|
+
} else {
|
|
2441
|
+
fillStart = lastT;
|
|
2442
|
+
fillEnd = duration;
|
|
2443
|
+
}
|
|
2444
|
+
const fillDuration = fillEnd - fillStart;
|
|
2445
|
+
if (fillDuration <= 0) return keyframes;
|
|
2446
|
+
const segStartT = (_d = segKfs[0].t) != null ? _d : 0;
|
|
2447
|
+
const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
|
|
2448
|
+
const segDuration = segEndT - segStartT;
|
|
2449
|
+
if (segDuration <= 0) return keyframes;
|
|
2450
|
+
const template = segKfs.map((kf) => ({
|
|
2451
|
+
relT: (kf.t - segStartT) / segDuration,
|
|
2452
|
+
v: kf.v,
|
|
2453
|
+
e: kf.e,
|
|
2454
|
+
tangentIn: keyframeTangentIn(kf),
|
|
2455
|
+
tangentOut: keyframeTangentOut(kf)
|
|
2456
|
+
}));
|
|
2457
|
+
const fullReps = Math.floor(fillDuration / segDuration);
|
|
2458
|
+
const remainder = fillDuration - fullReps * segDuration;
|
|
2459
|
+
const partialFraction = remainder / segDuration;
|
|
2460
|
+
const looped = [];
|
|
2461
|
+
const separateBoundary = loop.repeatAt !== PxLoopRepeatAt.start;
|
|
2462
|
+
const originalTerminalKf = keyframes[keyframes.length - 1];
|
|
2463
|
+
let terminalEasingOverride;
|
|
2464
|
+
let hasTerminalEasingOverride = false;
|
|
2465
|
+
function appendRep(repStart, isReversed, partial) {
|
|
2466
|
+
var _a3;
|
|
2467
|
+
let entries;
|
|
2468
|
+
if (isReversed) {
|
|
2469
|
+
entries = [];
|
|
2470
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
2471
|
+
entries.push({
|
|
2472
|
+
relT: 1 - template[i].relT,
|
|
2473
|
+
v: template[i].v,
|
|
2474
|
+
// Easing for reversed transition: use reversed easing from the forward "from" keyframe
|
|
2475
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
2476
|
+
// Reversed traversal swaps each vertex's in/out spatial tangents
|
|
2477
|
+
// (geometry is identical, walked backwards), so curvature and
|
|
2478
|
+
// auto-orientation survive the reversed rep.
|
|
2479
|
+
tangentIn: template[i].tangentOut,
|
|
2480
|
+
tangentOut: template[i].tangentIn
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
2483
|
+
} else {
|
|
2484
|
+
entries = template;
|
|
2485
|
+
}
|
|
2486
|
+
const cutRelT = partial !== void 0 ? partial : 1;
|
|
2487
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2488
|
+
const entry = entries[i];
|
|
2489
|
+
if (entry.relT > cutRelT + 1e-9) {
|
|
2490
|
+
const prev = entries[i - 1];
|
|
2491
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
2492
|
+
const localFrac = (cutRelT - prev.relT) / intervalSpan;
|
|
2493
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
2494
|
+
const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
2495
|
+
const { left: leftEasing } = splitEasing(prev.e, localFrac);
|
|
2496
|
+
if (looped.length > 0 && prev.relT <= cutRelT) {
|
|
2497
|
+
looped[looped.length - 1].e = leftEasing;
|
|
2498
|
+
}
|
|
2499
|
+
looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
|
|
2500
|
+
return;
|
|
2501
|
+
}
|
|
2502
|
+
const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
|
|
2503
|
+
const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a3 = prevKf.t) != null ? _a3 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
|
|
2504
|
+
if (isBoundary) {
|
|
2505
|
+
if (deepEqualValue(prevKf.v, entry.v)) {
|
|
2506
|
+
if (looped.length > 0) {
|
|
2507
|
+
prevKf.e = entry.e;
|
|
2508
|
+
prevKf.tangentOut = entry.tangentOut;
|
|
2509
|
+
} else {
|
|
2510
|
+
terminalEasingOverride = entry.e;
|
|
2511
|
+
hasTerminalEasingOverride = true;
|
|
2512
|
+
}
|
|
2513
|
+
continue;
|
|
2514
|
+
}
|
|
2515
|
+
if (looped.length > 0) {
|
|
2516
|
+
delete prevKf.tangentIn;
|
|
2517
|
+
delete prevKf.tangentOut;
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
const pushed = {
|
|
2521
|
+
t: repStart + entry.relT * segDuration + (isBoundary ? PX_LOOP_JUMP_SHIFT_MS : 0),
|
|
2522
|
+
v: entry.v,
|
|
2523
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
2524
|
+
};
|
|
2525
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
2526
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
2527
|
+
looped.push(pushed);
|
|
2107
2528
|
}
|
|
2108
|
-
return animDef;
|
|
2109
2529
|
}
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2530
|
+
function appendRepTail(repStart, isReversed, tailFraction) {
|
|
2531
|
+
let entries;
|
|
2532
|
+
if (isReversed) {
|
|
2533
|
+
entries = [];
|
|
2534
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
2535
|
+
entries.push({
|
|
2536
|
+
relT: 1 - template[i].relT,
|
|
2537
|
+
v: template[i].v,
|
|
2538
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
2539
|
+
tangentIn: template[i].tangentOut,
|
|
2540
|
+
tangentOut: template[i].tangentIn
|
|
2541
|
+
});
|
|
2542
|
+
}
|
|
2543
|
+
} else {
|
|
2544
|
+
entries = template;
|
|
2545
|
+
}
|
|
2546
|
+
const startRelT = 1 - tailFraction;
|
|
2547
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2548
|
+
const entry = entries[i];
|
|
2549
|
+
if (entry.relT < startRelT - 1e-9) continue;
|
|
2550
|
+
const prev = entries[i - 1];
|
|
2551
|
+
if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {
|
|
2552
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
2553
|
+
const localFrac = (startRelT - prev.relT) / intervalSpan;
|
|
2554
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
2555
|
+
const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
2556
|
+
const { right: rightEasing } = splitEasing(prev.e, localFrac);
|
|
2557
|
+
looped.push({ t: repStart, v: startValue, e: rightEasing });
|
|
2558
|
+
}
|
|
2559
|
+
const pushed = {
|
|
2560
|
+
t: repStart + (entry.relT - startRelT) * segDuration,
|
|
2561
|
+
v: entry.v,
|
|
2562
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
2563
|
+
};
|
|
2564
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
2565
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
2566
|
+
looped.push(pushed);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
if (loop.repeatAt === PxLoopRepeatAt.start) {
|
|
2570
|
+
if (partialFraction > 1e-9) {
|
|
2571
|
+
const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
|
|
2572
|
+
appendRepTail(fillStart, isReversed, partialFraction);
|
|
2573
|
+
}
|
|
2574
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
2575
|
+
const distFromBoundary = fullReps - 1 - rep;
|
|
2576
|
+
const isReversed = loop.direction === PxLoopDirection.alternate && distFromBoundary % 2 === 0;
|
|
2577
|
+
const repStart = fillStart + remainder + rep * segDuration;
|
|
2578
|
+
appendRep(repStart, isReversed);
|
|
2579
|
+
}
|
|
2580
|
+
} else {
|
|
2581
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
2582
|
+
const isReversed = loop.direction === PxLoopDirection.alternate && rep % 2 === 0;
|
|
2583
|
+
const repStart = fillStart + rep * segDuration;
|
|
2584
|
+
appendRep(repStart, isReversed);
|
|
2585
|
+
}
|
|
2586
|
+
if (partialFraction > 1e-9) {
|
|
2587
|
+
const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
|
|
2588
|
+
const repStart = fillStart + fullReps * segDuration;
|
|
2589
|
+
appendRep(repStart, isReversed, partialFraction);
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
if (loop.repeatAt === PxLoopRepeatAt.start) {
|
|
2593
|
+
return [...looped, ...keyframes];
|
|
2594
|
+
} else {
|
|
2595
|
+
if (hasTerminalEasingOverride && keyframes.length > 0) {
|
|
2596
|
+
const head = keyframes.slice(0, -1);
|
|
2597
|
+
const tail = __spreadProps(__spreadValues({}, keyframes[keyframes.length - 1]), { e: terminalEasingOverride });
|
|
2598
|
+
return [...head, tail, ...looped];
|
|
2599
|
+
}
|
|
2600
|
+
return [...keyframes, ...looped];
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
function normalizeKeyframes(propName, propAnim, duration, defs) {
|
|
2604
|
+
var _a2;
|
|
2605
|
+
const keyframes = propAnim.keyframes || [];
|
|
2606
|
+
const normalized = [];
|
|
2607
|
+
for (const kf of keyframes) {
|
|
2608
|
+
const timePct = keyframeTime(kf);
|
|
2609
|
+
let value = keyframeValue(kf);
|
|
2610
|
+
const easing = keyframeEasing(kf);
|
|
2611
|
+
if (propName === "d") {
|
|
2612
|
+
value = normalizePathValue(value);
|
|
2613
|
+
}
|
|
2614
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
2615
|
+
if (PX_COLOR_ATTR_NAMES.has(propNameKebab)) {
|
|
2616
|
+
value = (_a2 = parseColor(value)) != null ? _a2 : value;
|
|
2617
|
+
}
|
|
2618
|
+
const normKf = {
|
|
2619
|
+
t: timePct,
|
|
2620
|
+
v: value,
|
|
2621
|
+
e: resolveEasing(easing, defs)
|
|
2622
|
+
};
|
|
2623
|
+
const tIn = keyframeTangentIn(kf);
|
|
2624
|
+
const tOut = keyframeTangentOut(kf);
|
|
2625
|
+
if (tIn) normKf.tangentIn = tIn;
|
|
2626
|
+
if (tOut) normKf.tangentOut = tOut;
|
|
2627
|
+
normalized.push(normKf);
|
|
2628
|
+
}
|
|
2629
|
+
normalized.sort((a, b) => {
|
|
2630
|
+
var _a3, _b;
|
|
2631
|
+
return ((_a3 = a.t) != null ? _a3 : 0) - ((_b = b.t) != null ? _b : 0);
|
|
2117
2632
|
});
|
|
2118
|
-
|
|
2119
|
-
const
|
|
2120
|
-
|
|
2121
|
-
|
|
2633
|
+
const loopRaw = propAnim.loop;
|
|
2634
|
+
const loop = loopRaw === true ? {} : loopRaw || void 0;
|
|
2635
|
+
if (loop && normalized.length >= 2) {
|
|
2636
|
+
return expandLoopKeyframes(propName, normalized, loop, duration);
|
|
2637
|
+
}
|
|
2638
|
+
return normalized;
|
|
2639
|
+
}
|
|
2640
|
+
function mergeAnimationDefinitions(animations) {
|
|
2641
|
+
const merged = {};
|
|
2642
|
+
for (const anim of animations) {
|
|
2643
|
+
for (const [prop, propAnim] of Object.entries(anim)) {
|
|
2644
|
+
merged[prop] = propAnim;
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
return merged;
|
|
2648
|
+
}
|
|
2649
|
+
function materializeInternalLoopsInPropAnim(propName, propAnim, duration) {
|
|
2650
|
+
const loopRaw = propAnim.loop;
|
|
2651
|
+
if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
|
|
2652
|
+
const loop = loopRaw === true ? {} : loopRaw;
|
|
2653
|
+
const rawKfs = propAnim.keyframes;
|
|
2654
|
+
if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
|
|
2655
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
2656
|
+
const isColor = PX_COLOR_ATTR_NAMES.has(propNameKebab);
|
|
2657
|
+
const kfs = rawKfs.map((kf) => {
|
|
2658
|
+
var _a2;
|
|
2659
|
+
const t = keyframeTime(kf);
|
|
2660
|
+
let v = keyframeValue(kf);
|
|
2661
|
+
if (propName === "d") v = normalizePathValue(v);
|
|
2662
|
+
if (isColor) v = (_a2 = parseColor(v)) != null ? _a2 : v;
|
|
2663
|
+
const e = keyframeEasing(kf);
|
|
2664
|
+
const out2 = { t, v, e };
|
|
2665
|
+
const tIn = keyframeTangentIn(kf);
|
|
2666
|
+
const tOut = keyframeTangentOut(kf);
|
|
2667
|
+
if (tIn) out2.tangentIn = tIn;
|
|
2668
|
+
if (tOut) out2.tangentOut = tOut;
|
|
2669
|
+
return out2;
|
|
2670
|
+
});
|
|
2671
|
+
const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
|
|
2672
|
+
const out = { keyframes: expanded };
|
|
2673
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
2674
|
+
return out;
|
|
2675
|
+
}
|
|
2676
|
+
function materializeInternalLoopsInTree(root, duration) {
|
|
2677
|
+
const ret = walkAndMaterializeLoops(root, duration);
|
|
2678
|
+
return ret != null ? ret : root;
|
|
2679
|
+
}
|
|
2680
|
+
function walkAndMaterializeLoops(node, duration) {
|
|
2681
|
+
let newChildren;
|
|
2682
|
+
if (node.children) {
|
|
2683
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2684
|
+
const ret = walkAndMaterializeLoops(node.children[i], duration);
|
|
2685
|
+
if (ret !== null) {
|
|
2686
|
+
if (!newChildren) newChildren = node.children.slice();
|
|
2687
|
+
newChildren[i] = ret;
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
let newAnimate;
|
|
2692
|
+
const animBucket = node.animate;
|
|
2693
|
+
if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
|
|
2694
|
+
const animDef = animBucket;
|
|
2695
|
+
for (const propName of Object.keys(animDef)) {
|
|
2696
|
+
const propAnim = animDef[propName];
|
|
2697
|
+
const materialized = materializeInternalLoopsInPropAnim(propName, propAnim, duration);
|
|
2698
|
+
if (materialized !== propAnim) {
|
|
2699
|
+
if (!newAnimate) newAnimate = __spreadValues({}, animDef);
|
|
2700
|
+
newAnimate[propName] = materialized;
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
if (!newChildren && !newAnimate) return null;
|
|
2705
|
+
const cloned = __spreadValues({}, node);
|
|
2706
|
+
if (newChildren) cloned.children = newChildren;
|
|
2707
|
+
if (newAnimate) cloned.animate = newAnimate;
|
|
2708
|
+
return cloned;
|
|
2709
|
+
}
|
|
2710
|
+
var _elementIdCounter = 0;
|
|
2711
|
+
function generateElementId() {
|
|
2712
|
+
return "_px_el_" + ++_elementIdCounter;
|
|
2713
|
+
}
|
|
2714
|
+
function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimelineEngine.native) {
|
|
2715
|
+
const normalized = {};
|
|
2716
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
2717
|
+
if (propName === "transform" && propAnim.alongPathMode === "offsetPath" && animDef["offsetDistance"] !== void 0) {
|
|
2718
|
+
continue;
|
|
2719
|
+
}
|
|
2720
|
+
const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
|
|
2721
|
+
if (normalizedKfs.length > 0) {
|
|
2722
|
+
const out = { keyframes: normalizedKfs };
|
|
2723
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
2724
|
+
if (propAnim.loop !== void 0) out.loop = propAnim.loop;
|
|
2725
|
+
normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materializeMotionPathInPropAnim(out) : out;
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
return normalized;
|
|
2729
|
+
}
|
|
2730
|
+
function normalizeBindings(doc, engine = PxTimelineEngine.native) {
|
|
2731
|
+
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
2732
|
+
const defs = getDefinitions(doc);
|
|
2733
|
+
const duration = animatorConfig.duration || 1e3;
|
|
2734
|
+
const bindings = [];
|
|
2735
|
+
const processAnimation = (id, animDefs, staticTransform) => {
|
|
2736
|
+
if (animDefs.length === 0) return null;
|
|
2737
|
+
const merged = mergeStaticTransformIntoAnimDef(mergeAnimationDefinitions(animDefs), staticTransform);
|
|
2738
|
+
const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
|
|
2739
|
+
if (Object.keys(normalizedAnim).length === 0) return null;
|
|
2740
|
+
return {
|
|
2741
|
+
id,
|
|
2742
|
+
animate: normalizedAnim
|
|
2743
|
+
};
|
|
2744
|
+
};
|
|
2745
|
+
const docBindings = getBindings(doc);
|
|
2746
|
+
if (docBindings) {
|
|
2747
|
+
for (const binding of docBindings) {
|
|
2748
|
+
const id = binding.target.startsWith("#") ? binding.target.slice(1) : binding.target;
|
|
2749
|
+
const animDefs = binding.animateWith.map((name) => resolveAnimation(name, defs)).filter((d) => !!d);
|
|
2750
|
+
const normalized = processAnimation(id, animDefs);
|
|
2751
|
+
if (normalized) bindings.push(normalized);
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
const processNode = (node) => {
|
|
2755
|
+
const inlineAnim = node.animate;
|
|
2756
|
+
if (inlineAnim && Object.keys(inlineAnim).length > 0) {
|
|
2757
|
+
const nodeId = node.id || generateElementId();
|
|
2758
|
+
node.id = nodeId;
|
|
2759
|
+
const normalized = processAnimation(nodeId, resolveElementAnimation(inlineAnim, defs), node.transform);
|
|
2760
|
+
if (normalized) bindings.push(normalized);
|
|
2761
|
+
}
|
|
2762
|
+
if (node.children) {
|
|
2763
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2764
|
+
processNode(node.children[i]);
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
};
|
|
2768
|
+
if (doc.children) {
|
|
2769
|
+
for (let i = 0; i < doc.children.length; i++) {
|
|
2770
|
+
processNode(doc.children[i]);
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
return bindings;
|
|
2774
|
+
}
|
|
2775
|
+
function getKeyframesPair(keyframes, progress) {
|
|
2776
|
+
var _a2, _b;
|
|
2777
|
+
const last = keyframes.length - 1;
|
|
2778
|
+
let prevKf = keyframes[0];
|
|
2779
|
+
let nextKf = keyframes[last > 0 ? 1 : 0];
|
|
2780
|
+
for (let j = 0; j < last; j++) {
|
|
2781
|
+
const aOff = (_a2 = keyframes[j].t) != null ? _a2 : 0;
|
|
2782
|
+
const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
|
|
2783
|
+
if (aOff <= progress && progress <= bOff) {
|
|
2784
|
+
prevKf = keyframes[j];
|
|
2785
|
+
nextKf = keyframes[j + 1];
|
|
2786
|
+
break;
|
|
2787
|
+
}
|
|
2788
|
+
if (progress > bOff && j === last - 1) {
|
|
2789
|
+
prevKf = keyframes[last > 0 ? last - 1 : 0];
|
|
2790
|
+
nextKf = keyframes[last];
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
return { prevKf, nextKf };
|
|
2794
|
+
}
|
|
2795
|
+
function calcPropertyValue(propName, propAnim, progress) {
|
|
2796
|
+
var _a2, _b, _c, _d, _e;
|
|
2797
|
+
const keyframes = propAnim.keyframes || [];
|
|
2798
|
+
if (keyframes.length === 0) return null;
|
|
2799
|
+
const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
|
|
2800
|
+
let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a2 = prevKf.t) != null ? _a2 : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
|
|
2801
|
+
localProgress = clamp(localProgress, 0, 1);
|
|
2802
|
+
const easing = keyframeEasing(prevKf);
|
|
2803
|
+
if (easing && Array.isArray(easing)) {
|
|
2804
|
+
try {
|
|
2805
|
+
localProgress = cubicBezier(easing)(localProgress);
|
|
2806
|
+
} catch (e) {
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
2810
|
+
let cssValue = null;
|
|
2811
|
+
const prevV = prevKf == null ? void 0 : prevKf.v;
|
|
2812
|
+
const nextV = nextKf == null ? void 0 : nextKf.v;
|
|
2813
|
+
if (cssAttrName === "d") {
|
|
2814
|
+
const prevPaths = (_c = prevV == null ? void 0 : prevV.paths) != null ? _c : Array.isArray(prevV) ? prevV : [];
|
|
2815
|
+
const nextPaths = (_d = nextV == null ? void 0 : nextV.paths) != null ? _d : Array.isArray(nextV) ? nextV : [];
|
|
2816
|
+
cssValue = interpolateBeziers(
|
|
2817
|
+
prevPaths,
|
|
2818
|
+
nextPaths,
|
|
2819
|
+
localProgress
|
|
2820
|
+
).map((bz) => bezierToSvgPath(bz)).join("");
|
|
2821
|
+
} else if (PX_COLOR_ATTR_NAMES.has(cssAttrName)) {
|
|
2822
|
+
cssValue = toRGBA(interpolateColor(
|
|
2823
|
+
prevV || [0, 0, 0, 1],
|
|
2824
|
+
nextV || [0, 0, 0, 1],
|
|
2825
|
+
localProgress
|
|
2826
|
+
));
|
|
2827
|
+
cssAttrName = propName;
|
|
2828
|
+
} else if (cssAttrName === "stroke-dasharray") {
|
|
2829
|
+
cssValue = interpolateVec(
|
|
2830
|
+
prevV || [],
|
|
2831
|
+
nextV || [],
|
|
2832
|
+
localProgress
|
|
2833
|
+
).join(" ");
|
|
2834
|
+
cssAttrName = propName;
|
|
2835
|
+
} else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
|
|
2836
|
+
const partKeys = /* @__PURE__ */ new Set([
|
|
2837
|
+
...prevV ? Object.keys(prevV) : [],
|
|
2838
|
+
...nextV ? Object.keys(nextV) : []
|
|
2839
|
+
]);
|
|
2840
|
+
const partsResult = {};
|
|
2841
|
+
for (const partKey of partKeys) {
|
|
2842
|
+
const prevPart = prevV == null ? void 0 : prevV[partKey];
|
|
2843
|
+
const nextPart = nextV == null ? void 0 : nextV[partKey];
|
|
2844
|
+
if (partKey === "rotate" || partKey === "skew") {
|
|
2845
|
+
partsResult[partKey] = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
|
|
2846
|
+
} else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
|
|
2847
|
+
const fallback = partKey === "scale" ? [1, 1] : [0, 0];
|
|
2848
|
+
const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
|
|
2849
|
+
partsResult[partKey] = interp;
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
if (propAnimIsMotionPath(propAnim)) {
|
|
2853
|
+
const prevTr = prevV.translate;
|
|
2854
|
+
const nextTr = nextV.translate;
|
|
2855
|
+
if (Array.isArray(prevTr) && Array.isArray(nextTr)) {
|
|
2856
|
+
const sample = evaluateMotionPathSegment(
|
|
2857
|
+
prevKf,
|
|
2858
|
+
nextKf,
|
|
2859
|
+
[+prevTr[0], +prevTr[1]],
|
|
2860
|
+
[+nextTr[0], +nextTr[1]],
|
|
2861
|
+
localProgress,
|
|
2862
|
+
!!propAnim.autoOrient
|
|
2863
|
+
);
|
|
2864
|
+
partsResult.translate = [sample.translate[0], sample.translate[1]];
|
|
2865
|
+
if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg + ((_e = partsResult.rotate) != null ? _e : 0);
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
cssValue = composeTransformParts(partsResult, { withUnits: false });
|
|
2869
|
+
cssAttrName = "transform";
|
|
2870
|
+
} else if (cssAttrName === "translate") {
|
|
2871
|
+
const v = interpolateVec(
|
|
2872
|
+
prevV || [0, 0],
|
|
2873
|
+
nextV || [0, 0],
|
|
2874
|
+
localProgress
|
|
2875
|
+
);
|
|
2876
|
+
cssValue = "translate(" + v.join(",") + ")";
|
|
2877
|
+
cssAttrName = "transform";
|
|
2878
|
+
} else if (cssAttrName === "rotate") {
|
|
2879
|
+
const v = interpolateNum(
|
|
2880
|
+
+(prevV || 0),
|
|
2881
|
+
+(nextV || 0),
|
|
2882
|
+
localProgress
|
|
2883
|
+
);
|
|
2884
|
+
cssValue = "rotate(" + v + ")";
|
|
2885
|
+
cssAttrName = "transform";
|
|
2886
|
+
} else if (cssAttrName === "scale") {
|
|
2887
|
+
const v = interpolateVec(
|
|
2888
|
+
prevV || [1, 1],
|
|
2889
|
+
nextV || [1, 1],
|
|
2890
|
+
localProgress
|
|
2891
|
+
);
|
|
2892
|
+
cssValue = "scale(" + v.join(",") + ")";
|
|
2893
|
+
cssAttrName = "transform";
|
|
2894
|
+
} else {
|
|
2895
|
+
const num2 = interpolateNum(
|
|
2896
|
+
+(prevV || 0),
|
|
2897
|
+
+(nextV || 0),
|
|
2898
|
+
localProgress
|
|
2899
|
+
);
|
|
2900
|
+
cssValue = num2;
|
|
2901
|
+
}
|
|
2902
|
+
if (PX_PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
|
|
2903
|
+
cssValue = cssValue * 100 + "%";
|
|
2904
|
+
}
|
|
2905
|
+
return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
|
|
2906
|
+
}
|
|
2907
|
+
function calcAnimationValues(animDef, progress) {
|
|
2908
|
+
const result = {};
|
|
2909
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
2910
|
+
const computed = calcPropertyValue(propName, propAnim, progress);
|
|
2911
|
+
if (computed) {
|
|
2912
|
+
result[computed.k] = computed.v;
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2915
|
+
return result;
|
|
2122
2916
|
}
|
|
2123
2917
|
|
|
2124
2918
|
// src/effects/PlayerEffectsUtil.visualModel.ts
|
|
@@ -2534,6 +3328,15 @@ function transformPathData(d, m, decimals = 2) {
|
|
|
2534
3328
|
}
|
|
2535
3329
|
|
|
2536
3330
|
// src/effects/shared/transformParts.ts
|
|
3331
|
+
function partsRecord(part, value, origin) {
|
|
3332
|
+
const rec = {};
|
|
3333
|
+
if (part === "translate" /* Translate */) rec.translate = value;
|
|
3334
|
+
else if (part === "rotate" /* Rotate */) rec.rotate = value;
|
|
3335
|
+
else if (part === "skew" /* Skew */) rec.skew = value;
|
|
3336
|
+
else rec.scale = value;
|
|
3337
|
+
if (origin && part !== "translate" /* Translate */) rec.origin = origin;
|
|
3338
|
+
return rec;
|
|
3339
|
+
}
|
|
2537
3340
|
function readAnimatable(raw) {
|
|
2538
3341
|
var _a2, _b;
|
|
2539
3342
|
if (raw === void 0) return { kind: "absent" /* Absent */ };
|
|
@@ -2552,6 +3355,24 @@ function readAnimatable(raw) {
|
|
|
2552
3355
|
}
|
|
2553
3356
|
return { kind: "static" /* Static */, value: raw };
|
|
2554
3357
|
}
|
|
3358
|
+
function writeAnimatableChannel(node, attrName, read, opts) {
|
|
3359
|
+
var _a2, _b, _c, _d;
|
|
3360
|
+
const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
|
|
3361
|
+
if (read.kind === "absent" /* Absent */) return;
|
|
3362
|
+
if (read.kind === "static" /* Static */) {
|
|
3363
|
+
node[attrName] = toOut(read.value);
|
|
3364
|
+
return;
|
|
3365
|
+
}
|
|
3366
|
+
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
3367
|
+
const animate = __spreadValues({}, prevAnimate || {});
|
|
3368
|
+
const block = { keyframes: read.keyframes };
|
|
3369
|
+
if (read.loop !== void 0) block.loop = read.loop;
|
|
3370
|
+
if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
|
|
3371
|
+
animate[attrName] = block;
|
|
3372
|
+
node.animate = animate;
|
|
3373
|
+
const baseline = (_d = (_b = read.base) != null ? _b : (_a2 = read.keyframes[0]) == null ? void 0 : _a2.value) != null ? _d : (_c = read.keyframes[0]) == null ? void 0 : _c.v;
|
|
3374
|
+
if (baseline !== void 0) node[attrName] = toOut(baseline);
|
|
3375
|
+
}
|
|
2555
3376
|
function normalizeKeyframe(kf) {
|
|
2556
3377
|
if (!kf || typeof kf !== "object") return kf;
|
|
2557
3378
|
const k = kf;
|
|
@@ -2566,6 +3387,22 @@ function normalizeKeyframe(kf) {
|
|
|
2566
3387
|
if (out.tangentIn === void 0 && k.ti !== void 0) out.tangentIn = k.ti;
|
|
2567
3388
|
return out;
|
|
2568
3389
|
}
|
|
3390
|
+
function readStaticOrigin(raw, ctx) {
|
|
3391
|
+
var _a2;
|
|
3392
|
+
const o = readAnimatable(raw);
|
|
3393
|
+
if (o.kind === "absent" /* Absent */) return void 0;
|
|
3394
|
+
if (o.kind === "static" /* Static */) return o.value;
|
|
3395
|
+
ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
|
|
3396
|
+
return (_a2 = o.keyframes[0]) == null ? void 0 : _a2.value;
|
|
3397
|
+
}
|
|
3398
|
+
function keyframeWith(kf, value) {
|
|
3399
|
+
const out = { value };
|
|
3400
|
+
if (kf.time !== void 0) out.time = kf.time;
|
|
3401
|
+
if (kf.easing !== void 0) out.easing = kf.easing;
|
|
3402
|
+
if (kf.tangentOut !== void 0) out.tangentOut = kf.tangentOut;
|
|
3403
|
+
if (kf.tangentIn !== void 0) out.tangentIn = kf.tangentIn;
|
|
3404
|
+
return out;
|
|
3405
|
+
}
|
|
2569
3406
|
|
|
2570
3407
|
// src/effects/text/textGlyphsEffect.ts
|
|
2571
3408
|
var DEFAULT_FONT_SIZE = 16;
|
|
@@ -3114,27 +3951,154 @@ function materializeGlyphText(node, opts) {
|
|
|
3114
3951
|
if (opts.alongPath) return materializeGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
|
|
3115
3952
|
return materializeGlyphTextHorizontal(node, opts);
|
|
3116
3953
|
}
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
if (read.kind === "static" /* Static */ && typeof read.value === "number") return { min: read.value, max: read.value };
|
|
3123
|
-
if (read.kind === "animated" /* Animated */ && read.keyframes.length) {
|
|
3124
|
-
const vals = read.keyframes.map((k) => Number(k.value) || 0);
|
|
3125
|
-
return { min: Math.min(...vals), max: Math.max(...vals) };
|
|
3954
|
+
function applyTextGlyphsEffect(node, fx, ctx) {
|
|
3955
|
+
if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
|
|
3956
|
+
if (!ctx.glyphs) {
|
|
3957
|
+
ctx.warnings.push("textGlyphs: no definitions.fonts \u2014 left as native <text>");
|
|
3958
|
+
return node;
|
|
3126
3959
|
}
|
|
3127
|
-
return {
|
|
3960
|
+
return materializeGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
|
|
3128
3961
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3962
|
+
function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
|
|
3963
|
+
if (!ctx.glyphs) {
|
|
3964
|
+
ctx.warnings.push("textGlyphs: no definitions.fonts");
|
|
3965
|
+
return null;
|
|
3966
|
+
}
|
|
3967
|
+
return materializeGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
|
|
3968
|
+
}
|
|
3969
|
+
|
|
3970
|
+
// src/util/PxNodeCloneUtil.ts
|
|
3971
|
+
function deepClonePxNode(value) {
|
|
3972
|
+
if (value === null || typeof value !== "object") return value;
|
|
3973
|
+
if (Array.isArray(value)) return value.map(deepClonePxNode);
|
|
3974
|
+
const out = {};
|
|
3975
|
+
for (const k of Object.keys(value)) out[k] = deepClonePxNode(value[k]);
|
|
3976
|
+
return out;
|
|
3977
|
+
}
|
|
3978
|
+
function regenerateIdsAndRewriteRefs(root, genId3) {
|
|
3979
|
+
const oldToNew = /* @__PURE__ */ new Map();
|
|
3980
|
+
const walkAssign = (n) => {
|
|
3981
|
+
var _a2;
|
|
3982
|
+
if (typeof n.id === "string") {
|
|
3983
|
+
const newId = genId3();
|
|
3984
|
+
oldToNew.set(n.id, newId);
|
|
3985
|
+
n.id = newId;
|
|
3986
|
+
}
|
|
3987
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(walkAssign);
|
|
3988
|
+
};
|
|
3989
|
+
walkAssign(root);
|
|
3990
|
+
const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
|
|
3991
|
+
const newId = oldToNew.get(oldId);
|
|
3992
|
+
return newId ? "url(#" + newId + ")" : m;
|
|
3993
|
+
});
|
|
3994
|
+
const walkRewrite = (n) => {
|
|
3995
|
+
var _a2;
|
|
3996
|
+
if (typeof n.href === "string" && n.href.startsWith("#")) {
|
|
3997
|
+
const newId = oldToNew.get(n.href.slice(1));
|
|
3998
|
+
if (newId) n.href = "#" + newId;
|
|
3999
|
+
}
|
|
4000
|
+
for (const k of Object.keys(n)) {
|
|
4001
|
+
if (k === "children" || k === "effects" || k === "meta" || k === "animate" || k === "href" || k === "id") continue;
|
|
4002
|
+
const v = n[k];
|
|
4003
|
+
if (typeof v === "string" && v.indexOf("url(#") !== -1) {
|
|
4004
|
+
n[k] = rewriteUrl(v);
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(walkRewrite);
|
|
4008
|
+
};
|
|
4009
|
+
walkRewrite(root);
|
|
4010
|
+
return oldToNew;
|
|
4011
|
+
}
|
|
4012
|
+
function toFiniteNum(v) {
|
|
4013
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? parseFloat(v) : NaN;
|
|
4014
|
+
return Number.isFinite(n) ? n : 0;
|
|
4015
|
+
}
|
|
4016
|
+
function applyUseOffsetToG(gNode) {
|
|
4017
|
+
var _a2;
|
|
4018
|
+
const x = toFiniteNum(gNode.x);
|
|
4019
|
+
const y = toFiniteNum(gNode.y);
|
|
4020
|
+
delete gNode.x;
|
|
4021
|
+
delete gNode.y;
|
|
4022
|
+
if (!x && !y) return gNode;
|
|
4023
|
+
const offset = "translate(" + x + "," + y + ")";
|
|
4024
|
+
const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
|
|
4025
|
+
if (carriesTransform) {
|
|
4026
|
+
const inner = { type: "g", transform: offset, children: (_a2 = gNode.children) != null ? _a2 : [] };
|
|
4027
|
+
gNode.children = [inner];
|
|
4028
|
+
} else {
|
|
4029
|
+
gNode.transform = offset;
|
|
4030
|
+
}
|
|
4031
|
+
return gNode;
|
|
4032
|
+
}
|
|
4033
|
+
|
|
4034
|
+
// src/effects/shared/util.ts
|
|
4035
|
+
function genId(ctx, prefix) {
|
|
4036
|
+
return "_lw_" + prefix + "_" + ctx.nextId++;
|
|
4037
|
+
}
|
|
4038
|
+
function stripHash(href) {
|
|
4039
|
+
return typeof href === "string" ? href.replace(/^#/, "") : void 0;
|
|
4040
|
+
}
|
|
4041
|
+
function indexById(node, map) {
|
|
4042
|
+
var _a2;
|
|
4043
|
+
if (typeof node.id === "string") map.set(node.id, node);
|
|
4044
|
+
(_a2 = node.children) == null ? void 0 : _a2.forEach((child) => indexById(child, map));
|
|
4045
|
+
}
|
|
4046
|
+
function spliceDefs(root, defs) {
|
|
4047
|
+
if (!defs.length) return;
|
|
4048
|
+
const existing = root.children || (root.children = []);
|
|
4049
|
+
existing.unshift({ type: "defs", children: defs });
|
|
4050
|
+
}
|
|
4051
|
+
var clone = deepClonePxNode;
|
|
4052
|
+
function regenerateIdsInClone(root, ctx) {
|
|
4053
|
+
return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
|
|
4054
|
+
}
|
|
4055
|
+
|
|
4056
|
+
// src/effects/text/textPathEffect.ts
|
|
4057
|
+
var EXTEND_MARGIN_FRAC = 0.15;
|
|
4058
|
+
function numRange(v) {
|
|
4059
|
+
const read = readAnimatable(v);
|
|
4060
|
+
if (read.kind === "static" /* Static */ && typeof read.value === "number") return { min: read.value, max: read.value };
|
|
4061
|
+
if (read.kind === "animated" /* Animated */ && read.keyframes.length) {
|
|
4062
|
+
const vals = read.keyframes.map((k) => Number(k.value) || 0);
|
|
4063
|
+
return { min: Math.min(...vals), max: Math.max(...vals) };
|
|
4064
|
+
}
|
|
4065
|
+
return { min: 0, max: 0 };
|
|
4066
|
+
}
|
|
4067
|
+
function estimateTextAdvance(node) {
|
|
4068
|
+
let chars = 0, maxFont = 16;
|
|
4069
|
+
const walk = (el) => {
|
|
4070
|
+
var _a2;
|
|
4071
|
+
const fs = parseFloat(String((_a2 = el.fontSize) != null ? _a2 : "")) || 0;
|
|
4072
|
+
if (fs) maxFont = Math.max(maxFont, fs);
|
|
4073
|
+
const t = el.textContent;
|
|
4074
|
+
if (typeof t === "string") chars += t.length;
|
|
4075
|
+
if (el.children) for (const c of el.children) walk(c);
|
|
4076
|
+
};
|
|
4077
|
+
walk(node);
|
|
4078
|
+
return chars * maxFont;
|
|
4079
|
+
}
|
|
4080
|
+
var r3 = (n) => Math.round(n * 1e3) / 1e3;
|
|
4081
|
+
function shiftAnimatable(v, by) {
|
|
4082
|
+
if (!by || v === void 0 || v === null) return v;
|
|
4083
|
+
const read = readAnimatable(v);
|
|
4084
|
+
if (read.kind === "absent" /* Absent */) return v;
|
|
4085
|
+
if (read.kind === "static" /* Static */) return typeof v === "number" ? read.value + by : { value: read.value + by };
|
|
4086
|
+
const out = {
|
|
4087
|
+
keyframes: read.keyframes.map((k) => __spreadProps(__spreadValues({}, k), { value: (Number(k.value) || 0) + by }))
|
|
4088
|
+
};
|
|
4089
|
+
if (read.loop !== void 0) out.loop = read.loop;
|
|
4090
|
+
if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
|
|
4091
|
+
if (read.base !== void 0) out.value = read.base + by;
|
|
4092
|
+
return out;
|
|
4093
|
+
}
|
|
4094
|
+
function extendedPathForBrowser(pathD, opts) {
|
|
4095
|
+
var _a2;
|
|
4096
|
+
if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
|
|
4097
|
+
const sampler = createPathSampler(pathD);
|
|
4098
|
+
if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
|
|
4099
|
+
const L = sampler.totalLength;
|
|
4100
|
+
const margin = EXTEND_MARGIN_FRAC * L;
|
|
4101
|
+
const so = numRange(opts.startOffset);
|
|
3138
4102
|
const runWidth = numRange(opts.textLength).max || ((_a2 = opts.advance) != null ? _a2 : 0);
|
|
3139
4103
|
const startOverflow = Math.max(0, -so.min);
|
|
3140
4104
|
const endOverflow = Math.max(0, so.max + runWidth - L);
|
|
@@ -3149,33 +4113,2083 @@ function extendedPathForBrowser(pathD, opts) {
|
|
|
3149
4113
|
const rest = pathD.replace(/^\s*[Mm]\s*-?[\d.]+[\s,]+-?[\d.]+/, "");
|
|
3150
4114
|
d = "M" + r3(sx) + "," + r3(sy) + "L" + r3(s.x) + "," + r3(s.y) + rest;
|
|
3151
4115
|
}
|
|
3152
|
-
if (endExt > 0) {
|
|
3153
|
-
const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;
|
|
3154
|
-
d += "L" + r3(ex) + "," + r3(ey);
|
|
4116
|
+
if (endExt > 0) {
|
|
4117
|
+
const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;
|
|
4118
|
+
d += "L" + r3(ex) + "," + r3(ey);
|
|
4119
|
+
}
|
|
4120
|
+
return { d, startShift: startExt };
|
|
4121
|
+
}
|
|
4122
|
+
function applyTextPathEffect(node, fx, ctx) {
|
|
4123
|
+
var _a2;
|
|
4124
|
+
if (!fx || typeof fx.pathData !== "string" || !fx.pathData) return node;
|
|
4125
|
+
const pathId = genId(ctx, "tpath");
|
|
4126
|
+
const { d, startShift } = extendedPathForBrowser(fx.pathData, {
|
|
4127
|
+
pathOverflow: fx.pathOverflow,
|
|
4128
|
+
startOffset: fx.startOffset,
|
|
4129
|
+
textLength: fx.textLength,
|
|
4130
|
+
advance: estimateTextAdvance(node)
|
|
4131
|
+
});
|
|
4132
|
+
ctx.defs.push({ type: "path", id: pathId, d });
|
|
4133
|
+
const textPath = {
|
|
4134
|
+
type: "textPath",
|
|
4135
|
+
href: "#" + pathId,
|
|
4136
|
+
children: (_a2 = node.children) != null ? _a2 : []
|
|
4137
|
+
};
|
|
4138
|
+
if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
|
|
4139
|
+
if (fx.method !== void 0) textPath.method = fx.method;
|
|
4140
|
+
if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
|
|
4141
|
+
applyAnimatableNumber(textPath, "startOffset", shiftAnimatable(fx.startOffset, startShift));
|
|
4142
|
+
applyAnimatableNumber(textPath, "textLength", fx.textLength);
|
|
4143
|
+
node.children = [textPath];
|
|
4144
|
+
return node;
|
|
4145
|
+
}
|
|
4146
|
+
function applyAnimatableNumber(node, attrName, raw) {
|
|
4147
|
+
if (raw === void 0 || raw === null) return;
|
|
4148
|
+
writeAnimatableChannel(node, attrName, readAnimatable(raw), { asString: true });
|
|
4149
|
+
}
|
|
4150
|
+
|
|
4151
|
+
// src/format/PxDocumentDiagnostic.ts
|
|
4152
|
+
var MAX_REPORTED = 6;
|
|
4153
|
+
function diagnoseDocument(doc) {
|
|
4154
|
+
try {
|
|
4155
|
+
return { problems: validateDocument(doc) };
|
|
4156
|
+
} catch (e) {
|
|
4157
|
+
return { problems: [] };
|
|
4158
|
+
}
|
|
4159
|
+
}
|
|
4160
|
+
function reportDocumentDiagnostics(doc, where) {
|
|
4161
|
+
const { problems } = diagnoseDocument(doc);
|
|
4162
|
+
if (!problems.length) return;
|
|
4163
|
+
const shown = problems.slice(0, MAX_REPORTED);
|
|
4164
|
+
const more = problems.length - shown.length;
|
|
4165
|
+
console.warn(
|
|
4166
|
+
where + ": this document does not match the animation schema in " + problems.length + " place" + (problems.length === 1 ? "" : "s") + ".\n" + shown.map((p) => " - " + p).join("\n") + (more > 0 ? "\n \u2026 and " + more + " more" : "") + "\n\nIf you did not author these keys, the usual cause is a build that MANGLES PROPERTY NAMES. An animation document is data loaded at runtime, so renaming the property reads inside the player stops them matching the keys in the JSON, and the animation silently does nothing. Feed the published reserved-name list to your minifier \u2014 @pixodesk/svg-animator-web/mangle-reserved.json \u2014 see docs/library/minification.md."
|
|
4167
|
+
);
|
|
4168
|
+
}
|
|
4169
|
+
|
|
4170
|
+
// src/effects/transform/transformationEffect.ts
|
|
4171
|
+
function applyTransformByEffect(node, fx, ctx) {
|
|
4172
|
+
if (!fx) return node;
|
|
4173
|
+
delete node.transform;
|
|
4174
|
+
let n = node;
|
|
4175
|
+
n = wrapOrigin(
|
|
4176
|
+
n,
|
|
4177
|
+
fx.origin,
|
|
4178
|
+
/*invert=*/
|
|
4179
|
+
true
|
|
4180
|
+
);
|
|
4181
|
+
n = wrapTransformPart(n, "scale" /* Scale */, normalizeScale(fx.scale), ctx);
|
|
4182
|
+
n = wrapTransformPart(n, "skew" /* Skew */, fx.skew, ctx);
|
|
4183
|
+
n = wrapTransformPart(n, "rotate" /* Rotate */, fx.rotate, ctx);
|
|
4184
|
+
n = wrapOrigin(
|
|
4185
|
+
n,
|
|
4186
|
+
fx.origin,
|
|
4187
|
+
/*invert=*/
|
|
4188
|
+
false
|
|
4189
|
+
);
|
|
4190
|
+
if (translateHasAutoOrient(fx.translate)) {
|
|
4191
|
+
n = wrapOrigin(
|
|
4192
|
+
n,
|
|
4193
|
+
fx.origin,
|
|
4194
|
+
/*invert=*/
|
|
4195
|
+
true
|
|
4196
|
+
);
|
|
4197
|
+
n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
|
|
4198
|
+
n = wrapOrigin(
|
|
4199
|
+
n,
|
|
4200
|
+
fx.origin,
|
|
4201
|
+
/*invert=*/
|
|
4202
|
+
false
|
|
4203
|
+
);
|
|
4204
|
+
} else {
|
|
4205
|
+
n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
|
|
4206
|
+
}
|
|
4207
|
+
if (n !== node && node.id) {
|
|
4208
|
+
n.id = node.id;
|
|
4209
|
+
delete node.id;
|
|
4210
|
+
}
|
|
4211
|
+
return n;
|
|
4212
|
+
}
|
|
4213
|
+
function translateHasAutoOrient(translate) {
|
|
4214
|
+
if (!translate || typeof translate !== "object") return false;
|
|
4215
|
+
const obj = translate;
|
|
4216
|
+
if (obj.autoOrient) return true;
|
|
4217
|
+
return Array.isArray(obj.keyframes) && obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
|
|
4218
|
+
}
|
|
4219
|
+
function normalizeScale(raw) {
|
|
4220
|
+
return raw;
|
|
4221
|
+
}
|
|
4222
|
+
function wrapTransformPart(inner, part, raw, ctx) {
|
|
4223
|
+
if (raw === void 0) return inner;
|
|
4224
|
+
const v = readAnimatable(raw);
|
|
4225
|
+
if (v.kind === "static" /* Static */) {
|
|
4226
|
+
return { type: "g", transform: { value: partsRecord(part, v.value, void 0) }, children: [inner] };
|
|
4227
|
+
}
|
|
4228
|
+
if (v.kind === "animated" /* Animated */) {
|
|
4229
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
|
|
4230
|
+
if (v.autoOrient) animTr.autoOrient = true;
|
|
4231
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
4232
|
+
return {
|
|
4233
|
+
type: "g",
|
|
4234
|
+
animate: { transform: animTr },
|
|
4235
|
+
children: [inner]
|
|
4236
|
+
};
|
|
4237
|
+
}
|
|
4238
|
+
return inner;
|
|
4239
|
+
}
|
|
4240
|
+
function wrapOrigin(inner, raw, invert) {
|
|
4241
|
+
if (raw === void 0) return inner;
|
|
4242
|
+
const v = readAnimatable(raw);
|
|
4243
|
+
const sign = (value) => invert ? [-value[0], -value[1]] : value;
|
|
4244
|
+
if (v.kind === "absent" /* Absent */) return inner;
|
|
4245
|
+
if (v.kind === "static" /* Static */) {
|
|
4246
|
+
if (v.value[0] === 0 && v.value[1] === 0) return inner;
|
|
4247
|
+
return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
|
|
4248
|
+
}
|
|
4249
|
+
if (v.kind === "animated" /* Animated */) {
|
|
4250
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) };
|
|
4251
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
4252
|
+
return {
|
|
4253
|
+
type: "g",
|
|
4254
|
+
animate: { transform: animTr },
|
|
4255
|
+
children: [inner]
|
|
4256
|
+
};
|
|
4257
|
+
}
|
|
4258
|
+
return inner;
|
|
4259
|
+
}
|
|
4260
|
+
|
|
4261
|
+
// src/effects/reference/contentRefSplit.ts
|
|
4262
|
+
function identifyContentRefTargets(node, ctx, allocator) {
|
|
4263
|
+
var _a2, _b, _c;
|
|
4264
|
+
if (node.type === "use" && ((_b = (_a2 = node.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.without) === "translate") {
|
|
4265
|
+
const sourceId = stripHash(node.effects.clone.source);
|
|
4266
|
+
if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
|
|
4267
|
+
ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
(_c = node.children) == null ? void 0 : _c.forEach((c) => identifyContentRefTargets(c, ctx, allocator));
|
|
4271
|
+
}
|
|
4272
|
+
function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
|
|
4273
|
+
const outerBody = liftBodyTranslate(node, transformBy);
|
|
4274
|
+
if (typeof node.id === "string") delete node.id;
|
|
4275
|
+
const { outer: outerTr, inner: innerTr } = splitTransformByEffect(transformBy);
|
|
4276
|
+
let innerNode = node;
|
|
4277
|
+
innerNode = applyTransformByEffect(innerNode, innerTr, ctx);
|
|
4278
|
+
const innerWrapper = { type: "g", id: innerId, children: [innerNode] };
|
|
4279
|
+
let outerWrapper = { type: "g", id: originalId, children: [innerWrapper] };
|
|
4280
|
+
if (outerBody.transform !== void 0) outerWrapper.transform = outerBody.transform;
|
|
4281
|
+
if (outerBody.animate !== void 0) outerWrapper.animate = outerBody.animate;
|
|
4282
|
+
if (outerTr) {
|
|
4283
|
+
delete outerWrapper.id;
|
|
4284
|
+
outerWrapper = applyTransformByEffect(outerWrapper, outerTr, ctx);
|
|
4285
|
+
outerWrapper.id = originalId;
|
|
4286
|
+
}
|
|
4287
|
+
return outerWrapper;
|
|
4288
|
+
}
|
|
4289
|
+
function liftBodyTranslate(node, transformBy) {
|
|
4290
|
+
var _a2, _b, _c;
|
|
4291
|
+
const out = {};
|
|
4292
|
+
let didLiftAnimate = false;
|
|
4293
|
+
const animTr = (_a2 = node.animate) == null ? void 0 : _a2.transform;
|
|
4294
|
+
if (animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes)) {
|
|
4295
|
+
const kfs = animTr.keyframes;
|
|
4296
|
+
const hasTranslate = kfs.some((kf) => kf.value && kf.value.translate);
|
|
4297
|
+
if (hasTranslate) {
|
|
4298
|
+
const outerHasOrigin = needsOriginOnOuter(animTr);
|
|
4299
|
+
const outerKfs = kfs.map((kf) => {
|
|
4300
|
+
const v = kf.value || {};
|
|
4301
|
+
const newValue = {};
|
|
4302
|
+
if (v.translate !== void 0) newValue.translate = v.translate;
|
|
4303
|
+
if (outerHasOrigin && v.origin !== void 0) newValue.origin = v.origin;
|
|
4304
|
+
const outerKf = { value: newValue };
|
|
4305
|
+
if (kf.time !== void 0) outerKf.time = kf.time;
|
|
4306
|
+
if (kf.easing !== void 0) outerKf.easing = kf.easing;
|
|
4307
|
+
if (kf.tangentOut !== void 0) outerKf.tangentOut = kf.tangentOut;
|
|
4308
|
+
if (kf.tangentIn !== void 0) outerKf.tangentIn = kf.tangentIn;
|
|
4309
|
+
return outerKf;
|
|
4310
|
+
});
|
|
4311
|
+
const outerAnimTr = { keyframes: outerKfs };
|
|
4312
|
+
if (animTr.autoOrient) outerAnimTr.autoOrient = true;
|
|
4313
|
+
const srcLoop = animTr.loop;
|
|
4314
|
+
if (srcLoop !== void 0) outerAnimTr.loop = srcLoop;
|
|
4315
|
+
out.animate = { transform: outerAnimTr };
|
|
4316
|
+
const innerHasPivotedPart = kfs.some((kf) => {
|
|
4317
|
+
const v = kf.value || {};
|
|
4318
|
+
return v.rotate !== void 0 || v.scale !== void 0;
|
|
4319
|
+
});
|
|
4320
|
+
const innerKfs = kfs.map((kf) => {
|
|
4321
|
+
const v = kf.value || {};
|
|
4322
|
+
const newValue = {};
|
|
4323
|
+
if (v.rotate !== void 0) newValue.rotate = v.rotate;
|
|
4324
|
+
if (v.scale !== void 0) newValue.scale = v.scale;
|
|
4325
|
+
if (v.origin !== void 0 && (!outerHasOrigin || innerHasPivotedPart)) newValue.origin = v.origin;
|
|
4326
|
+
const innerKf = { value: newValue };
|
|
4327
|
+
if (kf.time !== void 0) innerKf.time = kf.time;
|
|
4328
|
+
if (kf.easing !== void 0) innerKf.easing = kf.easing;
|
|
4329
|
+
return innerKf;
|
|
4330
|
+
});
|
|
4331
|
+
const allInnerEmpty = innerKfs.every((kf) => Object.keys(kf.value).length === 0);
|
|
4332
|
+
if (allInnerEmpty) {
|
|
4333
|
+
delete node.animate.transform;
|
|
4334
|
+
if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;
|
|
4335
|
+
} else {
|
|
4336
|
+
const innerAnimTr = { keyframes: innerKfs };
|
|
4337
|
+
if (srcLoop !== void 0) innerAnimTr.loop = srcLoop;
|
|
4338
|
+
node.animate.transform = innerAnimTr;
|
|
4339
|
+
}
|
|
4340
|
+
didLiftAnimate = true;
|
|
4341
|
+
}
|
|
4342
|
+
}
|
|
4343
|
+
const transformationHasTranslate = (transformBy == null ? void 0 : transformBy.translate) !== void 0;
|
|
4344
|
+
const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
|
|
4345
|
+
const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter(((_b = node.animate) == null ? void 0 : _b.transform) || void 0) || didLiftAnimate && needsOriginOnOuter(((_c = out.animate) == null ? void 0 : _c.transform) || void 0);
|
|
4346
|
+
if (typeof node.transform === "string") {
|
|
4347
|
+
const split = splitTransformString(node.transform);
|
|
4348
|
+
if (stripBodyTranslateOnly) {
|
|
4349
|
+
if (split.translate !== void 0) {
|
|
4350
|
+
if (split.rest) node.transform = split.rest;
|
|
4351
|
+
else delete node.transform;
|
|
4352
|
+
} else if (isPureTranslateBody(node.transform)) {
|
|
4353
|
+
delete node.transform;
|
|
4354
|
+
} else if (liftedAnimateIsAutoOriented && isSingleMatrixBody(node.transform)) {
|
|
4355
|
+
delete node.transform;
|
|
4356
|
+
}
|
|
4357
|
+
} else if (split.translate) {
|
|
4358
|
+
out.transform = split.translate;
|
|
4359
|
+
if (split.rest) node.transform = split.rest;
|
|
4360
|
+
else delete node.transform;
|
|
4361
|
+
}
|
|
4362
|
+
} else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes) {
|
|
4363
|
+
const wrapped = node.transform.value;
|
|
4364
|
+
const isWrapped = !!(wrapped && typeof wrapped === "object");
|
|
4365
|
+
const value = isWrapped ? wrapped : node.transform;
|
|
4366
|
+
const rewrap = (rec) => isWrapped ? { value: rec } : rec;
|
|
4367
|
+
if (Array.isArray(value.translate)) {
|
|
4368
|
+
const rest = __spreadValues({}, value);
|
|
4369
|
+
delete rest.translate;
|
|
4370
|
+
const hasRest = Object.keys(rest).length > 0;
|
|
4371
|
+
if (stripBodyTranslateOnly) {
|
|
4372
|
+
if (hasRest) node.transform = rewrap(rest);
|
|
4373
|
+
else delete node.transform;
|
|
4374
|
+
} else {
|
|
4375
|
+
out.transform = rewrap({ translate: value.translate });
|
|
4376
|
+
if (hasRest) node.transform = rewrap(rest);
|
|
4377
|
+
else delete node.transform;
|
|
4378
|
+
}
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
return out;
|
|
4382
|
+
}
|
|
4383
|
+
function isSingleMatrixBody(s) {
|
|
4384
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
4385
|
+
let count = 0;
|
|
4386
|
+
let isMatrix = false;
|
|
4387
|
+
let m;
|
|
4388
|
+
while (m = re.exec(s)) {
|
|
4389
|
+
count++;
|
|
4390
|
+
if (m[1] === "matrix") isMatrix = true;
|
|
4391
|
+
}
|
|
4392
|
+
return count === 1 && isMatrix;
|
|
4393
|
+
}
|
|
4394
|
+
function isPureTranslateBody(s) {
|
|
4395
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
4396
|
+
const ops = [];
|
|
4397
|
+
let m;
|
|
4398
|
+
while (m = re.exec(s)) ops.push({ name: m[1], full: m[0] });
|
|
4399
|
+
if (ops.length !== 1) return false;
|
|
4400
|
+
if (ops[0].name === "translate") return true;
|
|
4401
|
+
if (ops[0].name !== "matrix") return false;
|
|
4402
|
+
const args = /matrix\(([^)]*)\)/.exec(ops[0].full);
|
|
4403
|
+
if (!args) return false;
|
|
4404
|
+
const nums = args[1].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
4405
|
+
return nums.length >= 4 && nums[0] === 1 && nums[1] === 0 && nums[2] === 0 && nums[3] === 1;
|
|
4406
|
+
}
|
|
4407
|
+
function splitTransformString(s) {
|
|
4408
|
+
const ops = [];
|
|
4409
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
4410
|
+
let m;
|
|
4411
|
+
while (m = re.exec(s)) ops.push({ name: m[1], full: m[0] });
|
|
4412
|
+
if (!ops.length) return { rest: s || void 0 };
|
|
4413
|
+
if (ops.every((o) => o.name === "translate")) {
|
|
4414
|
+
return { translate: ops.map((o) => o.full).join("") };
|
|
4415
|
+
}
|
|
4416
|
+
const leading = ops[0];
|
|
4417
|
+
const trailing = ops[ops.length - 1];
|
|
4418
|
+
if (trailing.name === "translate" && leading.name === "translate") {
|
|
4419
|
+
const trailingVec = parseTranslateArgs(trailing.full);
|
|
4420
|
+
const leadingVec = parseTranslateArgs(leading.full);
|
|
4421
|
+
const ox = -trailingVec[0];
|
|
4422
|
+
const oy = -trailingVec[1];
|
|
4423
|
+
const userTx = leadingVec[0] - ox;
|
|
4424
|
+
const userTy = leadingVec[1] - oy;
|
|
4425
|
+
if (userTx === 0 && userTy === 0) return { rest: s };
|
|
4426
|
+
const middleAndTrailing = "translate(" + ox + "," + oy + ")" + ops.slice(1).map((o) => o.full).join("");
|
|
4427
|
+
return { translate: "translate(" + userTx + "," + userTy + ")", rest: middleAndTrailing };
|
|
4428
|
+
}
|
|
4429
|
+
if (trailing.name === "translate") return { rest: s };
|
|
4430
|
+
const lifted = [];
|
|
4431
|
+
let i = 0;
|
|
4432
|
+
while (i < ops.length && ops[i].name === "translate") {
|
|
4433
|
+
lifted.push(ops[i].full);
|
|
4434
|
+
i++;
|
|
4435
|
+
}
|
|
4436
|
+
if (!lifted.length) return { rest: s };
|
|
4437
|
+
const rest = ops.slice(i).map((o) => o.full).join("");
|
|
4438
|
+
return {
|
|
4439
|
+
translate: lifted.join(""),
|
|
4440
|
+
rest: rest || void 0
|
|
4441
|
+
};
|
|
4442
|
+
}
|
|
4443
|
+
function parseTranslateArgs(translateOp) {
|
|
4444
|
+
const m = /translate\(([^)]*)\)/.exec(translateOp);
|
|
4445
|
+
if (!m) return [0, 0];
|
|
4446
|
+
const nums = m[1].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
4447
|
+
return [nums[0] || 0, nums[1] || 0];
|
|
4448
|
+
}
|
|
4449
|
+
function splitTransformByEffect(fx) {
|
|
4450
|
+
if (!fx) return {};
|
|
4451
|
+
const originOnOuter = needsOriginOnOuter(fx.translate);
|
|
4452
|
+
const innerHasPivotedPart = fx.rotate !== void 0 || fx.scale !== void 0;
|
|
4453
|
+
const outer = {};
|
|
4454
|
+
const inner = {};
|
|
4455
|
+
if (fx.translate !== void 0) outer.translate = fx.translate;
|
|
4456
|
+
if (originOnOuter && fx.origin !== void 0) outer.origin = fx.origin;
|
|
4457
|
+
if (fx.rotate !== void 0) inner.rotate = fx.rotate;
|
|
4458
|
+
if (fx.scale !== void 0) inner.scale = fx.scale;
|
|
4459
|
+
if (fx.skew !== void 0) inner.skew = fx.skew;
|
|
4460
|
+
if (fx.origin !== void 0 && (!originOnOuter || innerHasPivotedPart)) inner.origin = fx.origin;
|
|
4461
|
+
return {
|
|
4462
|
+
outer: Object.keys(outer).length ? outer : void 0,
|
|
4463
|
+
inner: Object.keys(inner).length ? inner : void 0
|
|
4464
|
+
};
|
|
4465
|
+
}
|
|
4466
|
+
function needsOriginOnOuter(translateAnim) {
|
|
4467
|
+
if (!translateAnim || typeof translateAnim !== "object") return false;
|
|
4468
|
+
const obj = translateAnim;
|
|
4469
|
+
if (obj.autoOrient) return true;
|
|
4470
|
+
if (Array.isArray(obj.keyframes)) {
|
|
4471
|
+
return obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
|
|
4472
|
+
}
|
|
4473
|
+
return false;
|
|
4474
|
+
}
|
|
4475
|
+
|
|
4476
|
+
// src/effects/paint/gradientEffect.ts
|
|
4477
|
+
function applyFillGradientEffect(node, fx, ctx) {
|
|
4478
|
+
return applyGradient(node, fx, ctx, "fill");
|
|
4479
|
+
}
|
|
4480
|
+
function applyStrokeGradientEffect(node, fx, ctx) {
|
|
4481
|
+
return applyGradient(node, fx, ctx, "stroke");
|
|
4482
|
+
}
|
|
4483
|
+
function applyGradient(node, fx, ctx, attr) {
|
|
4484
|
+
if (!fx) return node;
|
|
4485
|
+
const id = genId(ctx, "grad");
|
|
4486
|
+
const def = synthesiseGradientDef(fx, id, ctx);
|
|
4487
|
+
ctx.defs.push(def);
|
|
4488
|
+
node[attr] = "url(#" + id + ")";
|
|
4489
|
+
return node;
|
|
4490
|
+
}
|
|
4491
|
+
function synthesiseGradientDef(fx, id, ctx) {
|
|
4492
|
+
const out = {
|
|
4493
|
+
type: fx.type === PxGradientType.radial ? "radialGradient" : "linearGradient",
|
|
4494
|
+
id
|
|
4495
|
+
};
|
|
4496
|
+
if (fx.type === PxGradientType.linear) {
|
|
4497
|
+
applyGeomVec(out, "x1", "y1", fx.start);
|
|
4498
|
+
applyGeomVec(out, "x2", "y2", fx.end);
|
|
4499
|
+
} else {
|
|
4500
|
+
applyGeomVec(out, "cx", "cy", fx.center);
|
|
4501
|
+
applyGeomNumber(out, "r", fx.radius);
|
|
4502
|
+
applyGeomVec(out, "fx", "fy", fx.focal);
|
|
4503
|
+
}
|
|
4504
|
+
if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
|
|
4505
|
+
if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
|
|
4506
|
+
if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
|
|
4507
|
+
out.children = buildStopChildren(fx.stops, ctx);
|
|
4508
|
+
return out;
|
|
4509
|
+
}
|
|
4510
|
+
function applyGeomVec(out, xAttr, yAttr, raw) {
|
|
4511
|
+
var _a2, _b, _c;
|
|
4512
|
+
const read = readAnimatable(raw);
|
|
4513
|
+
if (read.kind === "absent" /* Absent */) return;
|
|
4514
|
+
if (read.kind === "static" /* Static */) {
|
|
4515
|
+
out[xAttr] = String(read.value[0]);
|
|
4516
|
+
out[yAttr] = String(read.value[1]);
|
|
4517
|
+
return;
|
|
4518
|
+
}
|
|
4519
|
+
const axisChannel = (idx) => {
|
|
4520
|
+
const block = {
|
|
4521
|
+
keyframes: read.keyframes.map((kf) => {
|
|
4522
|
+
const axisKf = { time: kf.time, value: Array.isArray(kf.value) ? kf.value[idx] : void 0 };
|
|
4523
|
+
if (kf.easing !== void 0) axisKf.easing = kf.easing;
|
|
4524
|
+
return axisKf;
|
|
4525
|
+
})
|
|
4526
|
+
};
|
|
4527
|
+
if (read.loop !== void 0) block.loop = read.loop;
|
|
4528
|
+
return block;
|
|
4529
|
+
};
|
|
4530
|
+
const animate = (_a2 = out.animate) != null ? _a2 : {};
|
|
4531
|
+
animate[xAttr] = axisChannel(0);
|
|
4532
|
+
animate[yAttr] = axisChannel(1);
|
|
4533
|
+
out.animate = animate;
|
|
4534
|
+
const baseline = (_c = read.base) != null ? _c : (_b = read.keyframes[0]) == null ? void 0 : _b.value;
|
|
4535
|
+
if (Array.isArray(baseline)) {
|
|
4536
|
+
out[xAttr] = String(baseline[0]);
|
|
4537
|
+
out[yAttr] = String(baseline[1]);
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4540
|
+
function applyGeomNumber(out, attrName, raw) {
|
|
4541
|
+
const read = readAnimatable(raw);
|
|
4542
|
+
if (read.kind === "absent" /* Absent */) return;
|
|
4543
|
+
writeAnimatableChannel(out, attrName, read, { asString: true });
|
|
4544
|
+
}
|
|
4545
|
+
function buildStopChildren(stops, ctx) {
|
|
4546
|
+
var _a2, _b;
|
|
4547
|
+
if (!stops) return [];
|
|
4548
|
+
const read = readAnimatable(stops);
|
|
4549
|
+
if (read.kind === "absent" /* Absent */) return [];
|
|
4550
|
+
if (read.kind === "static" /* Static */) return Array.isArray(read.value) ? read.value.map(staticStopNode) : [];
|
|
4551
|
+
const kfs = read.keyframes;
|
|
4552
|
+
if (!kfs.length) return [];
|
|
4553
|
+
const loopFromSource = read.loop;
|
|
4554
|
+
let stopCount = 0;
|
|
4555
|
+
for (const kf of kfs) {
|
|
4556
|
+
const v = keyframeValue(kf);
|
|
4557
|
+
if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
|
|
4558
|
+
}
|
|
4559
|
+
if (!stopCount) return [];
|
|
4560
|
+
const firstKfValue = keyframeValue(kfs[0]);
|
|
4561
|
+
const baselineStops = [];
|
|
4562
|
+
for (let i = 0; i < stopCount; i++) {
|
|
4563
|
+
const s = (_b = (_a2 = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _a2 : prevDefinedStop(kfs, 0, i)) != null ? _b : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
|
|
4564
|
+
baselineStops.push({ offset: s.offset, color: s.color });
|
|
4565
|
+
}
|
|
4566
|
+
return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
|
|
4567
|
+
}
|
|
4568
|
+
function staticStopNode(s) {
|
|
4569
|
+
return {
|
|
4570
|
+
type: "stop",
|
|
4571
|
+
offset: formatOffset(s.offset),
|
|
4572
|
+
stopColor: s.color
|
|
4573
|
+
};
|
|
4574
|
+
}
|
|
4575
|
+
function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
|
|
4576
|
+
var _a2;
|
|
4577
|
+
const colorKfs = [];
|
|
4578
|
+
const offsetKfs = [];
|
|
4579
|
+
let offsetVaries = false;
|
|
4580
|
+
for (const kf of kfs) {
|
|
4581
|
+
const t = keyframeTime(kf);
|
|
4582
|
+
const arr = keyframeValue(kf);
|
|
4583
|
+
const sliced = (_a2 = arr == null ? void 0 : arr[stopIdx]) != null ? _a2 : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
|
|
4584
|
+
if (!sliced) continue;
|
|
4585
|
+
const easing = keyframeEasing(kf);
|
|
4586
|
+
const colorOut = { time: t, value: sliced.color };
|
|
4587
|
+
if (easing !== void 0) colorOut.easing = easing;
|
|
4588
|
+
colorKfs.push(colorOut);
|
|
4589
|
+
const offsetOut = { time: t, value: sliced.offset };
|
|
4590
|
+
if (easing !== void 0) offsetOut.easing = easing;
|
|
4591
|
+
offsetKfs.push(offsetOut);
|
|
4592
|
+
if (sliced.offset !== baseline.offset) offsetVaries = true;
|
|
4593
|
+
}
|
|
4594
|
+
const stop = {
|
|
4595
|
+
type: "stop",
|
|
4596
|
+
offset: formatOffset(baseline.offset),
|
|
4597
|
+
stopColor: baseline.color
|
|
4598
|
+
};
|
|
4599
|
+
const animate = {};
|
|
4600
|
+
if (colorKfs.length) {
|
|
4601
|
+
animate.stopColor = { keyframes: colorKfs };
|
|
4602
|
+
if (loop !== void 0) animate.stopColor.loop = loop;
|
|
4603
|
+
}
|
|
4604
|
+
if (offsetVaries && offsetKfs.length) {
|
|
4605
|
+
animate.offset = { keyframes: offsetKfs };
|
|
4606
|
+
if (loop !== void 0) animate.offset.loop = loop;
|
|
4607
|
+
}
|
|
4608
|
+
if (Object.keys(animate).length) stop.animate = animate;
|
|
4609
|
+
return stop;
|
|
4610
|
+
}
|
|
4611
|
+
function prevDefinedStop(kfs, fromIdx, stopIdx) {
|
|
4612
|
+
for (let i = fromIdx; i >= 0; i--) {
|
|
4613
|
+
const arr = keyframeValue(kfs[i]);
|
|
4614
|
+
if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
|
|
4615
|
+
}
|
|
4616
|
+
for (let i = fromIdx + 1; i < kfs.length; i++) {
|
|
4617
|
+
const arr = keyframeValue(kfs[i]);
|
|
4618
|
+
if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
|
|
4619
|
+
}
|
|
4620
|
+
return void 0;
|
|
4621
|
+
}
|
|
4622
|
+
function formatOffset(o) {
|
|
4623
|
+
const pct = Math.round(o * 1e3) / 10;
|
|
4624
|
+
return pct + "%";
|
|
4625
|
+
}
|
|
4626
|
+
|
|
4627
|
+
// src/effects/clipping/clipPathEffect.ts
|
|
4628
|
+
function applyClipPathEffect(node, fx, ctx) {
|
|
4629
|
+
if (!(fx == null ? void 0 : fx.pathData)) return node;
|
|
4630
|
+
const clipId = genId(ctx, "clip");
|
|
4631
|
+
const pathChild = { type: "path" };
|
|
4632
|
+
const read = readAnimatable(fx.pathData);
|
|
4633
|
+
if (read.kind !== "absent" /* Absent */) {
|
|
4634
|
+
if (read.kind === "static" /* Static */) {
|
|
4635
|
+
pathChild.d = pathString(read.value);
|
|
4636
|
+
} else {
|
|
4637
|
+
writeAnimatableChannel(pathChild, "d", read);
|
|
4638
|
+
if (pathChild.d !== void 0) pathChild.d = pathString(pathChild.d);
|
|
4639
|
+
}
|
|
4640
|
+
}
|
|
4641
|
+
ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
|
|
4642
|
+
node.clipPath = "url(#" + clipId + ")";
|
|
4643
|
+
return node;
|
|
4644
|
+
}
|
|
4645
|
+
function pathString(v) {
|
|
4646
|
+
if (typeof v === "string") return v;
|
|
4647
|
+
if (v && typeof v === "object" && typeof v.pathData === "string") return v.pathData;
|
|
4648
|
+
return void 0;
|
|
4649
|
+
}
|
|
4650
|
+
|
|
4651
|
+
// src/effects/clipping/maskedByEffect.ts
|
|
4652
|
+
function applyMaskedByEffect(node, fx, transformBy, ctx) {
|
|
4653
|
+
if (!fx) return node;
|
|
4654
|
+
const sourceId = stripHash(fx.source);
|
|
4655
|
+
if (!sourceId) {
|
|
4656
|
+
ctx.errors.push("maskedBy.source missing \u2014 cannot build mask");
|
|
4657
|
+
return node;
|
|
4658
|
+
}
|
|
4659
|
+
const maskId = genId(ctx, "mask");
|
|
4660
|
+
let content = { type: "use", href: "#" + sourceId };
|
|
4661
|
+
if (transformBy) {
|
|
4662
|
+
content = wrapInverseTransform(content, transformBy, ctx);
|
|
4663
|
+
} else if (hasAnimateTransform(node)) {
|
|
4664
|
+
content = wrapInverseAnimatedBodyTransform(content, node, ctx);
|
|
4665
|
+
} else {
|
|
4666
|
+
const bodyStatic = readTransformationFromBody(node);
|
|
4667
|
+
if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
|
|
4668
|
+
}
|
|
4669
|
+
const includeTargetOwn = transformBy === void 0 && !nodeHasBodyTransform(node);
|
|
4670
|
+
content = wrapAncestorChainCompensation(content, node, sourceId, ctx, includeTargetOwn);
|
|
4671
|
+
const mask = { type: "mask", id: maskId, children: [content] };
|
|
4672
|
+
if (fx.maskType) mask.maskType = fx.maskType;
|
|
4673
|
+
if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
|
|
4674
|
+
if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
|
|
4675
|
+
if (fx.x !== void 0) mask.x = String(fx.x);
|
|
4676
|
+
if (fx.y !== void 0) mask.y = String(fx.y);
|
|
4677
|
+
if (fx.width !== void 0) mask.width = String(fx.width);
|
|
4678
|
+
if (fx.height !== void 0) mask.height = String(fx.height);
|
|
4679
|
+
ctx.defs.push(mask);
|
|
4680
|
+
node.mask = "url(#" + maskId + ")";
|
|
4681
|
+
return node;
|
|
4682
|
+
}
|
|
4683
|
+
function wrapInverseTransform(inner, fx, ctx) {
|
|
4684
|
+
if (!fx) return inner;
|
|
4685
|
+
const origin = readStaticOrigin(fx.origin, ctx);
|
|
4686
|
+
let n = inner;
|
|
4687
|
+
n = wrapInversePart(n, "translate" /* Translate */, fx.translate, void 0, ctx);
|
|
4688
|
+
n = wrapInversePart(n, "rotate" /* Rotate */, fx.rotate, origin, ctx);
|
|
4689
|
+
n = wrapInversePart(n, "scale" /* Scale */, fx.scale, origin, ctx);
|
|
4690
|
+
return n;
|
|
4691
|
+
}
|
|
4692
|
+
function wrapInversePart(inner, part, raw, origin, ctx) {
|
|
4693
|
+
if (raw === void 0) return inner;
|
|
4694
|
+
const normalizedRaw = part === "scale" /* Scale */ && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
|
|
4695
|
+
const v = readAnimatable(normalizedRaw);
|
|
4696
|
+
if (v.kind === "static" /* Static */) {
|
|
4697
|
+
return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
|
|
4698
|
+
}
|
|
4699
|
+
if (v.kind === "animated" /* Animated */) {
|
|
4700
|
+
const animTr = { keyframes: v.keyframes.map((kf) => {
|
|
4701
|
+
const out = keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin));
|
|
4702
|
+
return part === "translate" /* Translate */ ? __spreadValues(__spreadValues({}, out), negatedSpatialTangents(kf)) : out;
|
|
4703
|
+
}) };
|
|
4704
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
4705
|
+
return {
|
|
4706
|
+
type: "g",
|
|
4707
|
+
animate: { transform: animTr },
|
|
4708
|
+
children: [inner]
|
|
4709
|
+
};
|
|
4710
|
+
}
|
|
4711
|
+
return inner;
|
|
4712
|
+
}
|
|
4713
|
+
function invertPartValue(part, value) {
|
|
4714
|
+
if (part === "translate" /* Translate */) return [-value[0], -value[1]];
|
|
4715
|
+
if (part === "rotate" /* Rotate */) return -value;
|
|
4716
|
+
return [1 / value[0], 1 / value[1]];
|
|
4717
|
+
}
|
|
4718
|
+
function negatedSpatialTangents(kf) {
|
|
4719
|
+
var _a2, _b;
|
|
4720
|
+
const out = {};
|
|
4721
|
+
const to = (_a2 = kf.tangentOut) != null ? _a2 : kf.to;
|
|
4722
|
+
const ti = (_b = kf.tangentIn) != null ? _b : kf.ti;
|
|
4723
|
+
if (Array.isArray(to)) out.tangentOut = [-to[0], -to[1]];
|
|
4724
|
+
if (Array.isArray(ti)) out.tangentIn = [-ti[0], -ti[1]];
|
|
4725
|
+
return out;
|
|
4726
|
+
}
|
|
4727
|
+
function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
|
|
4728
|
+
var _a2;
|
|
4729
|
+
const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
4730
|
+
const animTr = animate == null ? void 0 : animate.transform;
|
|
4731
|
+
const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
|
|
4732
|
+
if (!kfs || !kfs.length) return inner;
|
|
4733
|
+
const translateKfs = [];
|
|
4734
|
+
const rotateKfs = [];
|
|
4735
|
+
const scaleKfs = [];
|
|
4736
|
+
for (const kf of kfs) {
|
|
4737
|
+
const v = ((_a2 = kf.value) != null ? _a2 : kf.v) || {};
|
|
4738
|
+
const baseKf = keyframeWith(kf, void 0);
|
|
4739
|
+
if (Array.isArray(v.translate)) {
|
|
4740
|
+
translateKfs.push(__spreadProps(__spreadValues(__spreadValues({}, baseKf), negatedSpatialTangents(kf)), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
|
|
4741
|
+
}
|
|
4742
|
+
if (typeof v.rotate === "number") {
|
|
4743
|
+
const rec = { rotate: -v.rotate };
|
|
4744
|
+
if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
|
|
4745
|
+
rotateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
4746
|
+
}
|
|
4747
|
+
if (Array.isArray(v.scale)) {
|
|
4748
|
+
const rec = { scale: [1 / v.scale[0], 1 / v.scale[1]] };
|
|
4749
|
+
if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
|
|
4750
|
+
scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
4751
|
+
}
|
|
4752
|
+
}
|
|
4753
|
+
const srcLoop = animTr == null ? void 0 : animTr.loop;
|
|
4754
|
+
const withLoop = (kfs2) => {
|
|
4755
|
+
const block = { keyframes: kfs2 };
|
|
4756
|
+
if (srcLoop !== void 0) block.loop = srcLoop;
|
|
4757
|
+
return block;
|
|
4758
|
+
};
|
|
4759
|
+
let n = inner;
|
|
4760
|
+
if (translateKfs.length) n = { type: "g", animate: { transform: withLoop(translateKfs) }, children: [n] };
|
|
4761
|
+
if (rotateKfs.length) n = { type: "g", animate: { transform: withLoop(rotateKfs) }, children: [n] };
|
|
4762
|
+
if (scaleKfs.length) n = { type: "g", animate: { transform: withLoop(scaleKfs) }, children: [n] };
|
|
4763
|
+
return n;
|
|
4764
|
+
}
|
|
4765
|
+
function nodeHasBodyTransform(node) {
|
|
4766
|
+
if (typeof node.transform === "string") return true;
|
|
4767
|
+
if (node.transform && typeof node.transform === "object") return true;
|
|
4768
|
+
return hasAnimateTransform(node);
|
|
4769
|
+
}
|
|
4770
|
+
function hasAnimateTransform(node) {
|
|
4771
|
+
const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
4772
|
+
return !!(animate && animate.transform);
|
|
4773
|
+
}
|
|
4774
|
+
function readTransformationFromBody(node) {
|
|
4775
|
+
if (typeof node.transform === "string") {
|
|
4776
|
+
const parts = parseTransformStringToParts(node.transform);
|
|
4777
|
+
if (!parts) return void 0;
|
|
4778
|
+
const out = {};
|
|
4779
|
+
if (parts.translate) out.translate = parts.translate;
|
|
4780
|
+
if (parts.rotate !== void 0) out.rotate = parts.rotate;
|
|
4781
|
+
if (parts.scale) out.scale = { value: parts.scale };
|
|
4782
|
+
if (parts.origin) out.origin = parts.origin;
|
|
4783
|
+
return Object.keys(out).length ? out : void 0;
|
|
4784
|
+
}
|
|
4785
|
+
if (node.transform && typeof node.transform === "object" && !node.transform.keyframes) {
|
|
4786
|
+
const wrapped = node.transform.value;
|
|
4787
|
+
const value = wrapped && typeof wrapped === "object" ? wrapped : node.transform;
|
|
4788
|
+
if (value && typeof value === "object") {
|
|
4789
|
+
const out = {};
|
|
4790
|
+
if (Array.isArray(value.translate)) out.translate = value.translate;
|
|
4791
|
+
if (typeof value.rotate === "number") out.rotate = value.rotate;
|
|
4792
|
+
if (typeof value.skew === "number") out.skew = value.skew;
|
|
4793
|
+
if (Array.isArray(value.scale)) out.scale = { value: value.scale };
|
|
4794
|
+
if (Array.isArray(value.origin)) out.origin = value.origin;
|
|
4795
|
+
return Object.keys(out).length ? out : void 0;
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4798
|
+
return void 0;
|
|
4799
|
+
}
|
|
4800
|
+
function parseTransformStringToParts(s) {
|
|
4801
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
4802
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
4803
|
+
let m;
|
|
4804
|
+
const ops = [];
|
|
4805
|
+
while ((m = re.exec(s)) !== null) {
|
|
4806
|
+
const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
|
|
4807
|
+
ops.push({ name: m[1], args });
|
|
4808
|
+
}
|
|
4809
|
+
if (!ops.length) return void 0;
|
|
4810
|
+
const last = ops[ops.length - 1];
|
|
4811
|
+
if (last.name === "translate") {
|
|
4812
|
+
for (let j = ops.length - 2; j >= 0; j--) {
|
|
4813
|
+
const cand = ops[j];
|
|
4814
|
+
if (cand.name !== "translate") continue;
|
|
4815
|
+
const ox = (_a2 = cand.args[0]) != null ? _a2 : 0;
|
|
4816
|
+
const oy = (_b = cand.args[1]) != null ? _b : 0;
|
|
4817
|
+
const lx = (_c = last.args[0]) != null ? _c : 0;
|
|
4818
|
+
const ly = (_d = last.args[1]) != null ? _d : 0;
|
|
4819
|
+
if (lx !== -ox || ly !== -oy) continue;
|
|
4820
|
+
const out2 = {};
|
|
4821
|
+
out2.origin = [ox, oy];
|
|
4822
|
+
for (let k = 0; k < j; k++) {
|
|
4823
|
+
if (ops[k].name === "translate") {
|
|
4824
|
+
const tx = (_e = ops[k].args[0]) != null ? _e : 0;
|
|
4825
|
+
const ty = (_f = ops[k].args[1]) != null ? _f : 0;
|
|
4826
|
+
out2.translate = out2.translate ? [out2.translate[0] + tx, out2.translate[1] + ty] : [tx, ty];
|
|
4827
|
+
}
|
|
4828
|
+
}
|
|
4829
|
+
for (let k = j + 1; k < ops.length - 1; k++) {
|
|
4830
|
+
const op = ops[k];
|
|
4831
|
+
if (op.name === "rotate") out2.rotate = ((_g = out2.rotate) != null ? _g : 0) + ((_h = op.args[0]) != null ? _h : 0);
|
|
4832
|
+
else if (op.name === "scale") {
|
|
4833
|
+
const sx = (_i = op.args[0]) != null ? _i : 1;
|
|
4834
|
+
const sy = op.args.length > 1 ? op.args[1] : sx;
|
|
4835
|
+
out2.scale = out2.scale ? [out2.scale[0] * sx, out2.scale[1] * sy] : [sx, sy];
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
return out2;
|
|
4839
|
+
}
|
|
4840
|
+
}
|
|
4841
|
+
let translate;
|
|
4842
|
+
let rotate;
|
|
4843
|
+
let scale;
|
|
4844
|
+
for (const op of ops) {
|
|
4845
|
+
if (op.name === "translate") {
|
|
4846
|
+
const dx = (_j = op.args[0]) != null ? _j : 0;
|
|
4847
|
+
const dy = (_k = op.args[1]) != null ? _k : 0;
|
|
4848
|
+
translate = translate ? [translate[0] + dx, translate[1] + dy] : [dx, dy];
|
|
4849
|
+
} else if (op.name === "rotate") {
|
|
4850
|
+
rotate = (rotate != null ? rotate : 0) + ((_l = op.args[0]) != null ? _l : 0);
|
|
4851
|
+
} else if (op.name === "scale") {
|
|
4852
|
+
const sx = (_m = op.args[0]) != null ? _m : 1;
|
|
4853
|
+
const sy = op.args.length > 1 ? op.args[1] : sx;
|
|
4854
|
+
scale = scale ? [scale[0] * sx, scale[1] * sy] : [sx, sy];
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4857
|
+
const out = {};
|
|
4858
|
+
if (translate) out.translate = translate;
|
|
4859
|
+
if (rotate !== void 0) out.rotate = rotate;
|
|
4860
|
+
if (scale) out.scale = scale;
|
|
4861
|
+
return Object.keys(out).length ? out : void 0;
|
|
4862
|
+
}
|
|
4863
|
+
function wrapAncestorChainCompensation(inner, maskedNode, sourceId, ctx, includeTargetOwn) {
|
|
4864
|
+
const sourceNode = ctx.idMap.get(sourceId);
|
|
4865
|
+
const targetAncestors = ctx.maskAncestorChains.get(maskedNode) || [];
|
|
4866
|
+
const targetOwn = includeTargetOwn ? extractTranslateOnly(maskedNode, ctx) : void 0;
|
|
4867
|
+
const targetChain = targetOwn ? [...targetAncestors, targetOwn] : targetAncestors;
|
|
4868
|
+
const sourceChain = sourceNode && ctx.maskAncestorChains.get(sourceNode) || [];
|
|
4869
|
+
if (!targetChain.length && !sourceChain.length) return inner;
|
|
4870
|
+
const times = /* @__PURE__ */ new Set();
|
|
4871
|
+
for (const a of targetChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
|
|
4872
|
+
for (const a of sourceChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
|
|
4873
|
+
const animated = times.size > 0;
|
|
4874
|
+
if (!animated) {
|
|
4875
|
+
const tgt = sumStaticTranslate(targetChain);
|
|
4876
|
+
const src = sumStaticTranslate(sourceChain);
|
|
4877
|
+
const dx = src[0] - tgt[0];
|
|
4878
|
+
const dy = src[1] - tgt[1];
|
|
4879
|
+
if (dx === 0 && dy === 0) return inner;
|
|
4880
|
+
return { type: "g", transform: "translate(" + dx + "," + dy + ")", children: [inner] };
|
|
4881
|
+
}
|
|
4882
|
+
const sortedTimes = Array.from(times).sort((a, b) => a - b);
|
|
4883
|
+
const keyframes = sortedTimes.map((t) => {
|
|
4884
|
+
const tgt = sumTranslateAt(targetChain, t);
|
|
4885
|
+
const src = sumTranslateAt(sourceChain, t);
|
|
4886
|
+
return { time: t, value: { translate: [src[0] - tgt[0], src[1] - tgt[1]] } };
|
|
4887
|
+
});
|
|
4888
|
+
return { type: "g", animate: { transform: { keyframes } }, children: [inner] };
|
|
4889
|
+
}
|
|
4890
|
+
function sumStaticTranslate(chain) {
|
|
4891
|
+
let x = 0, y = 0;
|
|
4892
|
+
for (const a of chain) {
|
|
4893
|
+
if (a.translate) {
|
|
4894
|
+
x += a.translate[0];
|
|
4895
|
+
y += a.translate[1];
|
|
4896
|
+
}
|
|
4897
|
+
}
|
|
4898
|
+
return [x, y];
|
|
4899
|
+
}
|
|
4900
|
+
function sumTranslateAt(chain, t) {
|
|
4901
|
+
let x = 0, y = 0;
|
|
4902
|
+
for (const a of chain) {
|
|
4903
|
+
if (a.translateKeyframes && a.translateKeyframes.length) {
|
|
4904
|
+
const v = interpKfs(a.translateKeyframes, t);
|
|
4905
|
+
x += v[0];
|
|
4906
|
+
y += v[1];
|
|
4907
|
+
} else if (a.translate) {
|
|
4908
|
+
x += a.translate[0];
|
|
4909
|
+
y += a.translate[1];
|
|
4910
|
+
}
|
|
4911
|
+
}
|
|
4912
|
+
return [x, y];
|
|
4913
|
+
}
|
|
4914
|
+
function interpKfs(kfs, t) {
|
|
4915
|
+
if (t <= kfs[0].time) return kfs[0].value;
|
|
4916
|
+
if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
|
|
4917
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
4918
|
+
if (t <= kfs[i].time) {
|
|
4919
|
+
const prev = kfs[i - 1];
|
|
4920
|
+
const cur = kfs[i];
|
|
4921
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
4922
|
+
return [prev.value[0] + (cur.value[0] - prev.value[0]) * a, prev.value[1] + (cur.value[1] - prev.value[1]) * a];
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
return kfs[kfs.length - 1].value;
|
|
4926
|
+
}
|
|
4927
|
+
function collectMaskAncestorChains(root, ctx) {
|
|
4928
|
+
const interestingNodes = /* @__PURE__ */ new Set();
|
|
4929
|
+
const collectInterestingNodes = (n) => {
|
|
4930
|
+
var _a2, _b;
|
|
4931
|
+
const maskSourceId = stripHash((_b = (_a2 = n.effects) == null ? void 0 : _a2.maskedBy) == null ? void 0 : _b.source);
|
|
4932
|
+
if (typeof maskSourceId === "string") {
|
|
4933
|
+
interestingNodes.add(n);
|
|
4934
|
+
const sourceNode = ctx.idMap.get(maskSourceId);
|
|
4935
|
+
if (sourceNode) interestingNodes.add(sourceNode);
|
|
4936
|
+
}
|
|
4937
|
+
if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
|
|
4938
|
+
};
|
|
4939
|
+
collectInterestingNodes(root);
|
|
4940
|
+
if (interestingNodes.size === 0) return;
|
|
4941
|
+
const walk = (node, chain) => {
|
|
4942
|
+
if (interestingNodes.has(node)) ctx.maskAncestorChains.set(node, chain);
|
|
4943
|
+
if (Array.isArray(node.children)) {
|
|
4944
|
+
const own = extractTranslateOnly(node, ctx);
|
|
4945
|
+
const next = own ? [...chain, own] : chain;
|
|
4946
|
+
for (const ch of node.children) walk(ch, next);
|
|
4947
|
+
}
|
|
4948
|
+
};
|
|
4949
|
+
walk(root, []);
|
|
4950
|
+
}
|
|
4951
|
+
function extractTranslateOnly(node, ctx) {
|
|
4952
|
+
var _a2, _b, _c;
|
|
4953
|
+
const tr = node.transform;
|
|
4954
|
+
const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
|
|
4955
|
+
if (tr === void 0 && !animateBlock) return void 0;
|
|
4956
|
+
const out = {};
|
|
4957
|
+
if (typeof tr === "string") {
|
|
4958
|
+
const parts = parseTranslateOnlyFromString(tr, ctx);
|
|
4959
|
+
if (parts) out.translate = parts;
|
|
4960
|
+
} else if (tr && typeof tr === "object" && !tr.keyframes) {
|
|
4961
|
+
const wrapped = tr.value;
|
|
4962
|
+
const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
|
|
4963
|
+
if (value && typeof value === "object" && Array.isArray(value.translate)) {
|
|
4964
|
+
out.translate = [value.translate[0] || 0, value.translate[1] || 0];
|
|
4965
|
+
}
|
|
4966
|
+
if (value && (value.rotate !== void 0 || value.scale !== void 0 || value.skew !== void 0)) {
|
|
4967
|
+
ctx.warnings.push("maskedBy ancestor: non-translate transform parts ignored (rotate/scale not yet supported)");
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4970
|
+
if (animateBlock && Array.isArray(animateBlock.keyframes)) {
|
|
4971
|
+
const kfs = animateBlock.keyframes;
|
|
4972
|
+
const translateKfs = [];
|
|
4973
|
+
for (const kf of kfs) {
|
|
4974
|
+
const v = (_a2 = kf.value) != null ? _a2 : kf.v;
|
|
4975
|
+
const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
|
|
4976
|
+
if (v && typeof v === "object" && Array.isArray(v.translate)) {
|
|
4977
|
+
translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
|
|
4978
|
+
if (v.rotate !== void 0 || v.scale !== void 0 || v.skew !== void 0) {
|
|
4979
|
+
ctx.warnings.push("maskedBy ancestor: animated non-translate parts ignored");
|
|
4980
|
+
}
|
|
4981
|
+
}
|
|
4982
|
+
}
|
|
4983
|
+
if (translateKfs.length) out.translateKeyframes = translateKfs;
|
|
4984
|
+
}
|
|
4985
|
+
return out.translate || out.translateKeyframes ? out : void 0;
|
|
4986
|
+
}
|
|
4987
|
+
function parseTranslateOnlyFromString(s, ctx) {
|
|
4988
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
4989
|
+
let m;
|
|
4990
|
+
let x = 0, y = 0;
|
|
4991
|
+
let seen = false;
|
|
4992
|
+
let droppedNonTranslate = false;
|
|
4993
|
+
while ((m = re.exec(s)) !== null) {
|
|
4994
|
+
const name = m[1];
|
|
4995
|
+
const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
|
|
4996
|
+
if (name === "translate") {
|
|
4997
|
+
x += args[0] || 0;
|
|
4998
|
+
y += args[1] || 0;
|
|
4999
|
+
seen = true;
|
|
5000
|
+
} else {
|
|
5001
|
+
droppedNonTranslate = true;
|
|
5002
|
+
}
|
|
5003
|
+
}
|
|
5004
|
+
if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
|
|
5005
|
+
return seen ? [x, y] : void 0;
|
|
5006
|
+
}
|
|
5007
|
+
|
|
5008
|
+
// src/effects/reference/refEffect.ts
|
|
5009
|
+
function applyRefHref(node, clone2, ctx) {
|
|
5010
|
+
if (!clone2) return;
|
|
5011
|
+
const sourceId = stripHash(clone2.source);
|
|
5012
|
+
if (!sourceId) {
|
|
5013
|
+
if (clone2.without === PxCloneWithout.translate) ctx.errors.push("clone: content ref missing `source`");
|
|
5014
|
+
return;
|
|
5015
|
+
}
|
|
5016
|
+
const targetId = clone2.without === PxCloneWithout.translate ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
|
|
5017
|
+
node.href = "#" + targetId;
|
|
5018
|
+
}
|
|
5019
|
+
function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
|
|
5020
|
+
applyRefHref(node, clone2, ctx);
|
|
5021
|
+
return applyTransformByEffect(node, transformBy, ctx);
|
|
5022
|
+
}
|
|
5023
|
+
|
|
5024
|
+
// src/effects/transform/repeaterEffect.ts
|
|
5025
|
+
function applyRepeaterEffect(node, fx, ctx) {
|
|
5026
|
+
var _a2, _b;
|
|
5027
|
+
if (!fx) return node;
|
|
5028
|
+
const copies = (_a2 = fx.copies) != null ? _a2 : 1;
|
|
5029
|
+
if (copies < 1) {
|
|
5030
|
+
ctx.errors.push("repeater.copies invalid: " + fx.copies);
|
|
5031
|
+
return node;
|
|
5032
|
+
}
|
|
5033
|
+
const sharedTransform = node.transform;
|
|
5034
|
+
const sharedAnimTransform = (_b = node.animate) == null ? void 0 : _b.transform;
|
|
5035
|
+
const base = clone(node);
|
|
5036
|
+
delete base.transform;
|
|
5037
|
+
if (base.animate) {
|
|
5038
|
+
delete base.animate.transform;
|
|
5039
|
+
if (Object.keys(base.animate).length === 0) delete base.animate;
|
|
5040
|
+
}
|
|
5041
|
+
delete base.id;
|
|
5042
|
+
const children = [base];
|
|
5043
|
+
for (let i = 1; i < copies; i++) {
|
|
5044
|
+
const baseClone = clone(base);
|
|
5045
|
+
const synthFx = synthesisePerCopyFx(fx, i);
|
|
5046
|
+
const wrapped = synthFx ? applyTransformByEffect(baseClone, synthFx, ctx) : baseClone;
|
|
5047
|
+
children.push(wrapped);
|
|
5048
|
+
}
|
|
5049
|
+
const wrapper = { type: "g", children };
|
|
5050
|
+
if (node.id) wrapper.id = node.id;
|
|
5051
|
+
if (sharedTransform !== void 0) wrapper.transform = sharedTransform;
|
|
5052
|
+
if (sharedAnimTransform !== void 0) wrapper.animate = { transform: sharedAnimTransform };
|
|
5053
|
+
return wrapper;
|
|
5054
|
+
}
|
|
5055
|
+
function synthesisePerCopyFx(fx, i) {
|
|
5056
|
+
const out = {};
|
|
5057
|
+
if (fx.translate !== void 0) {
|
|
5058
|
+
out.translate = mapAnimatable(fx.translate, (v) => [v[0] * i, v[1] * i]);
|
|
5059
|
+
}
|
|
5060
|
+
if (fx.rotate !== void 0) {
|
|
5061
|
+
out.rotate = mapAnimatable(fx.rotate, (v) => v * i);
|
|
5062
|
+
}
|
|
5063
|
+
if (fx.skew !== void 0) {
|
|
5064
|
+
out.skew = mapAnimatable(fx.skew, (v) => v * i);
|
|
5065
|
+
}
|
|
5066
|
+
if (fx.scale !== void 0) {
|
|
5067
|
+
out.scale = synthesiseScale(fx.scale, i);
|
|
5068
|
+
}
|
|
5069
|
+
if (fx.origin !== void 0) {
|
|
5070
|
+
out.origin = fx.origin;
|
|
5071
|
+
}
|
|
5072
|
+
return Object.keys(out).length ? out : void 0;
|
|
5073
|
+
}
|
|
5074
|
+
function mapAnimatable(raw, fn, wrapStatic = false) {
|
|
5075
|
+
const read = readAnimatable(raw);
|
|
5076
|
+
if (read.kind === "absent" /* Absent */) return raw;
|
|
5077
|
+
if (read.kind === "static" /* Static */) {
|
|
5078
|
+
const mapped = fn(read.value);
|
|
5079
|
+
const wasRawStatic = typeof raw === "number" || Array.isArray(raw);
|
|
5080
|
+
return wasRawStatic && !wrapStatic ? mapped : { value: mapped };
|
|
5081
|
+
}
|
|
5082
|
+
const out = {
|
|
5083
|
+
keyframes: read.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
|
|
5084
|
+
};
|
|
5085
|
+
if (read.loop !== void 0) out.loop = read.loop;
|
|
5086
|
+
if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
|
|
5087
|
+
if (read.base !== void 0) out.value = fn(read.base);
|
|
5088
|
+
return out;
|
|
5089
|
+
}
|
|
5090
|
+
function synthesiseScale(raw, i) {
|
|
5091
|
+
const scalePower = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
|
|
5092
|
+
return mapAnimatable(raw, scalePower, true);
|
|
5093
|
+
}
|
|
5094
|
+
|
|
5095
|
+
// src/effects/reference/retimeEffect.ts
|
|
5096
|
+
var RETIME_MATERIALIZATION_MODE_INLINE_G = false;
|
|
5097
|
+
function asRetime(r) {
|
|
5098
|
+
var _a2, _b;
|
|
5099
|
+
return { start: (_a2 = r.start) != null ? _a2 : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
|
|
5100
|
+
}
|
|
5101
|
+
var CROP_EDGE_MS = 1;
|
|
5102
|
+
function applyTimeCrop(useNode, crop, ctx) {
|
|
5103
|
+
const [start, end] = crop;
|
|
5104
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) {
|
|
5105
|
+
ctx.warnings.push("retime: timeCrop is not a pair of finite numbers \u2014 ignored");
|
|
5106
|
+
return;
|
|
5107
|
+
}
|
|
5108
|
+
const keyframes = end <= start ? [{ time: 0, value: 0 }] : [
|
|
5109
|
+
...start > 0 ? [{ time: Math.max(0, start - CROP_EDGE_MS), value: 0 }] : [],
|
|
5110
|
+
{ time: Math.max(0, start), value: 1 },
|
|
5111
|
+
{ time: end, value: 1 },
|
|
5112
|
+
{ time: end + CROP_EDGE_MS, value: 0 }
|
|
5113
|
+
];
|
|
5114
|
+
const inner = __spreadValues({}, useNode);
|
|
5115
|
+
for (const k of Object.keys(useNode)) delete useNode[k];
|
|
5116
|
+
useNode.type = "g";
|
|
5117
|
+
useNode.children = [inner];
|
|
5118
|
+
useNode.animate = { opacity: { keyframes } };
|
|
5119
|
+
}
|
|
5120
|
+
function concatRetime(child, parent) {
|
|
5121
|
+
return {
|
|
5122
|
+
start: parent.start + parent.stretch * child.start,
|
|
5123
|
+
stretch: parent.stretch * child.stretch
|
|
5124
|
+
};
|
|
5125
|
+
}
|
|
5126
|
+
function readCloneRetime(n) {
|
|
5127
|
+
var _a2, _b;
|
|
5128
|
+
return (_b = (_a2 = n.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.retime;
|
|
5129
|
+
}
|
|
5130
|
+
function clearCloneRetime(n) {
|
|
5131
|
+
var _a2;
|
|
5132
|
+
const clone2 = (_a2 = n.effects) == null ? void 0 : _a2.clone;
|
|
5133
|
+
if (!clone2) return;
|
|
5134
|
+
delete clone2.retime;
|
|
5135
|
+
if (Object.keys(clone2).length === 0) delete n.effects.clone;
|
|
5136
|
+
if (n.effects && Object.keys(n.effects).length === 0) delete n.effects;
|
|
5137
|
+
}
|
|
5138
|
+
function applyAllRetimeEffects(root, ctx) {
|
|
5139
|
+
ctx.idMap.clear();
|
|
5140
|
+
indexById(root, ctx.idMap);
|
|
5141
|
+
const sites = [];
|
|
5142
|
+
const collect = (n) => {
|
|
5143
|
+
var _a2;
|
|
5144
|
+
if (readCloneRetime(n)) sites.push(n);
|
|
5145
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(collect);
|
|
5146
|
+
};
|
|
5147
|
+
collect(root);
|
|
5148
|
+
const reachCount = /* @__PURE__ */ new Map();
|
|
5149
|
+
for (const site of sites) {
|
|
5150
|
+
let count = 0;
|
|
5151
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5152
|
+
const walk = (n) => {
|
|
5153
|
+
var _a2;
|
|
5154
|
+
if (!n) return;
|
|
5155
|
+
if (n !== site && readCloneRetime(n)) count++;
|
|
5156
|
+
if (n.type === "use" && n.href) {
|
|
5157
|
+
const id = stripHash(n.href);
|
|
5158
|
+
if (id && !visited.has(id)) {
|
|
5159
|
+
visited.add(id);
|
|
5160
|
+
walk(ctx.idMap.get(id));
|
|
5161
|
+
}
|
|
5162
|
+
}
|
|
5163
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(walk);
|
|
5164
|
+
};
|
|
5165
|
+
const rootId = stripHash(site.href);
|
|
5166
|
+
if (rootId) {
|
|
5167
|
+
visited.add(rootId);
|
|
5168
|
+
walk(ctx.idMap.get(rootId));
|
|
5169
|
+
}
|
|
5170
|
+
reachCount.set(site, count);
|
|
5171
|
+
}
|
|
5172
|
+
sites.sort((a, b) => {
|
|
5173
|
+
var _a2, _b;
|
|
5174
|
+
return ((_a2 = reachCount.get(b)) != null ? _a2 : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
|
|
5175
|
+
});
|
|
5176
|
+
for (const useNode of sites) {
|
|
5177
|
+
const retime = readCloneRetime(useNode);
|
|
5178
|
+
if (!retime) continue;
|
|
5179
|
+
const crop = retime.timeCrop;
|
|
5180
|
+
clearCloneRetime(useNode);
|
|
5181
|
+
materializeRetime(useNode, asRetime(retime), ctx);
|
|
5182
|
+
if (crop) applyTimeCrop(useNode, crop, ctx);
|
|
5183
|
+
}
|
|
5184
|
+
}
|
|
5185
|
+
function materializeRetime(useNode, retime, ctx) {
|
|
5186
|
+
const targetId = stripHash(useNode.href);
|
|
5187
|
+
if (!targetId) {
|
|
5188
|
+
ctx.errors.push("retime: <use> has no href to follow");
|
|
5189
|
+
return;
|
|
5190
|
+
}
|
|
5191
|
+
const chainRootId = buildChainClone(targetId, retime, ctx, /* @__PURE__ */ new Set());
|
|
5192
|
+
if (!chainRootId) return;
|
|
5193
|
+
if (RETIME_MATERIALIZATION_MODE_INLINE_G) {
|
|
5194
|
+
const cloneNode = ctx.idMap.get(chainRootId);
|
|
5195
|
+
useNode.type = "g";
|
|
5196
|
+
delete useNode.href;
|
|
5197
|
+
useNode.children = [cloneNode];
|
|
5198
|
+
applyUseOffsetToG(useNode);
|
|
5199
|
+
ctx.defs = ctx.defs.filter((d) => d !== cloneNode);
|
|
5200
|
+
} else {
|
|
5201
|
+
useNode.href = "#" + chainRootId;
|
|
5202
|
+
}
|
|
5203
|
+
}
|
|
5204
|
+
function buildChainClone(targetId, accum, ctx, chain) {
|
|
5205
|
+
if (chain.has(targetId)) {
|
|
5206
|
+
ctx.errors.push('retime: loop via "' + targetId + '"');
|
|
5207
|
+
return void 0;
|
|
5208
|
+
}
|
|
5209
|
+
const target = ctx.idMap.get(targetId);
|
|
5210
|
+
if (!target) {
|
|
5211
|
+
ctx.warnings.push('retime: target "' + targetId + '" not found');
|
|
5212
|
+
return void 0;
|
|
5213
|
+
}
|
|
5214
|
+
const cloneNode = clone(target);
|
|
5215
|
+
regenerateIdsInClone(cloneNode, ctx);
|
|
5216
|
+
if (target.type === "use") {
|
|
5217
|
+
remapKeyframeTimesOnly(cloneNode, accum.start, accum.stretch);
|
|
5218
|
+
} else {
|
|
5219
|
+
remapKeyframeTimes(cloneNode, accum.start, accum.stretch);
|
|
5220
|
+
}
|
|
5221
|
+
clearCloneRetime(cloneNode);
|
|
5222
|
+
if (target.type === "use" && target.href) {
|
|
5223
|
+
const subId = stripHash(target.href);
|
|
5224
|
+
if (subId) {
|
|
5225
|
+
const innerRetime = readCloneRetime(target);
|
|
5226
|
+
const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
|
|
5227
|
+
const subChain = new Set(chain);
|
|
5228
|
+
subChain.add(targetId);
|
|
5229
|
+
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
5230
|
+
if (subId2) cloneNode.href = "#" + subId2;
|
|
5231
|
+
}
|
|
5232
|
+
} else {
|
|
5233
|
+
materializeNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
|
|
5234
|
+
}
|
|
5235
|
+
ctx.defs.push(cloneNode);
|
|
5236
|
+
if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
|
|
5237
|
+
return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
|
|
5238
|
+
}
|
|
5239
|
+
function materializeNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
|
|
5240
|
+
const visit = (n) => {
|
|
5241
|
+
var _a2;
|
|
5242
|
+
const retime = readCloneRetime(n);
|
|
5243
|
+
if (n.type === "use" && retime && n.href) {
|
|
5244
|
+
const subId = stripHash(n.href);
|
|
5245
|
+
if (subId) {
|
|
5246
|
+
const subAccum = concatRetime(asRetime(retime), accum);
|
|
5247
|
+
const subChain = new Set(chain);
|
|
5248
|
+
subChain.add(parentTargetId);
|
|
5249
|
+
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
5250
|
+
if (subId2) n.href = "#" + subId2;
|
|
5251
|
+
}
|
|
5252
|
+
clearCloneRetime(n);
|
|
5253
|
+
}
|
|
5254
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
|
|
5255
|
+
};
|
|
5256
|
+
visit(node);
|
|
5257
|
+
}
|
|
5258
|
+
function remapKeyframeTimes(node, start, stretch) {
|
|
5259
|
+
var _a2;
|
|
5260
|
+
remapKeyframeTimesOnly(node, start, stretch);
|
|
5261
|
+
(_a2 = node.children) == null ? void 0 : _a2.forEach((c) => remapKeyframeTimes(c, start, stretch));
|
|
5262
|
+
}
|
|
5263
|
+
function remapKeyframeTimesOnly(node, start, stretch) {
|
|
5264
|
+
const remap2 = (kfs) => {
|
|
5265
|
+
for (const kf of kfs) if (typeof kf.time === "number") kf.time = start + kf.time * stretch;
|
|
5266
|
+
};
|
|
5267
|
+
if (node.transform && typeof node.transform === "object" && Array.isArray(node.transform.keyframes)) {
|
|
5268
|
+
remap2(node.transform.keyframes);
|
|
5269
|
+
}
|
|
5270
|
+
if (node.animate && typeof node.animate === "object") {
|
|
5271
|
+
for (const prop of Object.keys(node.animate)) {
|
|
5272
|
+
const anim = node.animate[prop];
|
|
5273
|
+
if (anim && Array.isArray(anim.keyframes)) remap2(anim.keyframes);
|
|
5274
|
+
}
|
|
5275
|
+
}
|
|
5276
|
+
}
|
|
5277
|
+
|
|
5278
|
+
// src/effects/stroke/strokeTrimEffect.ts
|
|
5279
|
+
function applyStrokeTrimEffect(node, strokeTrim, ctx) {
|
|
5280
|
+
if (!strokeTrim) return node;
|
|
5281
|
+
const combined = strokeTrim.subPaths === PxStrokeTrimSubPaths.combined;
|
|
5282
|
+
const leafEntries = [];
|
|
5283
|
+
const measure = (n) => {
|
|
5284
|
+
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
5285
|
+
for (const ch of n.children) measure(ch);
|
|
5286
|
+
return;
|
|
5287
|
+
}
|
|
5288
|
+
const d = typeof n.d === "string" ? n.d : shapeToPathD(n);
|
|
5289
|
+
if (d === void 0) return;
|
|
5290
|
+
const subpaths = parseSvgPathToBezier(d);
|
|
5291
|
+
if (!subpaths.length) return;
|
|
5292
|
+
const entry = { leaf: n, subpaths: [] };
|
|
5293
|
+
for (const sp of subpaths) {
|
|
5294
|
+
const lengthPx = pxBezierPathLength(sp);
|
|
5295
|
+
entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: 0 });
|
|
5296
|
+
}
|
|
5297
|
+
leafEntries.push(entry);
|
|
5298
|
+
};
|
|
5299
|
+
measure(node);
|
|
5300
|
+
if (!leafEntries.length) return node;
|
|
5301
|
+
let acc = 0;
|
|
5302
|
+
const iterOrder = combined ? [...leafEntries].reverse() : leafEntries;
|
|
5303
|
+
for (const entry of iterOrder) {
|
|
5304
|
+
for (const sp of entry.subpaths) {
|
|
5305
|
+
if (!combined) acc = 0;
|
|
5306
|
+
sp.startOffsetPx = acc;
|
|
5307
|
+
acc += sp.lengthPx;
|
|
5308
|
+
}
|
|
5309
|
+
}
|
|
5310
|
+
const chainLengthPx = acc;
|
|
5311
|
+
if (combined && chainLengthPx < 1e-3) return node;
|
|
5312
|
+
const offsetReadRaw = readAnimatable(strokeTrim.offset);
|
|
5313
|
+
const offsetRead = offsetReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: 0 } : offsetReadRaw;
|
|
5314
|
+
const rangeReadRaw = readRangeWithCrossings(strokeTrim.range);
|
|
5315
|
+
const rangeRead = rangeReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: [0, 1] } : rangeReadRaw;
|
|
5316
|
+
const offsetValues = readScalarValues(offsetRead);
|
|
5317
|
+
const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;
|
|
5318
|
+
const maxOffset = offsetValues.length ? Math.max(...offsetValues) : 0;
|
|
5319
|
+
const minMaxOffset = [minOffset, maxOffset];
|
|
5320
|
+
if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
|
|
5321
|
+
const entry = leafEntries[0];
|
|
5322
|
+
const sp = entry.subpaths[0];
|
|
5323
|
+
const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
|
|
5324
|
+
if (pathLengthPx < 1e-3) return node;
|
|
5325
|
+
const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
|
|
5326
|
+
return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
|
|
5327
|
+
}
|
|
5328
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
5329
|
+
for (const entry of leafEntries) {
|
|
5330
|
+
const newChildren = [];
|
|
5331
|
+
for (const sp of entry.subpaths) {
|
|
5332
|
+
const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
|
|
5333
|
+
if (pathLengthPx < 1e-3) continue;
|
|
5334
|
+
const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
|
|
5335
|
+
newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
|
|
5336
|
+
}
|
|
5337
|
+
replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
|
|
5338
|
+
}
|
|
5339
|
+
const swap = (n) => {
|
|
5340
|
+
const r = replacements.get(n);
|
|
5341
|
+
if (r) return r;
|
|
5342
|
+
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
5343
|
+
return __spreadProps(__spreadValues({}, n), { children: n.children.map(swap) });
|
|
5344
|
+
}
|
|
5345
|
+
return n;
|
|
5346
|
+
};
|
|
5347
|
+
return swap(node);
|
|
5348
|
+
}
|
|
5349
|
+
function wrapLeafAsGroup(leaf, children) {
|
|
5350
|
+
const wrapper = __spreadProps(__spreadValues({}, leaf), { type: "g", children });
|
|
5351
|
+
delete wrapper.d;
|
|
5352
|
+
delete wrapper.strokeDasharray;
|
|
5353
|
+
delete wrapper.strokeDashoffset;
|
|
5354
|
+
delete wrapper.effects;
|
|
5355
|
+
return wrapper;
|
|
5356
|
+
}
|
|
5357
|
+
function buildSubpathNodes(leaf, subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx) {
|
|
5358
|
+
const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
|
|
5359
|
+
const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
|
|
5360
|
+
const dashOffsetAttr = computeAnimAttr(offsetRead, offsetToDashOffset);
|
|
5361
|
+
const dashArrayAttr = computeAnimAttr(rangeRead, rangeToDasharray);
|
|
5362
|
+
const strokeOpacityAttr = computeOpacityFromRange(rangeRead);
|
|
5363
|
+
const dStr = bezierToSvgPath(subpath);
|
|
5364
|
+
const base = makeBareSubpath(dStr);
|
|
5365
|
+
applyAttr(base, "strokeDasharray", dashArrayAttr);
|
|
5366
|
+
applyAttr(base, "strokeDashoffset", dashOffsetAttr);
|
|
5367
|
+
applyAttr(base, "strokeOpacity", strokeOpacityAttr);
|
|
5368
|
+
return [base];
|
|
5369
|
+
}
|
|
5370
|
+
function collapseLeafWithTrim(leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead) {
|
|
5371
|
+
const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
|
|
5372
|
+
const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
|
|
5373
|
+
const node = __spreadValues({}, leaf);
|
|
5374
|
+
delete node.effects;
|
|
5375
|
+
applyAttr(node, "strokeDasharray", computeAnimAttr(rangeRead, rangeToDasharray));
|
|
5376
|
+
applyAttr(node, "strokeDashoffset", computeAnimAttr(offsetRead, offsetToDashOffset));
|
|
5377
|
+
applyAttr(node, "strokeOpacity", computeOpacityFromRange(rangeRead));
|
|
5378
|
+
return node;
|
|
5379
|
+
}
|
|
5380
|
+
function makeBareSubpath(dStr) {
|
|
5381
|
+
return { type: "path", d: dStr };
|
|
5382
|
+
}
|
|
5383
|
+
var SMALL_PADDING_PX = 1;
|
|
5384
|
+
function makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset) {
|
|
5385
|
+
const [minIdx] = getOffsetIndexRange(minMaxOffset);
|
|
5386
|
+
return (offsetVal) => pathLengthPx * (-offsetVal - minIdx + startOffsetPct) + SMALL_PADDING_PX;
|
|
5387
|
+
}
|
|
5388
|
+
function makeRangeToDasharray(pathLengthPx, minMaxOffset) {
|
|
5389
|
+
const [minIdx, maxIdx] = getOffsetIndexRange(minMaxOffset);
|
|
5390
|
+
const repeats = maxIdx - minIdx + 1;
|
|
5391
|
+
return (rangeVal) => {
|
|
5392
|
+
const a = clamp(rangeVal[0], 0, 1);
|
|
5393
|
+
const b = clamp(rangeVal[1], 0, 1);
|
|
5394
|
+
const minR = Math.min(a, b);
|
|
5395
|
+
const maxR = Math.max(a, b);
|
|
5396
|
+
const out = [0];
|
|
5397
|
+
let gap = SMALL_PADDING_PX;
|
|
5398
|
+
for (let i = 0; i < repeats; i++) {
|
|
5399
|
+
out.push(gap + minR * pathLengthPx);
|
|
5400
|
+
out.push((maxR - minR) * pathLengthPx);
|
|
5401
|
+
gap = (1 - maxR) * pathLengthPx;
|
|
5402
|
+
}
|
|
5403
|
+
out.push(gap + SMALL_PADDING_PX);
|
|
5404
|
+
return out;
|
|
5405
|
+
};
|
|
5406
|
+
}
|
|
5407
|
+
function getOffsetIndexRange(minMaxOffset) {
|
|
5408
|
+
return [
|
|
5409
|
+
Math.floor(Math.min(-minMaxOffset[0], -minMaxOffset[1])),
|
|
5410
|
+
Math.ceil(Math.max(-minMaxOffset[0], -minMaxOffset[1]))
|
|
5411
|
+
];
|
|
5412
|
+
}
|
|
5413
|
+
function readScalarValues(r) {
|
|
5414
|
+
if (r.kind === "absent" /* Absent */) return [];
|
|
5415
|
+
if (r.kind === "static" /* Static */) return [r.value];
|
|
5416
|
+
const out = [];
|
|
5417
|
+
for (const kf of r.keyframes) {
|
|
5418
|
+
const v = keyframeValue(kf);
|
|
5419
|
+
if (typeof v === "number") out.push(v);
|
|
5420
|
+
}
|
|
5421
|
+
return out;
|
|
5422
|
+
}
|
|
5423
|
+
function computeAnimAttr(read, map) {
|
|
5424
|
+
if (read.kind === "absent" /* Absent */) return void 0;
|
|
5425
|
+
if (read.kind === "static" /* Static */) return { kind: "static" /* Static */, value: map(read.value) };
|
|
5426
|
+
return {
|
|
5427
|
+
kind: "animated" /* Animated */,
|
|
5428
|
+
keyframes: read.keyframes.map((kf) => ({
|
|
5429
|
+
time: keyframeTime(kf),
|
|
5430
|
+
value: map(keyframeValue(kf)),
|
|
5431
|
+
easing: keyframeEasing(kf)
|
|
5432
|
+
})),
|
|
5433
|
+
loop: read.loop
|
|
5434
|
+
};
|
|
5435
|
+
}
|
|
5436
|
+
function applyAttr(node, attrName, attr) {
|
|
5437
|
+
if (!attr) return;
|
|
5438
|
+
writeAnimatableChannel(node, attrName, attr);
|
|
5439
|
+
}
|
|
5440
|
+
var OPACITY_STEP_MS = 10;
|
|
5441
|
+
function computeOpacityFromRange(rangeRead) {
|
|
5442
|
+
const hide = (v) => v[0] === v[1];
|
|
5443
|
+
if (rangeRead.kind === "absent" /* Absent */) return void 0;
|
|
5444
|
+
if (rangeRead.kind === "static" /* Static */) return hide(rangeRead.value) ? { kind: "static" /* Static */, value: 0 } : void 0;
|
|
5445
|
+
const kfs = rangeRead.keyframes;
|
|
5446
|
+
let anyHide = false;
|
|
5447
|
+
let allHide = true;
|
|
5448
|
+
for (const kf of kfs) {
|
|
5449
|
+
if (hide(keyframeValue(kf))) anyHide = true;
|
|
5450
|
+
else allHide = false;
|
|
5451
|
+
}
|
|
5452
|
+
if (!anyHide) return void 0;
|
|
5453
|
+
if (allHide) return { kind: "static" /* Static */, value: 0 };
|
|
5454
|
+
const out = [];
|
|
5455
|
+
for (let i = 0; i < kfs.length; i++) {
|
|
5456
|
+
const kf = kfs[i];
|
|
5457
|
+
const prevKf = i > 0 ? kfs[i - 1] : void 0;
|
|
5458
|
+
const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
|
|
5459
|
+
const t = keyframeTime(kf);
|
|
5460
|
+
const thisHide = hide(keyframeValue(kf));
|
|
5461
|
+
const prevHide = prevKf ? thisHide && hide(keyframeValue(prevKf)) : thisHide;
|
|
5462
|
+
const nextHide = nextKf ? thisHide && hide(keyframeValue(nextKf)) : thisHide;
|
|
5463
|
+
if (prevHide && !nextHide) {
|
|
5464
|
+
out.push({ time: t, value: 0 });
|
|
5465
|
+
out.push({ time: t + OPACITY_STEP_MS, value: 1 });
|
|
5466
|
+
} else if (!prevHide && nextHide) {
|
|
5467
|
+
out.push({ time: t - OPACITY_STEP_MS, value: 1 });
|
|
5468
|
+
out.push({ time: t, value: 0 });
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
if (out.length <= 1) return void 0;
|
|
5472
|
+
return { kind: "animated" /* Animated */, keyframes: out };
|
|
5473
|
+
}
|
|
5474
|
+
function readRangeWithCrossings(raw) {
|
|
5475
|
+
const r = readAnimatable(raw);
|
|
5476
|
+
if (r.kind !== "animated" /* Animated */) return r;
|
|
5477
|
+
const kfs = r.keyframes.map((kf) => ({
|
|
5478
|
+
time: keyframeTime(kf),
|
|
5479
|
+
value: keyframeValue(kf),
|
|
5480
|
+
easing: keyframeEasing(kf)
|
|
5481
|
+
}));
|
|
5482
|
+
const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
|
|
5483
|
+
if (!hasReverse) {
|
|
5484
|
+
return {
|
|
5485
|
+
kind: "animated" /* Animated */,
|
|
5486
|
+
keyframes: kfs.map((kf) => ({ time: kf.time, value: kf.value, easing: kf.easing }))
|
|
5487
|
+
};
|
|
5488
|
+
}
|
|
5489
|
+
const crossingTimes = [];
|
|
5490
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
5491
|
+
const prev = kfs[i - 1];
|
|
5492
|
+
const cur = kfs[i];
|
|
5493
|
+
const dPrev = prev.value[1] - prev.value[0];
|
|
5494
|
+
const dCur = cur.value[1] - cur.value[0];
|
|
5495
|
+
if (dPrev * dCur < 0) {
|
|
5496
|
+
const t = bisectionForRangeCrossing(prev, cur);
|
|
5497
|
+
if (t !== null && t > prev.time && t < cur.time) {
|
|
5498
|
+
crossingTimes.push(Math.round(t));
|
|
5499
|
+
}
|
|
5500
|
+
}
|
|
5501
|
+
}
|
|
5502
|
+
const uniqueTs = Array.from(new Set(crossingTimes)).sort((a, b) => a - b);
|
|
5503
|
+
const out = [];
|
|
5504
|
+
let j = 0;
|
|
5505
|
+
for (const kf of kfs) {
|
|
5506
|
+
while (j < uniqueTs.length && uniqueTs[j] < kf.time) {
|
|
5507
|
+
const t = uniqueTs[j++];
|
|
5508
|
+
const v2 = interpolateRangeAt(kfs, t);
|
|
5509
|
+
const m = (v2[0] + v2[1]) / 2;
|
|
5510
|
+
out.push({ time: t, value: [m, m] });
|
|
5511
|
+
}
|
|
5512
|
+
const v = kf.value[0] > kf.value[1] ? [kf.value[1], kf.value[0]] : kf.value;
|
|
5513
|
+
out.push({ time: kf.time, value: v, easing: kf.easing });
|
|
5514
|
+
}
|
|
5515
|
+
while (j < uniqueTs.length) {
|
|
5516
|
+
const t = uniqueTs[j++];
|
|
5517
|
+
const v = interpolateRangeAt(kfs, t);
|
|
5518
|
+
const m = (v[0] + v[1]) / 2;
|
|
5519
|
+
out.push({ time: t, value: [m, m] });
|
|
5520
|
+
}
|
|
5521
|
+
return { kind: "animated" /* Animated */, keyframes: out };
|
|
5522
|
+
}
|
|
5523
|
+
function bisectionForRangeCrossing(prev, cur) {
|
|
5524
|
+
const f = (t) => {
|
|
5525
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
5526
|
+
const v0 = prev.value[0] + (cur.value[0] - prev.value[0]) * a;
|
|
5527
|
+
const v1 = prev.value[1] + (cur.value[1] - prev.value[1]) * a;
|
|
5528
|
+
return v1 - v0;
|
|
5529
|
+
};
|
|
5530
|
+
let lo = prev.time, hi = cur.time;
|
|
5531
|
+
let fLo = f(lo);
|
|
5532
|
+
if (fLo === 0) return lo;
|
|
5533
|
+
const fHi = f(hi);
|
|
5534
|
+
if (fHi === 0) return hi;
|
|
5535
|
+
if (fLo * fHi > 0) return null;
|
|
5536
|
+
for (let i = 0; i < 100; i++) {
|
|
5537
|
+
const mid = (lo + hi) / 2;
|
|
5538
|
+
const fMid = f(mid);
|
|
5539
|
+
if (fMid === 0 || Math.abs(hi - lo) < 1e-4) return mid;
|
|
5540
|
+
if (fLo * fMid < 0) {
|
|
5541
|
+
hi = mid;
|
|
5542
|
+
} else {
|
|
5543
|
+
lo = mid;
|
|
5544
|
+
fLo = fMid;
|
|
5545
|
+
}
|
|
5546
|
+
}
|
|
5547
|
+
return (lo + hi) / 2;
|
|
5548
|
+
}
|
|
5549
|
+
function interpolateRangeAt(kfs, t) {
|
|
5550
|
+
if (t <= kfs[0].time) return kfs[0].value;
|
|
5551
|
+
if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
|
|
5552
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
5553
|
+
if (t <= kfs[i].time) {
|
|
5554
|
+
const prev = kfs[i - 1];
|
|
5555
|
+
const cur = kfs[i];
|
|
5556
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
5557
|
+
return [
|
|
5558
|
+
prev.value[0] + (cur.value[0] - prev.value[0]) * a,
|
|
5559
|
+
prev.value[1] + (cur.value[1] - prev.value[1]) * a
|
|
5560
|
+
];
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
return kfs[kfs.length - 1].value;
|
|
5564
|
+
}
|
|
5565
|
+
function pxBezierPathLength(path) {
|
|
5566
|
+
const v = path.v;
|
|
5567
|
+
if (!v || v.length < 2) return 0;
|
|
5568
|
+
let total = 0;
|
|
5569
|
+
for (let i = 0; i < v.length - 1; i++) {
|
|
5570
|
+
total += segmentLength(path, i, i + 1);
|
|
5571
|
+
}
|
|
5572
|
+
if (path.c && v.length > 1) {
|
|
5573
|
+
total += segmentLength(path, v.length - 1, 0);
|
|
5574
|
+
}
|
|
5575
|
+
return total;
|
|
5576
|
+
}
|
|
5577
|
+
function segmentLength(path, from, to) {
|
|
5578
|
+
var _a2, _b, _c, _d;
|
|
5579
|
+
const v = path.v;
|
|
5580
|
+
const p0 = v[from];
|
|
5581
|
+
const p3 = v[to];
|
|
5582
|
+
const p1 = (_b = (_a2 = path.o) == null ? void 0 : _a2[from]) != null ? _b : p0;
|
|
5583
|
+
const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
|
|
5584
|
+
const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
|
|
5585
|
+
return lut.ds[lut.ds.length - 1];
|
|
5586
|
+
}
|
|
5587
|
+
var ARC_KAPPA = 0.5522847498307936;
|
|
5588
|
+
function shapeToPathD(node) {
|
|
5589
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
5590
|
+
if (node.type === "rect") {
|
|
5591
|
+
const x = Number((_a2 = node.x) != null ? _a2 : 0), y = Number((_b = node.y) != null ? _b : 0);
|
|
5592
|
+
const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
|
|
5593
|
+
return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
|
|
5594
|
+
}
|
|
5595
|
+
if (node.type === "ellipse" || node.type === "circle") {
|
|
5596
|
+
const cx = Number((_e = node.cx) != null ? _e : 0), cy = Number((_f = node.cy) != null ? _f : 0);
|
|
5597
|
+
const rx = node.type === "circle" ? Number((_g = node.r) != null ? _g : 0) : Number((_h = node.rx) != null ? _h : 0);
|
|
5598
|
+
const ry = node.type === "circle" ? Number((_i = node.r) != null ? _i : 0) : Number((_j = node.ry) != null ? _j : 0);
|
|
5599
|
+
if (!(rx > 0) || !(ry > 0)) return void 0;
|
|
5600
|
+
const kx = rx * ARC_KAPPA, ky = ry * ARC_KAPPA;
|
|
5601
|
+
const c = (x1, y1, x2, y2, x, y) => "C" + x1 + "," + y1 + " " + x2 + "," + y2 + " " + x + "," + y;
|
|
5602
|
+
return "M" + (cx + rx) + "," + cy + c(cx + rx, cy + ky, cx + kx, cy + ry, cx, cy + ry) + c(cx - kx, cy + ry, cx - rx, cy + ky, cx - rx, cy) + c(cx - rx, cy - ky, cx - kx, cy - ry, cx, cy - ry) + c(cx + kx, cy - ry, cx + rx, cy - ky, cx + rx, cy) + "z";
|
|
5603
|
+
}
|
|
5604
|
+
return void 0;
|
|
5605
|
+
}
|
|
5606
|
+
|
|
5607
|
+
// src/effects/PlayerEffectsUtil.ts
|
|
5608
|
+
function materializeNodeEffects(root) {
|
|
5609
|
+
var _a2, _b;
|
|
5610
|
+
const ctx = {
|
|
5611
|
+
defs: [],
|
|
5612
|
+
warnings: [],
|
|
5613
|
+
errors: [],
|
|
5614
|
+
idMap: /* @__PURE__ */ new Map(),
|
|
5615
|
+
nextId: 0,
|
|
5616
|
+
contentRefInnerIds: /* @__PURE__ */ new Map(),
|
|
5617
|
+
maskAncestorChains: /* @__PURE__ */ new Map(),
|
|
5618
|
+
// Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
|
|
5619
|
+
// waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
|
|
5620
|
+
engine: resolveTimelineEngine((_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.engine),
|
|
5621
|
+
glyphs: (_b = getDefinitions(root)) == null ? void 0 : _b.fonts
|
|
5622
|
+
};
|
|
5623
|
+
const working = clone(root);
|
|
5624
|
+
indexById(working, ctx.idMap);
|
|
5625
|
+
identifyContentRefTargets(working, ctx, () => genId(ctx, "inner"));
|
|
5626
|
+
collectMaskAncestorChains(working, ctx);
|
|
5627
|
+
const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);
|
|
5628
|
+
const out = applyPlayerEffects_retime(afterPass1, ctx);
|
|
5629
|
+
spliceDefs(out, ctx.defs);
|
|
5630
|
+
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
5631
|
+
}
|
|
5632
|
+
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
5633
|
+
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
5634
|
+
const fx = node.effects;
|
|
5635
|
+
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
5636
|
+
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
5637
|
+
if (!fx && !innerIdForContentRef) return node;
|
|
5638
|
+
const { transformBy, repeater, maskedBy, clipPath, strokeTrim, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
|
|
5639
|
+
if (fx) delete node.effects;
|
|
5640
|
+
let n = node;
|
|
5641
|
+
let consumedByGlyphs = false;
|
|
5642
|
+
if (text == null ? void 0 : text.useGlyphs) {
|
|
5643
|
+
if (textPath) {
|
|
5644
|
+
const pathD = typeof textPath.pathData === "string" ? textPath.pathData : void 0;
|
|
5645
|
+
const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textPath.textLength, textPath.pathOverflow);
|
|
5646
|
+
if (glyphed) {
|
|
5647
|
+
n = glyphed;
|
|
5648
|
+
consumedByGlyphs = true;
|
|
5649
|
+
}
|
|
5650
|
+
} else {
|
|
5651
|
+
n = applyTextGlyphsEffect(n, text, ctx);
|
|
5652
|
+
consumedByGlyphs = true;
|
|
5653
|
+
}
|
|
5654
|
+
}
|
|
5655
|
+
if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
|
|
5656
|
+
n = applyFillGradientEffect(n, fillGradient, ctx);
|
|
5657
|
+
n = applyStrokeGradientEffect(n, strokeGradient, ctx);
|
|
5658
|
+
n = applyStrokeTrimEffect(n, strokeTrim, ctx);
|
|
5659
|
+
n = applyRepeaterEffect(n, repeater, ctx);
|
|
5660
|
+
n = applyMaskedByEffect(n, maskedBy, transformBy, ctx);
|
|
5661
|
+
n = applyClipPathEffect(n, clipPath, ctx);
|
|
5662
|
+
if (innerIdForContentRef) {
|
|
5663
|
+
applyRefHref(n, cloneFx, ctx);
|
|
5664
|
+
n = splitForContentRef(n, transformBy, originalId, innerIdForContentRef, ctx);
|
|
5665
|
+
} else {
|
|
5666
|
+
n = applyRefAndTransformationEffect(n, cloneFx, transformBy, ctx);
|
|
5667
|
+
}
|
|
5668
|
+
if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
|
|
5669
|
+
if (originalId) ctx.idMap.set(originalId, n);
|
|
5670
|
+
return n;
|
|
5671
|
+
}
|
|
5672
|
+
function applyPlayerEffects_retime(node, ctx) {
|
|
5673
|
+
applyAllRetimeEffects(node, ctx);
|
|
5674
|
+
return node;
|
|
5675
|
+
}
|
|
5676
|
+
|
|
5677
|
+
// src/materialize/PxOffsetPathMaterializer.ts
|
|
5678
|
+
function cubicAt(p0, c1, c2, p1, t) {
|
|
5679
|
+
const u = 1 - t;
|
|
5680
|
+
const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
|
|
5681
|
+
return [
|
|
5682
|
+
a * p0[0] + b * c1[0] + c * c2[0] + d * p1[0],
|
|
5683
|
+
a * p0[1] + b * c1[1] + c * c2[1] + d * p1[1]
|
|
5684
|
+
];
|
|
5685
|
+
}
|
|
5686
|
+
function cubicLength(p0, c1, c2, p1, steps = 64) {
|
|
5687
|
+
let len = 0;
|
|
5688
|
+
let prev = p0;
|
|
5689
|
+
for (let i = 1; i <= steps; i++) {
|
|
5690
|
+
const pt = cubicAt(p0, c1, c2, p1, i / steps);
|
|
5691
|
+
len += Math.hypot(pt[0] - prev[0], pt[1] - prev[1]);
|
|
5692
|
+
prev = pt;
|
|
5693
|
+
}
|
|
5694
|
+
return len;
|
|
5695
|
+
}
|
|
5696
|
+
var fmt2 = (n) => {
|
|
5697
|
+
const r = Math.round(n * 1e4) / 1e4;
|
|
5698
|
+
return Object.is(r, -0) ? "0" : String(r);
|
|
5699
|
+
};
|
|
5700
|
+
function buildOffsetPath(propAnim) {
|
|
5701
|
+
var _a2, _b, _c;
|
|
5702
|
+
if (propAnim.alongPathMode !== "offsetPath") return void 0;
|
|
5703
|
+
const kfs = propAnim.keyframes;
|
|
5704
|
+
if (!kfs || kfs.length < 2) return void 0;
|
|
5705
|
+
const first = keyframeValue(kfs[0]);
|
|
5706
|
+
const anchor = (first == null ? void 0 : first.origin) && first.origin.length >= 2 ? [first.origin[0], first.origin[1]] : [0, 0];
|
|
5707
|
+
const points = [];
|
|
5708
|
+
let keyframesCarryRotate = false;
|
|
5709
|
+
for (const kf of kfs) {
|
|
5710
|
+
const v = keyframeValue(kf);
|
|
5711
|
+
const tr = v == null ? void 0 : v.translate;
|
|
5712
|
+
if (!tr || tr.length < 2) return void 0;
|
|
5713
|
+
const parts = Object.keys(v);
|
|
5714
|
+
if (parts.some((p) => p !== TRANSFORM_PART.translate && p !== TRANSFORM_PART.origin && p !== TRANSFORM_PART.rotate)) return void 0;
|
|
5715
|
+
if ((v == null ? void 0 : v.rotate) !== void 0) {
|
|
5716
|
+
if (v.rotate !== 0) return void 0;
|
|
5717
|
+
keyframesCarryRotate = true;
|
|
5718
|
+
}
|
|
5719
|
+
const o = (_a2 = v == null ? void 0 : v.origin) != null ? _a2 : [0, 0];
|
|
5720
|
+
if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
|
|
5721
|
+
points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
|
|
5722
|
+
}
|
|
5723
|
+
if (!kfs.some((kf) => keyframeTangentIn(kf) || keyframeTangentOut(kf))) return void 0;
|
|
5724
|
+
let d = "M" + fmt2(points[0][0]) + "," + fmt2(points[0][1]);
|
|
5725
|
+
const segLens = [];
|
|
5726
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
5727
|
+
const p0 = points[i], p1 = points[i + 1];
|
|
5728
|
+
const to = (_b = keyframeTangentOut(kfs[i])) != null ? _b : [0, 0];
|
|
5729
|
+
const ti = (_c = keyframeTangentIn(kfs[i + 1])) != null ? _c : [0, 0];
|
|
5730
|
+
const c1 = [p0[0] + to[0], p0[1] + to[1]];
|
|
5731
|
+
const c2 = [p1[0] + ti[0], p1[1] + ti[1]];
|
|
5732
|
+
d += "C" + fmt2(c1[0]) + "," + fmt2(c1[1]) + "," + fmt2(c2[0]) + "," + fmt2(c2[1]) + "," + fmt2(p1[0]) + "," + fmt2(p1[1]);
|
|
5733
|
+
segLens.push(cubicLength(p0, c1, c2, p1));
|
|
5734
|
+
}
|
|
5735
|
+
const total = segLens.reduce((a, b) => a + b, 0);
|
|
5736
|
+
if (!(total > 0)) return void 0;
|
|
5737
|
+
const distanceKfs = [];
|
|
5738
|
+
let cum = 0;
|
|
5739
|
+
for (let i = 0; i < kfs.length; i++) {
|
|
5740
|
+
if (i > 0) cum += segLens[i - 1];
|
|
5741
|
+
const out = { t: keyframeTime(kfs[i]), v: cum / total };
|
|
5742
|
+
const e = keyframeEasing(kfs[i]);
|
|
5743
|
+
if (e !== void 0) out.e = e;
|
|
5744
|
+
distanceKfs.push(out);
|
|
5745
|
+
}
|
|
5746
|
+
return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor, keyframesCarryRotate };
|
|
5747
|
+
}
|
|
5748
|
+
function materializeOffsetPathsInTree(root) {
|
|
5749
|
+
const walk = (node) => {
|
|
5750
|
+
var _a2;
|
|
5751
|
+
let out = node;
|
|
5752
|
+
const anim = node.animate;
|
|
5753
|
+
const transform = anim == null ? void 0 : anim["transform"];
|
|
5754
|
+
if (transform) {
|
|
5755
|
+
const built = buildOffsetPath(transform);
|
|
5756
|
+
if (built) {
|
|
5757
|
+
const newAnimate = __spreadValues({}, anim);
|
|
5758
|
+
delete newAnimate[TRANSFORM_ATTR];
|
|
5759
|
+
const distance = { keyframes: built.distanceKfs };
|
|
5760
|
+
if (transform.loop !== void 0) distance.loop = transform.loop;
|
|
5761
|
+
newAnimate[OFFSET_DISTANCE_ATTR] = distance;
|
|
5762
|
+
const staticTr = node.transform;
|
|
5763
|
+
let newTransform = staticTr;
|
|
5764
|
+
if (staticTr && typeof staticTr === "object") {
|
|
5765
|
+
const t = __spreadValues({}, staticTr);
|
|
5766
|
+
delete t[TRANSFORM_PART.translate];
|
|
5767
|
+
delete t[TRANSFORM_PART.origin];
|
|
5768
|
+
if (built.keyframesCarryRotate) delete t[TRANSFORM_PART.rotate];
|
|
5769
|
+
newTransform = Object.keys(t).length ? t : void 0;
|
|
5770
|
+
}
|
|
5771
|
+
out = __spreadProps(__spreadValues({}, node), {
|
|
5772
|
+
animate: newAnimate,
|
|
5773
|
+
style: __spreadProps(__spreadValues({}, node.style), {
|
|
5774
|
+
offsetPath: "path('" + built.pathStr + "')",
|
|
5775
|
+
offsetAnchor: fmt2(built.anchor[0]) + "px " + fmt2(built.anchor[1]) + "px",
|
|
5776
|
+
offsetRotate: built.autoOrient ? "auto" : "0deg",
|
|
5777
|
+
offsetDistance: "0%"
|
|
5778
|
+
})
|
|
5779
|
+
});
|
|
5780
|
+
if (newTransform !== void 0) out.transform = newTransform;
|
|
5781
|
+
else delete out.transform;
|
|
5782
|
+
}
|
|
5783
|
+
}
|
|
5784
|
+
if ((_a2 = out.children) == null ? void 0 : _a2.length) {
|
|
5785
|
+
const children = out.children.map(walk);
|
|
5786
|
+
if (children.some((c, i) => c !== out.children[i])) out = __spreadProps(__spreadValues({}, out), { children });
|
|
5787
|
+
}
|
|
5788
|
+
return out;
|
|
5789
|
+
};
|
|
5790
|
+
return walk(root);
|
|
5791
|
+
}
|
|
5792
|
+
|
|
5793
|
+
// src/materialize/PxAnimatorUseMaterializer.ts
|
|
5794
|
+
function materializeAnimatedUseInstances(root) {
|
|
5795
|
+
var _a2;
|
|
5796
|
+
const idMap = buildIdMap2(root);
|
|
5797
|
+
const animatedIds = computeAnimatedSubtreeIds(root, idMap);
|
|
5798
|
+
if (animatedIds.size === 0) return root;
|
|
5799
|
+
let idCounter = 0;
|
|
5800
|
+
const genId3 = () => "_lw_use_mat_" + ++idCounter;
|
|
5801
|
+
const rootViewport = readRootViewport(root);
|
|
5802
|
+
const defsCollector = [];
|
|
5803
|
+
const walked = walkAndMaterialize2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
5804
|
+
if (defsCollector.length === 0) return walked;
|
|
5805
|
+
const defsNode = { type: "defs", children: defsCollector };
|
|
5806
|
+
const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
|
|
5807
|
+
return __spreadProps(__spreadValues({}, walked), { children: newChildren });
|
|
5808
|
+
}
|
|
5809
|
+
function readRootViewport(root) {
|
|
5810
|
+
const vb = parseViewBox(root.viewBox);
|
|
5811
|
+
if (vb) return [vb[2], vb[3]];
|
|
5812
|
+
const w = numericAttr(root.width);
|
|
5813
|
+
const h = numericAttr(root.height);
|
|
5814
|
+
if (w !== void 0 && h !== void 0) return [w, h];
|
|
5815
|
+
return [1, 1];
|
|
5816
|
+
}
|
|
5817
|
+
function numericAttr(v) {
|
|
5818
|
+
if (typeof v === "number") return v;
|
|
5819
|
+
if (typeof v === "string") {
|
|
5820
|
+
const n = parseFloat(v);
|
|
5821
|
+
return Number.isFinite(n) ? n : void 0;
|
|
5822
|
+
}
|
|
5823
|
+
return void 0;
|
|
5824
|
+
}
|
|
5825
|
+
function buildIdMap2(root) {
|
|
5826
|
+
const map = /* @__PURE__ */ new Map();
|
|
5827
|
+
const visit = (n) => {
|
|
5828
|
+
var _a2;
|
|
5829
|
+
if (typeof n.id === "string") map.set(n.id, n);
|
|
5830
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
|
|
5831
|
+
};
|
|
5832
|
+
visit(root);
|
|
5833
|
+
return map;
|
|
5834
|
+
}
|
|
5835
|
+
function computeAnimatedSubtreeIds(root, idMap) {
|
|
5836
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
5837
|
+
const result = /* @__PURE__ */ new Set();
|
|
5838
|
+
const hasAnim = (n, visiting) => {
|
|
5839
|
+
const cached = cache.get(n);
|
|
5840
|
+
if (cached !== void 0) return cached;
|
|
5841
|
+
if (visiting.has(n)) return false;
|
|
5842
|
+
visiting.add(n);
|
|
5843
|
+
let r = false;
|
|
5844
|
+
if (n.animate && typeof n.animate === "object" && !Array.isArray(n.animate)) {
|
|
5845
|
+
for (const _ in n.animate) {
|
|
5846
|
+
r = true;
|
|
5847
|
+
break;
|
|
5848
|
+
}
|
|
5849
|
+
}
|
|
5850
|
+
if (!r && n.children) {
|
|
5851
|
+
for (const ch of n.children) {
|
|
5852
|
+
if (hasAnim(ch, visiting)) {
|
|
5853
|
+
r = true;
|
|
5854
|
+
break;
|
|
5855
|
+
}
|
|
5856
|
+
}
|
|
5857
|
+
}
|
|
5858
|
+
if (!r && n.type === "use" && typeof n.href === "string") {
|
|
5859
|
+
const targetId = stripHash2(n.href);
|
|
5860
|
+
const target = targetId ? idMap.get(targetId) : void 0;
|
|
5861
|
+
if (target) r = hasAnim(target, visiting);
|
|
5862
|
+
}
|
|
5863
|
+
visiting.delete(n);
|
|
5864
|
+
cache.set(n, r);
|
|
5865
|
+
return r;
|
|
5866
|
+
};
|
|
5867
|
+
for (const [id, node] of idMap) {
|
|
5868
|
+
if (hasAnim(node, /* @__PURE__ */ new Set())) result.add(id);
|
|
5869
|
+
}
|
|
5870
|
+
return result;
|
|
5871
|
+
}
|
|
5872
|
+
function stripHash2(href) {
|
|
5873
|
+
if (typeof href !== "string") return void 0;
|
|
5874
|
+
return href.startsWith("#") ? href.slice(1) : href;
|
|
5875
|
+
}
|
|
5876
|
+
function materializeOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
|
|
5877
|
+
var _a2, _b, _c, _d;
|
|
5878
|
+
const clone2 = deepClonePxNode(target);
|
|
5879
|
+
regenerateIdsAndRewriteRefs(clone2, genId3);
|
|
5880
|
+
const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
|
|
5881
|
+
const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
|
|
5882
|
+
const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
|
|
5883
|
+
const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
|
|
5884
|
+
const materializedClone = walkAndMaterialize2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
5885
|
+
const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materializedClone] });
|
|
5886
|
+
delete newNode.href;
|
|
5887
|
+
delete newNode.width;
|
|
5888
|
+
delete newNode.height;
|
|
5889
|
+
return applyUseOffsetToG(newNode);
|
|
5890
|
+
}
|
|
5891
|
+
function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector, useW, useH) {
|
|
5892
|
+
const viewBox = parseViewBox(symbolNode.viewBox);
|
|
5893
|
+
const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
|
|
5894
|
+
delete g.viewBox;
|
|
5895
|
+
delete g.preserveAspectRatio;
|
|
5896
|
+
delete g.width;
|
|
5897
|
+
delete g.height;
|
|
5898
|
+
if (!viewBox) return g;
|
|
5899
|
+
const [vbX, vbY, vbW, vbH] = viewBox;
|
|
5900
|
+
const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;
|
|
5901
|
+
const xOff = (useW - vbW * scale) / 2;
|
|
5902
|
+
const yOff = (useH - vbH * scale) / 2;
|
|
5903
|
+
const parts = [];
|
|
5904
|
+
if (xOff !== 0 || yOff !== 0) parts.push("translate(" + xOff + "," + yOff + ")");
|
|
5905
|
+
if (scale !== 1) parts.push("scale(" + scale + ")");
|
|
5906
|
+
if (vbX !== 0 || vbY !== 0) parts.push("translate(" + -vbX + "," + -vbY + ")");
|
|
5907
|
+
if (parts.length) g.transform = parts.join("");
|
|
5908
|
+
const clipId = genId3();
|
|
5909
|
+
defsCollector.push({
|
|
5910
|
+
type: "clipPath",
|
|
5911
|
+
id: clipId,
|
|
5912
|
+
children: [{ type: "rect", x: vbX, y: vbY, width: vbW, height: vbH }]
|
|
5913
|
+
});
|
|
5914
|
+
g.clipPath = "url(#" + clipId + ")";
|
|
5915
|
+
return g;
|
|
5916
|
+
}
|
|
5917
|
+
function parseViewBox(v) {
|
|
5918
|
+
if (typeof v !== "string") return void 0;
|
|
5919
|
+
const parts = v.trim().split(/[\s,]+/).map(Number);
|
|
5920
|
+
if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
|
|
5921
|
+
return [parts[0], parts[1], parts[2], parts[3]];
|
|
5922
|
+
}
|
|
5923
|
+
function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
|
|
5924
|
+
if (node.type === "use" && typeof node.href === "string") {
|
|
5925
|
+
const targetId = stripHash2(node.href);
|
|
5926
|
+
if (targetId && animatedIds.has(targetId)) {
|
|
5927
|
+
const target = idMap.get(targetId);
|
|
5928
|
+
if (target) return materializeOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
5929
|
+
}
|
|
3155
5930
|
}
|
|
3156
|
-
|
|
5931
|
+
if (!node.children) return node;
|
|
5932
|
+
let changed = false;
|
|
5933
|
+
const newChildren = node.children.map((ch) => {
|
|
5934
|
+
const m = walkAndMaterialize2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
5935
|
+
if (m !== ch) changed = true;
|
|
5936
|
+
return m;
|
|
5937
|
+
});
|
|
5938
|
+
return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
|
|
3157
5939
|
}
|
|
3158
5940
|
|
|
3159
|
-
// src/
|
|
3160
|
-
var
|
|
3161
|
-
function
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
5941
|
+
// src/util/PxIdUtil.ts
|
|
5942
|
+
var _idCounter = 0;
|
|
5943
|
+
function generateUniqueId() {
|
|
5944
|
+
const timestamp = Date.now().toString(36);
|
|
5945
|
+
const counter = (++_idCounter).toString(36);
|
|
5946
|
+
const random = Math.random().toString(36).substring(2, 6);
|
|
5947
|
+
return "_px_" + timestamp + counter + random;
|
|
5948
|
+
}
|
|
5949
|
+
function deepClone(value) {
|
|
5950
|
+
if (value === null || typeof value !== "object") return value;
|
|
5951
|
+
if (Array.isArray(value)) return value.map((item) => deepClone(item));
|
|
5952
|
+
const obj = value;
|
|
5953
|
+
const cloned = {};
|
|
5954
|
+
for (const key of Object.keys(obj)) {
|
|
5955
|
+
cloned[key] = deepClone(obj[key]);
|
|
3166
5956
|
}
|
|
5957
|
+
return cloned;
|
|
3167
5958
|
}
|
|
3168
|
-
function
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
const
|
|
3172
|
-
const
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
5959
|
+
function generateNewIds(doc) {
|
|
5960
|
+
var _a2;
|
|
5961
|
+
const cloned = deepClone(doc);
|
|
5962
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
5963
|
+
const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
|
|
5964
|
+
const urlRefAttrs = /* @__PURE__ */ new Set([
|
|
5965
|
+
"fill",
|
|
5966
|
+
"stroke",
|
|
5967
|
+
"clip-path",
|
|
5968
|
+
"clipPath",
|
|
5969
|
+
"mask",
|
|
5970
|
+
"marker",
|
|
5971
|
+
"marker-start",
|
|
5972
|
+
"marker-mid",
|
|
5973
|
+
"marker-end",
|
|
5974
|
+
"filter",
|
|
5975
|
+
"flood-color",
|
|
5976
|
+
"lighting-color"
|
|
5977
|
+
]);
|
|
5978
|
+
const directIdRefAttrs = /* @__PURE__ */ new Set(["targetId", "boundElementId"]);
|
|
5979
|
+
const isEffectSourceRef = (key, parentKey) => key === "source" && (parentKey === "maskedBy" || parentKey === "clone");
|
|
5980
|
+
function collectIds(node) {
|
|
5981
|
+
if (!node || typeof node !== "object") return;
|
|
5982
|
+
if (node.id && typeof node.id === "string") {
|
|
5983
|
+
const oldId = node.id;
|
|
5984
|
+
const newId = generateUniqueId();
|
|
5985
|
+
idMap.set(oldId, newId);
|
|
5986
|
+
node.id = newId;
|
|
5987
|
+
} else if (node.animate) {
|
|
5988
|
+
node.id = generateUniqueId();
|
|
5989
|
+
}
|
|
5990
|
+
if (Array.isArray(node.children)) {
|
|
5991
|
+
for (const child of node.children) {
|
|
5992
|
+
collectIds(child);
|
|
5993
|
+
}
|
|
5994
|
+
}
|
|
5995
|
+
}
|
|
5996
|
+
function updateRefs(node, parentKey) {
|
|
5997
|
+
if (!node || typeof node !== "object") return;
|
|
5998
|
+
for (const [key, value] of Object.entries(node)) {
|
|
5999
|
+
if (key === "children") {
|
|
6000
|
+
if (Array.isArray(value)) {
|
|
6001
|
+
for (const child of value) {
|
|
6002
|
+
updateRefs(child);
|
|
6003
|
+
}
|
|
6004
|
+
}
|
|
6005
|
+
continue;
|
|
6006
|
+
}
|
|
6007
|
+
if (typeof value === "string") {
|
|
6008
|
+
if (hashRefAttrs.has(key) && value.startsWith("#")) {
|
|
6009
|
+
const oldId = value.slice(1);
|
|
6010
|
+
const newId = idMap.get(oldId);
|
|
6011
|
+
if (newId) {
|
|
6012
|
+
node[key] = "#" + newId;
|
|
6013
|
+
}
|
|
6014
|
+
} else if (urlRefAttrs.has(key)) {
|
|
6015
|
+
node[key] = replaceUrlRefs(value, idMap);
|
|
6016
|
+
} else if (directIdRefAttrs.has(key) || isEffectSourceRef(key, parentKey)) {
|
|
6017
|
+
const hasHash = value.startsWith("#");
|
|
6018
|
+
const newId = idMap.get(hasHash ? value.slice(1) : value);
|
|
6019
|
+
if (newId) {
|
|
6020
|
+
node[key] = hasHash ? "#" + newId : newId;
|
|
6021
|
+
}
|
|
6022
|
+
} else if (value.includes("url(#")) {
|
|
6023
|
+
node[key] = replaceUrlRefs(value, idMap);
|
|
6024
|
+
}
|
|
6025
|
+
} else if (key === "style" && typeof value === "object" && value !== null) {
|
|
6026
|
+
for (const [styleProp, styleValue] of Object.entries(value)) {
|
|
6027
|
+
if (typeof styleValue === "string") {
|
|
6028
|
+
value[styleProp] = replaceUrlRefs(styleValue, idMap);
|
|
6029
|
+
}
|
|
6030
|
+
}
|
|
6031
|
+
} else if (typeof value === "object" && value !== null) {
|
|
6032
|
+
updateRefs(value, key);
|
|
6033
|
+
}
|
|
6034
|
+
}
|
|
6035
|
+
}
|
|
6036
|
+
collectIds(cloned);
|
|
6037
|
+
updateRefs(cloned);
|
|
6038
|
+
const docBindings = (_a2 = cloned.animator) == null ? void 0 : _a2.bindings;
|
|
6039
|
+
if (Array.isArray(docBindings)) {
|
|
6040
|
+
const updatedBindings = docBindings.map((binding) => {
|
|
6041
|
+
var _a3;
|
|
6042
|
+
const hashed = binding.target.startsWith("#");
|
|
6043
|
+
const id = hashed ? binding.target.slice(1) : binding.target;
|
|
6044
|
+
const newId = (_a3 = idMap.get(id)) != null ? _a3 : id;
|
|
6045
|
+
return __spreadProps(__spreadValues({}, binding), { target: hashed ? "#" + newId : newId });
|
|
6046
|
+
});
|
|
6047
|
+
cloned.animator = __spreadProps(__spreadValues({}, cloned.animator), { bindings: updatedBindings });
|
|
6048
|
+
}
|
|
6049
|
+
return cloned;
|
|
6050
|
+
}
|
|
6051
|
+
function replaceUrlRefs(value, idMap) {
|
|
6052
|
+
return value.replace(/url\(#([^)]+)\)/g, (match, oldId) => {
|
|
6053
|
+
const newId = idMap.get(oldId);
|
|
6054
|
+
return newId ? "url(#" + newId + ")" : match;
|
|
6055
|
+
});
|
|
6056
|
+
}
|
|
6057
|
+
|
|
6058
|
+
// src/materialize/PxRestPose.ts
|
|
6059
|
+
var TRANSFORM_CHANNEL = "transform";
|
|
6060
|
+
var REVERSED_DIRECTIONS = /* @__PURE__ */ new Set(["reverse", "alternate-reverse"]);
|
|
6061
|
+
var SCRATCH_ID_PREFIX = "__px_rest_";
|
|
6062
|
+
function materializeRestPosesInTree(root, engine) {
|
|
6063
|
+
var _a2;
|
|
6064
|
+
const out = deepClone(root);
|
|
6065
|
+
const config = getAnimatorConfig(out) || {};
|
|
6066
|
+
const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
|
|
6067
|
+
const firstFrameTime = REVERSED_DIRECTIONS.has(String(config.direction)) ? duration : 0;
|
|
6068
|
+
const nodes = animatedNodes(out);
|
|
6069
|
+
if (!nodes.size) return out;
|
|
6070
|
+
const before = bindingsOf(out, engine);
|
|
6071
|
+
const added = /* @__PURE__ */ new Map();
|
|
6072
|
+
for (const [key, animate] of before) {
|
|
6073
|
+
const node = nodes.get(key);
|
|
6074
|
+
if (!node) continue;
|
|
6075
|
+
for (const channel of Object.keys(animate)) {
|
|
6076
|
+
if (!mayCarryRestPose(node, channel)) continue;
|
|
6077
|
+
const value = firstFrameValue(animate, channel, firstFrameTime);
|
|
6078
|
+
if (value === void 0) continue;
|
|
6079
|
+
node[channel] = value;
|
|
6080
|
+
added.set(key, [...(_a2 = added.get(key)) != null ? _a2 : [], channel]);
|
|
6081
|
+
}
|
|
6082
|
+
}
|
|
6083
|
+
if (added.size) {
|
|
6084
|
+
const after = bindingsOf(out, engine);
|
|
6085
|
+
for (const [key, channels] of added) {
|
|
6086
|
+
if (JSON.stringify(after.get(key)) === JSON.stringify(before.get(key))) continue;
|
|
6087
|
+
const node = nodes.get(key);
|
|
6088
|
+
if (node) for (const channel of channels) delete node[channel];
|
|
6089
|
+
}
|
|
6090
|
+
}
|
|
6091
|
+
return out;
|
|
6092
|
+
}
|
|
6093
|
+
function mayCarryRestPose(node, channel) {
|
|
6094
|
+
if (node[channel] !== void 0) return false;
|
|
6095
|
+
if (PX_TRANSFORM_FN_NAMES.has(channel)) return false;
|
|
6096
|
+
if (channel === TRANSFORM_CHANNEL) {
|
|
6097
|
+
for (const part of PX_TRANSFORM_FN_NAMES) if (node[part] !== void 0) return false;
|
|
6098
|
+
}
|
|
6099
|
+
return true;
|
|
6100
|
+
}
|
|
6101
|
+
function firstFrameValue(animate, channel, timeMs) {
|
|
6102
|
+
const values = Object.values(calcAnimationValues({ [channel]: animate[channel] }, timeMs));
|
|
6103
|
+
return values.length === 1 && values[0] !== "" ? values[0] : void 0;
|
|
6104
|
+
}
|
|
6105
|
+
function bindingsOf(tree, engine) {
|
|
6106
|
+
const scratch = deepClone(tree);
|
|
6107
|
+
const keyById = /* @__PURE__ */ new Map();
|
|
6108
|
+
for (const [key, node] of animatedNodes(scratch)) {
|
|
6109
|
+
if (node.id === void 0) node.id = SCRATCH_ID_PREFIX + key;
|
|
6110
|
+
keyById.set(String(node.id), key);
|
|
6111
|
+
}
|
|
6112
|
+
const out = /* @__PURE__ */ new Map();
|
|
6113
|
+
for (const binding of normalizeBindings(scratch, engine)) {
|
|
6114
|
+
const key = keyById.get(binding.id);
|
|
6115
|
+
if (key !== void 0) out.set(key, binding.animate);
|
|
6116
|
+
}
|
|
6117
|
+
return out;
|
|
6118
|
+
}
|
|
6119
|
+
function animatedNodes(tree) {
|
|
6120
|
+
const out = /* @__PURE__ */ new Map();
|
|
6121
|
+
let counter = 0;
|
|
6122
|
+
const visit = (node) => {
|
|
6123
|
+
if (node.animate) out.set(String(counter++), node);
|
|
6124
|
+
if (node.children) for (const child of node.children) visit(child);
|
|
6125
|
+
};
|
|
6126
|
+
if (tree.children) for (const child of tree.children) visit(child);
|
|
6127
|
+
return out;
|
|
6128
|
+
}
|
|
6129
|
+
|
|
6130
|
+
// src/materialize/PxAnimatorMaterializeAll.ts
|
|
6131
|
+
function materializeAllInTree(doc, engine, options) {
|
|
6132
|
+
var _a2, _b;
|
|
6133
|
+
let root = materializeNodeEffects(doc).root;
|
|
6134
|
+
root = materializeOffsetPathsInTree(root);
|
|
6135
|
+
const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : PX_DEFAULT_DURATION_MS;
|
|
6136
|
+
root = materializeInternalLoopsInTree(root, duration);
|
|
6137
|
+
if (engine === PxTimelineEngine.native) {
|
|
6138
|
+
root = materializeMotionPathsInTree(root, options == null ? void 0 : options.motionPath);
|
|
6139
|
+
root = materializeAnimatedUseInstances(root);
|
|
6140
|
+
root = pruneUnreferencedDefs(root);
|
|
6141
|
+
}
|
|
6142
|
+
root = materializeRestPosesInTree(root, engine);
|
|
6143
|
+
return root;
|
|
6144
|
+
}
|
|
6145
|
+
function prepareDocumentForRender(doc) {
|
|
6146
|
+
var _a2;
|
|
6147
|
+
const engine = resolveTimelineEngine((_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.engine);
|
|
6148
|
+
return generateNewIds(materializeAllInTree(doc, engine));
|
|
6149
|
+
}
|
|
6150
|
+
function pruneUnreferencedDefs(root) {
|
|
6151
|
+
const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
|
|
6152
|
+
const walk = (n, fn) => {
|
|
6153
|
+
var _a2;
|
|
6154
|
+
fn(n);
|
|
6155
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach((c) => walk(c, fn));
|
|
6156
|
+
};
|
|
6157
|
+
let changed = true;
|
|
6158
|
+
while (changed) {
|
|
6159
|
+
changed = false;
|
|
6160
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
6161
|
+
walk(root, (n) => {
|
|
6162
|
+
if (n.type === "use" && typeof n.href === "string") referenced.add(stripHash3(n.href));
|
|
6163
|
+
});
|
|
6164
|
+
walk(root, (n) => {
|
|
6165
|
+
if (!n.children) return;
|
|
6166
|
+
let kept = n.children;
|
|
6167
|
+
if (n.type === "defs") {
|
|
6168
|
+
kept = kept.filter((c) => !((c.type === "g" || c.type === "symbol") && typeof c.id === "string" && !referenced.has(c.id)));
|
|
6169
|
+
}
|
|
6170
|
+
kept = kept.filter((c) => !(c.type === "defs" && (!c.children || c.children.length === 0)));
|
|
6171
|
+
if (kept.length !== n.children.length) {
|
|
6172
|
+
n.children = kept;
|
|
6173
|
+
changed = true;
|
|
6174
|
+
}
|
|
6175
|
+
});
|
|
6176
|
+
}
|
|
6177
|
+
return root;
|
|
3176
6178
|
}
|
|
3177
6179
|
|
|
3178
6180
|
// src/playback/PxDiagnostics.ts
|
|
6181
|
+
var PxDiagnosticKind = {
|
|
6182
|
+
/** The document is wrong — regenerate or repair the file. */
|
|
6183
|
+
document: "document",
|
|
6184
|
+
/** The page or app cannot provide what the document asks for — fix the mount. */
|
|
6185
|
+
host: "host",
|
|
6186
|
+
/** The platform cannot do it and the player degraded — usually nothing to fix. */
|
|
6187
|
+
platform: "platform",
|
|
6188
|
+
/** The call is wrong or self-contradictory — fix the options or props you passed. */
|
|
6189
|
+
usage: "usage",
|
|
6190
|
+
/** The player failed where it did not expect to — report it to us. */
|
|
6191
|
+
internal: "internal"
|
|
6192
|
+
};
|
|
3179
6193
|
var DOCS_URL = "https://github.com/pixodesk/pixodesk-svg-animator/blob/main/docs/diagnostics.md";
|
|
3180
6194
|
function codeLine(code) {
|
|
3181
6195
|
return "PX" + code + " " + DOCS_URL + "#px" + code;
|
|
@@ -3208,81 +6222,6 @@ function createDiagnostics(config, prefix) {
|
|
|
3208
6222
|
};
|
|
3209
6223
|
}
|
|
3210
6224
|
|
|
3211
|
-
// src/playback/PxScrollMath.ts
|
|
3212
|
-
function isScrollTimeline(config) {
|
|
3213
|
-
return (config == null ? void 0 : config.timelineSource) === "scroll";
|
|
3214
|
-
}
|
|
3215
|
-
function scrollTotalDurationMs(config) {
|
|
3216
|
-
const duration = typeof (config == null ? void 0 : config.duration) === "number" && config.duration > 0 ? config.duration : PX_DEFAULT_DURATION_MS;
|
|
3217
|
-
const iterations = typeof (config == null ? void 0 : config.iterations) === "number" && config.iterations > 0 ? config.iterations : 1;
|
|
3218
|
-
return duration * iterations;
|
|
3219
|
-
}
|
|
3220
|
-
function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
|
|
3221
|
-
const s = subjectSize, vp = scrollportSize;
|
|
3222
|
-
switch (phase) {
|
|
3223
|
-
case "cover":
|
|
3224
|
-
return [0, s + vp];
|
|
3225
|
-
case "entry":
|
|
3226
|
-
return [0, Math.min(s, vp)];
|
|
3227
|
-
case "contain":
|
|
3228
|
-
return [Math.min(s, vp), Math.max(s, vp)];
|
|
3229
|
-
case "exit":
|
|
3230
|
-
return [Math.max(s, vp), s + vp];
|
|
3231
|
-
case "entry-crossing":
|
|
3232
|
-
return [0, s];
|
|
3233
|
-
case "exit-crossing":
|
|
3234
|
-
return [vp, s + vp];
|
|
3235
|
-
}
|
|
3236
|
-
}
|
|
3237
|
-
var DEFAULT_PHASE = "cover";
|
|
3238
|
-
function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
|
|
3239
|
-
var _a2;
|
|
3240
|
-
const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
|
|
3241
|
-
const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
|
|
3242
|
-
return u0 + fraction * (u1 - u0);
|
|
3243
|
-
}
|
|
3244
|
-
function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
|
|
3245
|
-
const u = scrollportSize - subjectStart;
|
|
3246
|
-
const uStart = resolveRangePointU(range == null ? void 0 : range.start, 0, subjectSize, scrollportSize);
|
|
3247
|
-
const uEnd = resolveRangePointU(range == null ? void 0 : range.end, 1, subjectSize, scrollportSize);
|
|
3248
|
-
if (uEnd <= uStart) return u >= uEnd ? 1 : 0;
|
|
3249
|
-
return clamp((u - uStart) / (uEnd - uStart), 0, 1);
|
|
3250
|
-
}
|
|
3251
|
-
function scrollOffsetProgress(offset, maxOffset, range) {
|
|
3252
|
-
var _a2, _b;
|
|
3253
|
-
const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
|
|
3254
|
-
const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
|
|
3255
|
-
const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
|
|
3256
|
-
if (end <= start) return raw >= end ? 1 : 0;
|
|
3257
|
-
return clamp((raw - start) / (end - start), 0, 1);
|
|
3258
|
-
}
|
|
3259
|
-
function scrollResolveAxis(axis, writingMode) {
|
|
3260
|
-
const a = axis != null ? axis : "block";
|
|
3261
|
-
if (a === "x" || a === "y") return a;
|
|
3262
|
-
const vertical = !!writingMode && writingMode.startsWith("vertical");
|
|
3263
|
-
if (a === "inline") return vertical ? "y" : "x";
|
|
3264
|
-
return vertical ? "x" : "y";
|
|
3265
|
-
}
|
|
3266
|
-
|
|
3267
|
-
// src/util/PxIdUtil.ts
|
|
3268
|
-
var _idCounter = 0;
|
|
3269
|
-
function generateUniqueId() {
|
|
3270
|
-
const timestamp = Date.now().toString(36);
|
|
3271
|
-
const counter = (++_idCounter).toString(36);
|
|
3272
|
-
const random = Math.random().toString(36).substring(2, 6);
|
|
3273
|
-
return "_px_" + timestamp + counter + random;
|
|
3274
|
-
}
|
|
3275
|
-
function deepClone(value) {
|
|
3276
|
-
if (value === null || typeof value !== "object") return value;
|
|
3277
|
-
if (Array.isArray(value)) return value.map((item) => deepClone(item));
|
|
3278
|
-
const obj = value;
|
|
3279
|
-
const cloned = {};
|
|
3280
|
-
for (const key of Object.keys(obj)) {
|
|
3281
|
-
cloned[key] = deepClone(obj[key]);
|
|
3282
|
-
}
|
|
3283
|
-
return cloned;
|
|
3284
|
-
}
|
|
3285
|
-
|
|
3286
6225
|
// src/util/PxNodeProps.ts
|
|
3287
6226
|
var PX_DISALLOWED_SVG_TAGS_LOWER = /* @__PURE__ */ new Set([
|
|
3288
6227
|
"script",
|
|
@@ -3346,6 +6285,135 @@ function sanitizeAttributeValue(name, value) {
|
|
|
3346
6285
|
}
|
|
3347
6286
|
return value;
|
|
3348
6287
|
}
|
|
6288
|
+
function toDomProps(props) {
|
|
6289
|
+
const propsCopy = {};
|
|
6290
|
+
for (const rawKey of Object.keys(props)) {
|
|
6291
|
+
const key = kebabToCamelCaseWord(rawKey);
|
|
6292
|
+
if (INTERNAL_ATTRS.has(key)) continue;
|
|
6293
|
+
if (key === "style") continue;
|
|
6294
|
+
let value = props[rawKey];
|
|
6295
|
+
if (PX_COLOR_ATTR_NAMES.has(key) && Array.isArray(value)) {
|
|
6296
|
+
propsCopy[key] = toRGBA(value);
|
|
6297
|
+
} else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
|
|
6298
|
+
const parts = value.value && typeof value.value === "object" ? value.value : value;
|
|
6299
|
+
propsCopy[TRANSFORM_ATTR] = composeTransformParts(parts, { withUnits: false });
|
|
6300
|
+
} else if (PX_TRANSFORM_FN_NAMES.has(key)) {
|
|
6301
|
+
if (Array.isArray(value)) {
|
|
6302
|
+
if (key === "translate") value = value.map((v) => v + "px");
|
|
6303
|
+
value = value.join(",");
|
|
6304
|
+
}
|
|
6305
|
+
if (key === "rotate") value = value + "deg";
|
|
6306
|
+
propsCopy[TRANSFORM_ATTR] = key + "(" + value + ")";
|
|
6307
|
+
} else if (Array.isArray(value)) {
|
|
6308
|
+
propsCopy[key] = value.join(",");
|
|
6309
|
+
} else if (value !== void 0 && value !== null) {
|
|
6310
|
+
propsCopy[key] = String(value);
|
|
6311
|
+
}
|
|
6312
|
+
}
|
|
6313
|
+
return propsCopy;
|
|
6314
|
+
}
|
|
6315
|
+
|
|
6316
|
+
// src/render/PxRenderTree.ts
|
|
6317
|
+
var CLASS_NAME_KEY = "className";
|
|
6318
|
+
var CLASS_ATTR2 = "class";
|
|
6319
|
+
var DOM_TYPE_KEY = "domType";
|
|
6320
|
+
var TYPE_ATTR = "type";
|
|
6321
|
+
var DEFAULT_TAG = "g";
|
|
6322
|
+
function renderPxTree(node, factory, diag) {
|
|
6323
|
+
return node ? renderOne(node, factory, diag, true, 0) : null;
|
|
6324
|
+
}
|
|
6325
|
+
function renderOne(node, factory, diag, isRoot, index) {
|
|
6326
|
+
const _a2 = node, { type, children, style } = _a2, props = __objRest(_a2, ["type", "children", "style"]);
|
|
6327
|
+
const tag = type || DEFAULT_TAG;
|
|
6328
|
+
if (PX_DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {
|
|
6329
|
+
(diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]")).warn(PxDiagnosticKind.document, 1103 /* blockedTag */, tag);
|
|
6330
|
+
return null;
|
|
6331
|
+
}
|
|
6332
|
+
const domType = props[DOM_TYPE_KEY];
|
|
6333
|
+
if (domType !== void 0) delete props[DOM_TYPE_KEY];
|
|
6334
|
+
const attrs = {};
|
|
6335
|
+
let inlineStyle;
|
|
6336
|
+
const domProps = toDomProps(props);
|
|
6337
|
+
for (const propName of Object.keys(domProps)) {
|
|
6338
|
+
const sanitized = sanitizeAttributeValue(propName, domProps[propName]);
|
|
6339
|
+
if (sanitized === void 0) continue;
|
|
6340
|
+
if (PX_CSS_ONLY_STYLE_PROPS.has(propName)) {
|
|
6341
|
+
(inlineStyle != null ? inlineStyle : inlineStyle = {})[propName] = String(sanitized);
|
|
6342
|
+
continue;
|
|
6343
|
+
}
|
|
6344
|
+
attrs[propName === CLASS_NAME_KEY ? CLASS_ATTR2 : camelCaseToKebabWordIfNeeded(propName)] = sanitized;
|
|
6345
|
+
}
|
|
6346
|
+
if (domType !== void 0) attrs[TYPE_ATTR] = String(domType);
|
|
6347
|
+
if (style) {
|
|
6348
|
+
for (const styleProp of Object.keys(style)) (inlineStyle != null ? inlineStyle : inlineStyle = {})[styleProp] = String(style[styleProp]);
|
|
6349
|
+
}
|
|
6350
|
+
const rendered = [];
|
|
6351
|
+
if (children) {
|
|
6352
|
+
children.forEach((child, i) => {
|
|
6353
|
+
const el = renderOne(child, factory, diag, false, i);
|
|
6354
|
+
if (el !== null) rendered.push(el);
|
|
6355
|
+
});
|
|
6356
|
+
}
|
|
6357
|
+
const ownText = props[PX_TEXT_CONTENT_ATTR];
|
|
6358
|
+
const text = !rendered.length && typeof ownText === "string" && ownText ? ownText : void 0;
|
|
6359
|
+
return factory({ tag, attrs, style: inlineStyle, children: rendered, text, node, isRoot, index });
|
|
6360
|
+
}
|
|
6361
|
+
|
|
6362
|
+
// src/playback/PxScrollMath.ts
|
|
6363
|
+
function isScrollTimeline(config) {
|
|
6364
|
+
return (config == null ? void 0 : config.timelineSource) === "scroll";
|
|
6365
|
+
}
|
|
6366
|
+
function scrollTotalDurationMs(config) {
|
|
6367
|
+
const duration = typeof (config == null ? void 0 : config.duration) === "number" && config.duration > 0 ? config.duration : PX_DEFAULT_DURATION_MS;
|
|
6368
|
+
const iterations = typeof (config == null ? void 0 : config.iterations) === "number" && config.iterations > 0 ? config.iterations : 1;
|
|
6369
|
+
return duration * iterations;
|
|
6370
|
+
}
|
|
6371
|
+
function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
|
|
6372
|
+
const s = subjectSize, vp = scrollportSize;
|
|
6373
|
+
switch (phase) {
|
|
6374
|
+
case "cover":
|
|
6375
|
+
return [0, s + vp];
|
|
6376
|
+
case "entry":
|
|
6377
|
+
return [0, Math.min(s, vp)];
|
|
6378
|
+
case "contain":
|
|
6379
|
+
return [Math.min(s, vp), Math.max(s, vp)];
|
|
6380
|
+
case "exit":
|
|
6381
|
+
return [Math.max(s, vp), s + vp];
|
|
6382
|
+
case "entry-crossing":
|
|
6383
|
+
return [0, s];
|
|
6384
|
+
case "exit-crossing":
|
|
6385
|
+
return [vp, s + vp];
|
|
6386
|
+
}
|
|
6387
|
+
}
|
|
6388
|
+
var DEFAULT_PHASE = "cover";
|
|
6389
|
+
function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
|
|
6390
|
+
var _a2;
|
|
6391
|
+
const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
|
|
6392
|
+
const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
|
|
6393
|
+
return u0 + fraction * (u1 - u0);
|
|
6394
|
+
}
|
|
6395
|
+
function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
|
|
6396
|
+
const u = scrollportSize - subjectStart;
|
|
6397
|
+
const uStart = resolveRangePointU(range == null ? void 0 : range.start, 0, subjectSize, scrollportSize);
|
|
6398
|
+
const uEnd = resolveRangePointU(range == null ? void 0 : range.end, 1, subjectSize, scrollportSize);
|
|
6399
|
+
if (uEnd <= uStart) return u >= uEnd ? 1 : 0;
|
|
6400
|
+
return clamp((u - uStart) / (uEnd - uStart), 0, 1);
|
|
6401
|
+
}
|
|
6402
|
+
function scrollOffsetProgress(offset, maxOffset, range) {
|
|
6403
|
+
var _a2, _b;
|
|
6404
|
+
const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
|
|
6405
|
+
const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
|
|
6406
|
+
const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
|
|
6407
|
+
if (end <= start) return raw >= end ? 1 : 0;
|
|
6408
|
+
return clamp((raw - start) / (end - start), 0, 1);
|
|
6409
|
+
}
|
|
6410
|
+
function scrollResolveAxis(axis, writingMode) {
|
|
6411
|
+
const a = axis != null ? axis : "block";
|
|
6412
|
+
if (a === "x" || a === "y") return a;
|
|
6413
|
+
const vertical = !!writingMode && writingMode.startsWith("vertical");
|
|
6414
|
+
if (a === "inline") return vertical ? "y" : "x";
|
|
6415
|
+
return vertical ? "x" : "y";
|
|
6416
|
+
}
|
|
3349
6417
|
|
|
3350
6418
|
// src/version/PxSchemaFieldUniverse.ts
|
|
3351
6419
|
function schemaFieldUniverse(root) {
|
|
@@ -3506,7 +6574,9 @@ function releaseLogProblems(releases, steps, declared, baseline) {
|
|
|
3506
6574
|
materializeMotionPathInPropAnim,
|
|
3507
6575
|
mergeStaticTransformIntoAnimDef,
|
|
3508
6576
|
planSchemaRelease,
|
|
6577
|
+
prepareDocumentForRender,
|
|
3509
6578
|
releaseLogProblems,
|
|
6579
|
+
renderPxTree,
|
|
3510
6580
|
reportDocumentDiagnostics,
|
|
3511
6581
|
reverseEasing,
|
|
3512
6582
|
sanitizeAttributeValue,
|