@pixodesk/svg-animator-web 1.0.8 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2285 -392
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2894 -155
- package/dist/index.d.ts +2894 -155
- package/dist/index.js +2249 -391
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.umd.js +2249 -391
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __pow = Math.pow;
|
|
7
8
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
9
|
var __spreadValues = (a, b) => {
|
|
9
10
|
for (var prop in b || (b = {}))
|
|
@@ -30,6 +31,1304 @@ var __objRest = (source, exclude) => {
|
|
|
30
31
|
return target;
|
|
31
32
|
};
|
|
32
33
|
|
|
34
|
+
// src/effects/transformParts.ts
|
|
35
|
+
function partsRecord(part, value, origin) {
|
|
36
|
+
const rec = {};
|
|
37
|
+
if (part === "translate") rec.translate = value;
|
|
38
|
+
else if (part === "rotate") rec.rotate = value;
|
|
39
|
+
else rec.scale = value;
|
|
40
|
+
if (origin && part !== "translate") rec.origin = origin;
|
|
41
|
+
return rec;
|
|
42
|
+
}
|
|
43
|
+
function readAnimatable(raw) {
|
|
44
|
+
if (raw === void 0) return { kind: "absent" };
|
|
45
|
+
if (Array.isArray(raw)) return { kind: "static", value: raw };
|
|
46
|
+
if (typeof raw === "object") {
|
|
47
|
+
const obj = raw;
|
|
48
|
+
if (obj.keyframes) {
|
|
49
|
+
return { kind: "animated", keyframes: obj.keyframes, autoOrient: obj.autoOrient };
|
|
50
|
+
}
|
|
51
|
+
if (obj.value !== void 0) return { kind: "static", value: obj.value };
|
|
52
|
+
}
|
|
53
|
+
return { kind: "static", value: raw };
|
|
54
|
+
}
|
|
55
|
+
function readStaticOrigin(raw, ctx) {
|
|
56
|
+
var _a;
|
|
57
|
+
const o = readAnimatable(raw);
|
|
58
|
+
if (o.kind === "absent") return void 0;
|
|
59
|
+
if (o.kind === "static") return o.value;
|
|
60
|
+
ctx.warnings.push("transformation.origin: animated origin approximated by its first keyframe");
|
|
61
|
+
return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
|
|
62
|
+
}
|
|
63
|
+
function keyframeWith(kf, value) {
|
|
64
|
+
const out = { value };
|
|
65
|
+
if (kf.time !== void 0) out.time = kf.time;
|
|
66
|
+
if (kf.easing !== void 0) out.easing = kf.easing;
|
|
67
|
+
if (kf.tangentOut !== void 0) out.tangentOut = kf.tangentOut;
|
|
68
|
+
if (kf.tangentIn !== void 0) out.tangentIn = kf.tangentIn;
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/effects/transformationEffect.ts
|
|
73
|
+
function applyTransformationEffect(node, fx, ctx) {
|
|
74
|
+
if (!fx) return node;
|
|
75
|
+
delete node.transform;
|
|
76
|
+
let n = node;
|
|
77
|
+
n = wrapTransformPart(n, "skew", fx.skew, ctx);
|
|
78
|
+
n = wrapOrigin(
|
|
79
|
+
n,
|
|
80
|
+
fx.origin,
|
|
81
|
+
/*invert=*/
|
|
82
|
+
true
|
|
83
|
+
);
|
|
84
|
+
n = wrapTransformPart(n, "scale", normalizeScale(fx.scale), ctx);
|
|
85
|
+
n = wrapTransformPart(n, "rotate", fx.rotate, ctx);
|
|
86
|
+
n = wrapOrigin(
|
|
87
|
+
n,
|
|
88
|
+
fx.origin,
|
|
89
|
+
/*invert=*/
|
|
90
|
+
false
|
|
91
|
+
);
|
|
92
|
+
if (translateHasAutoOrient(fx.translate)) {
|
|
93
|
+
n = wrapOrigin(
|
|
94
|
+
n,
|
|
95
|
+
fx.origin,
|
|
96
|
+
/*invert=*/
|
|
97
|
+
true
|
|
98
|
+
);
|
|
99
|
+
n = wrapTransformPart(n, "translate", fx.translate, ctx);
|
|
100
|
+
n = wrapOrigin(
|
|
101
|
+
n,
|
|
102
|
+
fx.origin,
|
|
103
|
+
/*invert=*/
|
|
104
|
+
false
|
|
105
|
+
);
|
|
106
|
+
} else {
|
|
107
|
+
n = wrapTransformPart(n, "translate", fx.translate, ctx);
|
|
108
|
+
}
|
|
109
|
+
return n;
|
|
110
|
+
}
|
|
111
|
+
function translateHasAutoOrient(translate) {
|
|
112
|
+
if (!translate || typeof translate !== "object") return false;
|
|
113
|
+
const obj = translate;
|
|
114
|
+
if (obj.autoOrient) return true;
|
|
115
|
+
return Array.isArray(obj.keyframes) && obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
|
|
116
|
+
}
|
|
117
|
+
function normalizeScale(raw) {
|
|
118
|
+
if (raw === void 0) return void 0;
|
|
119
|
+
if (Array.isArray(raw)) return [raw[0] / 100, raw[1] / 100];
|
|
120
|
+
return raw;
|
|
121
|
+
}
|
|
122
|
+
function wrapTransformPart(inner, part, raw, ctx) {
|
|
123
|
+
if (raw === void 0) return inner;
|
|
124
|
+
if (part === "skew") {
|
|
125
|
+
const skew = readAnimatable(raw);
|
|
126
|
+
if (skew.kind !== "static") {
|
|
127
|
+
ctx.warnings.push("transformation.skew: only static skew is supported");
|
|
128
|
+
return inner;
|
|
129
|
+
}
|
|
130
|
+
return { type: "g", transform: "skewX(" + skew.value[0] + ")skewY(" + skew.value[1] + ")", children: [inner] };
|
|
131
|
+
}
|
|
132
|
+
const v = readAnimatable(raw);
|
|
133
|
+
if (v.kind === "static") {
|
|
134
|
+
return { type: "g", transform: { value: partsRecord(part, v.value, void 0) }, children: [inner] };
|
|
135
|
+
}
|
|
136
|
+
if (v.kind === "animated") {
|
|
137
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
|
|
138
|
+
if (v.autoOrient) animTr.autoOrient = true;
|
|
139
|
+
return {
|
|
140
|
+
type: "g",
|
|
141
|
+
animate: { transform: animTr },
|
|
142
|
+
children: [inner]
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return inner;
|
|
146
|
+
}
|
|
147
|
+
function wrapOrigin(inner, raw, invert) {
|
|
148
|
+
if (raw === void 0) return inner;
|
|
149
|
+
const v = readAnimatable(raw);
|
|
150
|
+
const sign = (value) => invert ? [-value[0], -value[1]] : value;
|
|
151
|
+
if (v.kind === "absent") return inner;
|
|
152
|
+
if (v.kind === "static") {
|
|
153
|
+
if (v.value[0] === 0 && v.value[1] === 0) return inner;
|
|
154
|
+
return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
|
|
155
|
+
}
|
|
156
|
+
if (v.kind === "animated") {
|
|
157
|
+
return {
|
|
158
|
+
type: "g",
|
|
159
|
+
animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) } },
|
|
160
|
+
children: [inner]
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return inner;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/effects/contentRefSplit.ts
|
|
167
|
+
function identifyContentRefTargets(node, ctx, allocator) {
|
|
168
|
+
var _a, _b, _c;
|
|
169
|
+
if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.ref) == null ? void 0 : _b.type) === "content") {
|
|
170
|
+
const baseId = node.effects.ref.baseId;
|
|
171
|
+
if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
|
|
172
|
+
ctx.contentRefInnerIds.set(baseId, allocator(baseId));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
(_c = node.children) == null ? void 0 : _c.forEach((c) => identifyContentRefTargets(c, ctx, allocator));
|
|
176
|
+
}
|
|
177
|
+
function splitForContentRef(node, transformation, originalId, innerId, ctx) {
|
|
178
|
+
const outerBody = liftBodyTranslate(node, transformation);
|
|
179
|
+
if (typeof node.id === "string") delete node.id;
|
|
180
|
+
const { outer: outerTr, inner: innerTr } = splitTransformationEffect(transformation);
|
|
181
|
+
let innerNode = node;
|
|
182
|
+
innerNode = applyTransformationEffect(innerNode, innerTr, ctx);
|
|
183
|
+
const innerWrapper = { type: "g", id: innerId, children: [innerNode] };
|
|
184
|
+
let outerWrapper = { type: "g", id: originalId, children: [innerWrapper] };
|
|
185
|
+
if (outerBody.transform !== void 0) outerWrapper.transform = outerBody.transform;
|
|
186
|
+
if (outerBody.animate !== void 0) outerWrapper.animate = outerBody.animate;
|
|
187
|
+
if (outerTr) {
|
|
188
|
+
delete outerWrapper.id;
|
|
189
|
+
outerWrapper = applyTransformationEffect(outerWrapper, outerTr, ctx);
|
|
190
|
+
outerWrapper.id = originalId;
|
|
191
|
+
}
|
|
192
|
+
return outerWrapper;
|
|
193
|
+
}
|
|
194
|
+
function liftBodyTranslate(node, transformation) {
|
|
195
|
+
var _a;
|
|
196
|
+
const out = {};
|
|
197
|
+
let didLiftAnimate = false;
|
|
198
|
+
const animTr = (_a = node.animate) == null ? void 0 : _a.transform;
|
|
199
|
+
if (animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes)) {
|
|
200
|
+
const kfs = animTr.keyframes;
|
|
201
|
+
const hasTranslate = kfs.some((kf) => kf.value && kf.value.translate);
|
|
202
|
+
if (hasTranslate) {
|
|
203
|
+
const outerHasOrigin = needsOriginOnOuter(animTr);
|
|
204
|
+
const outerKfs = kfs.map((kf) => {
|
|
205
|
+
const v = kf.value || {};
|
|
206
|
+
const newValue = {};
|
|
207
|
+
if (v.translate !== void 0) newValue.translate = v.translate;
|
|
208
|
+
if (outerHasOrigin && v.origin !== void 0) newValue.origin = v.origin;
|
|
209
|
+
const outerKf = { value: newValue };
|
|
210
|
+
if (kf.time !== void 0) outerKf.time = kf.time;
|
|
211
|
+
if (kf.easing !== void 0) outerKf.easing = kf.easing;
|
|
212
|
+
if (kf.tangentOut !== void 0) outerKf.tangentOut = kf.tangentOut;
|
|
213
|
+
if (kf.tangentIn !== void 0) outerKf.tangentIn = kf.tangentIn;
|
|
214
|
+
return outerKf;
|
|
215
|
+
});
|
|
216
|
+
const outerAnimTr = { keyframes: outerKfs };
|
|
217
|
+
if (animTr.autoOrient) outerAnimTr.autoOrient = true;
|
|
218
|
+
out.animate = { transform: outerAnimTr };
|
|
219
|
+
const innerHasPivotedPart = kfs.some((kf) => {
|
|
220
|
+
const v = kf.value || {};
|
|
221
|
+
return v.rotate !== void 0 || v.scale !== void 0;
|
|
222
|
+
});
|
|
223
|
+
const innerKfs = kfs.map((kf) => {
|
|
224
|
+
const v = kf.value || {};
|
|
225
|
+
const newValue = {};
|
|
226
|
+
if (v.rotate !== void 0) newValue.rotate = v.rotate;
|
|
227
|
+
if (v.scale !== void 0) newValue.scale = v.scale;
|
|
228
|
+
if (v.origin !== void 0 && (!outerHasOrigin || innerHasPivotedPart)) newValue.origin = v.origin;
|
|
229
|
+
const innerKf = { value: newValue };
|
|
230
|
+
if (kf.time !== void 0) innerKf.time = kf.time;
|
|
231
|
+
if (kf.easing !== void 0) innerKf.easing = kf.easing;
|
|
232
|
+
return innerKf;
|
|
233
|
+
});
|
|
234
|
+
const allInnerEmpty = innerKfs.every((kf) => Object.keys(kf.value).length === 0);
|
|
235
|
+
if (allInnerEmpty) {
|
|
236
|
+
delete node.animate.transform;
|
|
237
|
+
if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;
|
|
238
|
+
} else {
|
|
239
|
+
node.animate.transform = { keyframes: innerKfs };
|
|
240
|
+
}
|
|
241
|
+
didLiftAnimate = true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const transformationHasTranslate = (transformation == null ? void 0 : transformation.translate) !== void 0;
|
|
245
|
+
const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
|
|
246
|
+
if (typeof node.transform === "string") {
|
|
247
|
+
const split = splitTransformString(node.transform);
|
|
248
|
+
if (stripBodyTranslateOnly) {
|
|
249
|
+
if (split.translate !== void 0) {
|
|
250
|
+
if (split.rest) node.transform = split.rest;
|
|
251
|
+
else delete node.transform;
|
|
252
|
+
} else if (isPureTranslateBody(node.transform)) {
|
|
253
|
+
delete node.transform;
|
|
254
|
+
}
|
|
255
|
+
} else if (split.translate) {
|
|
256
|
+
out.transform = split.translate;
|
|
257
|
+
if (split.rest) node.transform = split.rest;
|
|
258
|
+
else delete node.transform;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return out;
|
|
262
|
+
}
|
|
263
|
+
function isPureTranslateBody(s) {
|
|
264
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
265
|
+
const ops = [];
|
|
266
|
+
let m;
|
|
267
|
+
while (m = re.exec(s)) ops.push({ name: m[1], full: m[0] });
|
|
268
|
+
if (ops.length !== 1) return false;
|
|
269
|
+
if (ops[0].name === "translate") return true;
|
|
270
|
+
if (ops[0].name !== "matrix") return false;
|
|
271
|
+
const args = /matrix\(([^)]*)\)/.exec(ops[0].full);
|
|
272
|
+
if (!args) return false;
|
|
273
|
+
const nums = args[1].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
274
|
+
return nums.length >= 4 && nums[0] === 1 && nums[1] === 0 && nums[2] === 0 && nums[3] === 1;
|
|
275
|
+
}
|
|
276
|
+
function splitTransformString(s) {
|
|
277
|
+
const ops = [];
|
|
278
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
279
|
+
let m;
|
|
280
|
+
while (m = re.exec(s)) ops.push({ name: m[1], full: m[0] });
|
|
281
|
+
if (!ops.length) return { rest: s || void 0 };
|
|
282
|
+
if (ops.every((o) => o.name === "translate")) {
|
|
283
|
+
return { translate: ops.map((o) => o.full).join("") };
|
|
284
|
+
}
|
|
285
|
+
const leading = ops[0];
|
|
286
|
+
const trailing = ops[ops.length - 1];
|
|
287
|
+
if (trailing.name === "translate" && leading.name === "translate") {
|
|
288
|
+
const trailingVec = parseTranslateArgs(trailing.full);
|
|
289
|
+
const leadingVec = parseTranslateArgs(leading.full);
|
|
290
|
+
const ox = -trailingVec[0];
|
|
291
|
+
const oy = -trailingVec[1];
|
|
292
|
+
const userTx = leadingVec[0] - ox;
|
|
293
|
+
const userTy = leadingVec[1] - oy;
|
|
294
|
+
if (userTx === 0 && userTy === 0) return { rest: s };
|
|
295
|
+
const middleAndTrailing = "translate(" + ox + "," + oy + ")" + ops.slice(1).map((o) => o.full).join("");
|
|
296
|
+
return { translate: "translate(" + userTx + "," + userTy + ")", rest: middleAndTrailing };
|
|
297
|
+
}
|
|
298
|
+
if (trailing.name === "translate") return { rest: s };
|
|
299
|
+
const lifted = [];
|
|
300
|
+
let i = 0;
|
|
301
|
+
while (i < ops.length && ops[i].name === "translate") {
|
|
302
|
+
lifted.push(ops[i].full);
|
|
303
|
+
i++;
|
|
304
|
+
}
|
|
305
|
+
if (!lifted.length) return { rest: s };
|
|
306
|
+
const rest = ops.slice(i).map((o) => o.full).join("");
|
|
307
|
+
return {
|
|
308
|
+
translate: lifted.join(""),
|
|
309
|
+
rest: rest || void 0
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function parseTranslateArgs(translateOp) {
|
|
313
|
+
const m = /translate\(([^)]*)\)/.exec(translateOp);
|
|
314
|
+
if (!m) return [0, 0];
|
|
315
|
+
const nums = m[1].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
316
|
+
return [nums[0] || 0, nums[1] || 0];
|
|
317
|
+
}
|
|
318
|
+
function splitTransformationEffect(fx) {
|
|
319
|
+
if (!fx) return {};
|
|
320
|
+
const originOnOuter = needsOriginOnOuter(fx.translate);
|
|
321
|
+
const innerHasPivotedPart = fx.rotate !== void 0 || fx.scale !== void 0;
|
|
322
|
+
const outer = {};
|
|
323
|
+
const inner = {};
|
|
324
|
+
if (fx.translate !== void 0) outer.translate = fx.translate;
|
|
325
|
+
if (originOnOuter && fx.origin !== void 0) outer.origin = fx.origin;
|
|
326
|
+
if (fx.rotate !== void 0) inner.rotate = fx.rotate;
|
|
327
|
+
if (fx.scale !== void 0) inner.scale = fx.scale;
|
|
328
|
+
if (fx.skew !== void 0) inner.skew = fx.skew;
|
|
329
|
+
if (fx.origin !== void 0 && (!originOnOuter || innerHasPivotedPart)) inner.origin = fx.origin;
|
|
330
|
+
return {
|
|
331
|
+
outer: Object.keys(outer).length ? outer : void 0,
|
|
332
|
+
inner: Object.keys(inner).length ? inner : void 0
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function needsOriginOnOuter(translateAnim) {
|
|
336
|
+
if (!translateAnim || typeof translateAnim !== "object") return false;
|
|
337
|
+
const obj = translateAnim;
|
|
338
|
+
if (obj.autoOrient) return true;
|
|
339
|
+
if (Array.isArray(obj.keyframes)) {
|
|
340
|
+
return obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
|
|
341
|
+
}
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// src/effects/util.ts
|
|
346
|
+
function genId(ctx, prefix) {
|
|
347
|
+
return "_lw_" + prefix + "_" + ctx.nextId++;
|
|
348
|
+
}
|
|
349
|
+
function indexById(node, map) {
|
|
350
|
+
var _a;
|
|
351
|
+
if (typeof node.id === "string") map.set(node.id, node);
|
|
352
|
+
(_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
|
|
353
|
+
}
|
|
354
|
+
function spliceDefs(root, defs) {
|
|
355
|
+
if (!defs.length) return;
|
|
356
|
+
const existing = root.children || (root.children = []);
|
|
357
|
+
existing.unshift({ type: "defs", children: defs });
|
|
358
|
+
}
|
|
359
|
+
function clone(value) {
|
|
360
|
+
if (value === null || typeof value !== "object") return value;
|
|
361
|
+
if (Array.isArray(value)) return value.map(clone);
|
|
362
|
+
const out = {};
|
|
363
|
+
for (const k of Object.keys(value)) out[k] = clone(value[k]);
|
|
364
|
+
return out;
|
|
365
|
+
}
|
|
366
|
+
function regenerateIdsInClone(root, ctx) {
|
|
367
|
+
const oldToNew = /* @__PURE__ */ new Map();
|
|
368
|
+
const walkAssign = (n) => {
|
|
369
|
+
var _a;
|
|
370
|
+
if (typeof n.id === "string") {
|
|
371
|
+
const newId = genId(ctx, "retimed");
|
|
372
|
+
oldToNew.set(n.id, newId);
|
|
373
|
+
n.id = newId;
|
|
374
|
+
}
|
|
375
|
+
(_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
|
|
376
|
+
};
|
|
377
|
+
walkAssign(root);
|
|
378
|
+
const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
|
|
379
|
+
const newId = oldToNew.get(oldId);
|
|
380
|
+
return newId ? "url(#" + newId + ")" : m;
|
|
381
|
+
});
|
|
382
|
+
const walkRewrite = (n) => {
|
|
383
|
+
var _a;
|
|
384
|
+
if (typeof n.href === "string" && n.href.startsWith("#")) {
|
|
385
|
+
const newId = oldToNew.get(n.href.slice(1));
|
|
386
|
+
if (newId) n.href = "#" + newId;
|
|
387
|
+
}
|
|
388
|
+
for (const k of Object.keys(n)) {
|
|
389
|
+
if (k === "children" || k === "effects" || k === "meta" || k === "href" || k === "id") continue;
|
|
390
|
+
const v = n[k];
|
|
391
|
+
if (typeof v === "string" && v.indexOf("url(#") !== -1) n[k] = rewriteUrl(v);
|
|
392
|
+
}
|
|
393
|
+
(_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
|
|
394
|
+
};
|
|
395
|
+
walkRewrite(root);
|
|
396
|
+
return oldToNew;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// src/effects/maskedByEffect.ts
|
|
400
|
+
function applyMaskedByEffect(node, fx, transformation, ctx) {
|
|
401
|
+
if (!fx) return node;
|
|
402
|
+
if (!fx.href) {
|
|
403
|
+
ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
|
|
404
|
+
return node;
|
|
405
|
+
}
|
|
406
|
+
const maskId = genId(ctx, "mask");
|
|
407
|
+
let content = { type: "use", href: "#" + fx.href };
|
|
408
|
+
content = wrapInverseTransform(content, transformation, ctx);
|
|
409
|
+
const mask = { type: "mask", id: maskId, children: [content] };
|
|
410
|
+
if (fx.maskType) mask.maskType = fx.maskType;
|
|
411
|
+
if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
|
|
412
|
+
if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
|
|
413
|
+
ctx.defs.push(mask);
|
|
414
|
+
node.mask = "url(#" + maskId + ")";
|
|
415
|
+
return node;
|
|
416
|
+
}
|
|
417
|
+
function wrapInverseTransform(inner, fx, ctx) {
|
|
418
|
+
if (!fx) return inner;
|
|
419
|
+
const origin = readStaticOrigin(fx.origin, ctx);
|
|
420
|
+
let n = inner;
|
|
421
|
+
n = wrapInversePart(n, "translate", fx.translate, void 0, ctx);
|
|
422
|
+
n = wrapInversePart(n, "rotate", fx.rotate, origin, ctx);
|
|
423
|
+
n = wrapInversePart(n, "scale", fx.scale, origin, ctx);
|
|
424
|
+
return n;
|
|
425
|
+
}
|
|
426
|
+
function wrapInversePart(inner, part, raw, origin, ctx) {
|
|
427
|
+
if (raw === void 0) return inner;
|
|
428
|
+
const v = readAnimatable(raw);
|
|
429
|
+
if (v.kind === "static") {
|
|
430
|
+
return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
|
|
431
|
+
}
|
|
432
|
+
if (v.kind === "animated") {
|
|
433
|
+
return {
|
|
434
|
+
type: "g",
|
|
435
|
+
animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) } },
|
|
436
|
+
children: [inner]
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
return inner;
|
|
440
|
+
}
|
|
441
|
+
function invertPartValue(part, value) {
|
|
442
|
+
if (part === "translate") return [-value[0], -value[1]];
|
|
443
|
+
if (part === "rotate") return -value;
|
|
444
|
+
return [1 / value[0], 1 / value[1]];
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// src/effects/refEffect.ts
|
|
448
|
+
var CONTENT_SUBREF = "content";
|
|
449
|
+
function applyRefAndTransformationEffect(node, ref, transformation, ctx) {
|
|
450
|
+
if (ref) {
|
|
451
|
+
const baseId = ref.baseId;
|
|
452
|
+
if (!baseId) {
|
|
453
|
+
ctx.errors.push("ref: missing baseId");
|
|
454
|
+
} else {
|
|
455
|
+
const targetId = ref.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
|
|
456
|
+
node.href = "#" + targetId;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return applyTransformationEffect(node, transformation, ctx);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// src/effects/repeaterEffect.ts
|
|
463
|
+
function applyRepeaterEffect(node, fx, ctx) {
|
|
464
|
+
var _a, _b;
|
|
465
|
+
if (!fx) return node;
|
|
466
|
+
const copies = (_a = fx.copies) != null ? _a : 1;
|
|
467
|
+
if (copies < 1) {
|
|
468
|
+
ctx.errors.push("repeater.copies invalid: " + fx.copies);
|
|
469
|
+
return node;
|
|
470
|
+
}
|
|
471
|
+
const sharedTransform = node.transform;
|
|
472
|
+
const sharedAnimTransform = (_b = node.animate) == null ? void 0 : _b.transform;
|
|
473
|
+
const base = clone(node);
|
|
474
|
+
delete base.transform;
|
|
475
|
+
if (base.animate) {
|
|
476
|
+
delete base.animate.transform;
|
|
477
|
+
if (Object.keys(base.animate).length === 0) delete base.animate;
|
|
478
|
+
}
|
|
479
|
+
const children = [base];
|
|
480
|
+
for (let i = 1; i < copies; i++) {
|
|
481
|
+
const copy = clone(base);
|
|
482
|
+
copy.transform = { value: perCopyParts(fx, i) };
|
|
483
|
+
children.push(copy);
|
|
484
|
+
}
|
|
485
|
+
const wrapper = { type: "g", children };
|
|
486
|
+
if (sharedTransform !== void 0) wrapper.transform = sharedTransform;
|
|
487
|
+
if (sharedAnimTransform !== void 0) wrapper.animate = { transform: sharedAnimTransform };
|
|
488
|
+
return wrapper;
|
|
489
|
+
}
|
|
490
|
+
function perCopyParts(fx, i) {
|
|
491
|
+
const parts = {};
|
|
492
|
+
if (fx.translate) parts.translate = [fx.translate[0] * i, fx.translate[1] * i];
|
|
493
|
+
if (fx.rotate !== void 0) parts.rotate = fx.rotate * i;
|
|
494
|
+
if (fx.scale) parts.scale = [__pow(fx.scale[0] / 100, i), __pow(fx.scale[1] / 100, i)];
|
|
495
|
+
if (fx.origin) parts.origin = [fx.origin[0] * i, fx.origin[1] * i];
|
|
496
|
+
return parts;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// src/effects/retimeEffect.ts
|
|
500
|
+
var RETIME_AS_SYMBOL = true;
|
|
501
|
+
function applyRetimeEffect(node, retime, ctx) {
|
|
502
|
+
var _a, _b, _c, _d;
|
|
503
|
+
if (!retime) return node;
|
|
504
|
+
const baseId = retime.baseId;
|
|
505
|
+
if (!baseId) {
|
|
506
|
+
ctx.errors.push("retime: missing baseId");
|
|
507
|
+
return node;
|
|
508
|
+
}
|
|
509
|
+
const target = ctx.idMap.get(baseId);
|
|
510
|
+
if (!target) {
|
|
511
|
+
ctx.warnings.push('retime: target "' + baseId + '" not found');
|
|
512
|
+
return node;
|
|
513
|
+
}
|
|
514
|
+
const start = (_a = retime.start) != null ? _a : 0;
|
|
515
|
+
const stretch = (_b = retime.stretch) != null ? _b : 1;
|
|
516
|
+
if (RETIME_AS_SYMBOL) {
|
|
517
|
+
const symbolClone = clone(target);
|
|
518
|
+
regenerateIdsInClone(symbolClone, ctx);
|
|
519
|
+
const cloneId = genId(ctx, "retime");
|
|
520
|
+
symbolClone.id = cloneId;
|
|
521
|
+
remapKeyframeTimes(symbolClone, start, stretch);
|
|
522
|
+
ctx.defs.push(symbolClone);
|
|
523
|
+
node.href = "#" + cloneId;
|
|
524
|
+
return node;
|
|
525
|
+
}
|
|
526
|
+
const sourceNodes = target.type === "symbol" ? target.children || [] : [target];
|
|
527
|
+
const content = sourceNodes.map((child) => {
|
|
528
|
+
const c = clone(child);
|
|
529
|
+
regenerateIdsInClone(c, ctx);
|
|
530
|
+
remapKeyframeTimes(c, start, stretch);
|
|
531
|
+
return c;
|
|
532
|
+
});
|
|
533
|
+
const g = __spreadProps(__spreadValues({}, node), { type: "g", children: content });
|
|
534
|
+
delete g.href;
|
|
535
|
+
const x = Number((_c = node.x) != null ? _c : 0), y = Number((_d = node.y) != null ? _d : 0);
|
|
536
|
+
if (x || y) {
|
|
537
|
+
const offset = "translate(" + x + "," + y + ")";
|
|
538
|
+
g.transform = typeof g.transform === "string" ? offset + g.transform : offset;
|
|
539
|
+
delete g.x;
|
|
540
|
+
delete g.y;
|
|
541
|
+
}
|
|
542
|
+
return g;
|
|
543
|
+
}
|
|
544
|
+
function remapKeyframeTimes(node, start, stretch) {
|
|
545
|
+
var _a;
|
|
546
|
+
const remap2 = (kfs) => {
|
|
547
|
+
for (const kf of kfs) if (typeof kf.time === "number") kf.time = start + kf.time * stretch;
|
|
548
|
+
};
|
|
549
|
+
if (node.transform && typeof node.transform === "object" && Array.isArray(node.transform.keyframes)) {
|
|
550
|
+
remap2(node.transform.keyframes);
|
|
551
|
+
}
|
|
552
|
+
if (node.animate && typeof node.animate === "object") {
|
|
553
|
+
for (const prop of Object.keys(node.animate)) {
|
|
554
|
+
const anim = node.animate[prop];
|
|
555
|
+
if (anim && Array.isArray(anim.keyframes)) remap2(anim.keyframes);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
(_a = node.children) == null ? void 0 : _a.forEach((child) => remapKeyframeTimes(child, start, stretch));
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// src/effects/trimPathEffect.ts
|
|
562
|
+
function applyTrimPathEffect(node, trimPath, isCombinedShape) {
|
|
563
|
+
var _a;
|
|
564
|
+
if (!trimPath && !isCombinedShape) return node;
|
|
565
|
+
const d = (_a = node.d) != null ? _a : rectToPathD(node);
|
|
566
|
+
if (d === void 0) return node;
|
|
567
|
+
const g = __spreadProps(__spreadValues({}, node), { type: "g" });
|
|
568
|
+
delete g.d;
|
|
569
|
+
const meta = g.meta = __spreadValues({}, g.meta || {});
|
|
570
|
+
const effects = meta.effects = __spreadValues({}, meta.effects || {});
|
|
571
|
+
if (trimPath) effects.trimPath = trimPath;
|
|
572
|
+
effects.isCombinedShape = true;
|
|
573
|
+
g.children = [{ type: "path", d }];
|
|
574
|
+
return g;
|
|
575
|
+
}
|
|
576
|
+
function rectToPathD(node) {
|
|
577
|
+
var _a, _b, _c, _d;
|
|
578
|
+
if (node.type !== "rect") return void 0;
|
|
579
|
+
const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
|
|
580
|
+
const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
|
|
581
|
+
return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// src/effects/PlayerEffectsUtil.ts
|
|
585
|
+
function applyPlayerEffects(root) {
|
|
586
|
+
const ctx = {
|
|
587
|
+
defs: [],
|
|
588
|
+
warnings: [],
|
|
589
|
+
errors: [],
|
|
590
|
+
idMap: /* @__PURE__ */ new Map(),
|
|
591
|
+
nextId: 0,
|
|
592
|
+
contentRefInnerIds: /* @__PURE__ */ new Map()
|
|
593
|
+
};
|
|
594
|
+
const working = clone(root);
|
|
595
|
+
indexById(working, ctx.idMap);
|
|
596
|
+
identifyContentRefTargets(working, ctx, () => genId(ctx, "inner"));
|
|
597
|
+
const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);
|
|
598
|
+
const out = applyPlayerEffects_retime(afterPass1, ctx);
|
|
599
|
+
spliceDefs(out, ctx.defs);
|
|
600
|
+
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
601
|
+
}
|
|
602
|
+
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
603
|
+
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
604
|
+
const fx = node.effects;
|
|
605
|
+
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
606
|
+
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
607
|
+
if (!fx && !innerIdForContentRef) return node;
|
|
608
|
+
const { transformation, repeater, maskedBy, trimPath, retime, ref } = fx != null ? fx : {};
|
|
609
|
+
const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
|
|
610
|
+
if (fx) delete node.effects;
|
|
611
|
+
let n = node;
|
|
612
|
+
n = applyTrimPathEffect(n, trimPath, isCombinedShape);
|
|
613
|
+
n = applyRepeaterEffect(n, repeater, ctx);
|
|
614
|
+
n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
|
|
615
|
+
if (innerIdForContentRef) {
|
|
616
|
+
n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
|
|
617
|
+
} else {
|
|
618
|
+
n = applyRefAndTransformationEffect(n, ref, transformation, ctx);
|
|
619
|
+
}
|
|
620
|
+
if (retime) node.effects = { retime };
|
|
621
|
+
if (originalId) ctx.idMap.set(originalId, n);
|
|
622
|
+
return n;
|
|
623
|
+
}
|
|
624
|
+
function applyPlayerEffects_retime(node, ctx) {
|
|
625
|
+
var _a;
|
|
626
|
+
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_retime(child, ctx));
|
|
627
|
+
const retime = (_a = node.effects) == null ? void 0 : _a.retime;
|
|
628
|
+
if (!retime) return node;
|
|
629
|
+
delete node.effects;
|
|
630
|
+
return applyRetimeEffect(node, retime, ctx);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// src/PxSchema.ts
|
|
634
|
+
function pathStr(path) {
|
|
635
|
+
if (!path.length) return ".";
|
|
636
|
+
let result = "";
|
|
637
|
+
for (const seg of path) {
|
|
638
|
+
if (seg.startsWith("[")) result += seg;
|
|
639
|
+
else result += (result ? "." : "") + seg;
|
|
640
|
+
}
|
|
641
|
+
return result;
|
|
642
|
+
}
|
|
643
|
+
var Base = class {
|
|
644
|
+
_canSanitize(raw) {
|
|
645
|
+
return this.isValid(raw);
|
|
646
|
+
}
|
|
647
|
+
optional() {
|
|
648
|
+
return new Optional(this);
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
var Optional = class extends Base {
|
|
652
|
+
constructor(inner) {
|
|
653
|
+
super();
|
|
654
|
+
this.inner = inner;
|
|
655
|
+
this._default = void 0;
|
|
656
|
+
}
|
|
657
|
+
sanitize(raw) {
|
|
658
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
659
|
+
return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
|
|
660
|
+
}
|
|
661
|
+
isValid(raw, ctx, path) {
|
|
662
|
+
if (raw === void 0 || raw === null) return true;
|
|
663
|
+
return this.inner.isValid(raw, ctx, path);
|
|
664
|
+
}
|
|
665
|
+
_canSanitize(raw) {
|
|
666
|
+
return raw === void 0 || raw === null || this.inner._canSanitize(raw);
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
var Str = class extends Base {
|
|
670
|
+
constructor(_default = "") {
|
|
671
|
+
super();
|
|
672
|
+
this._default = _default;
|
|
673
|
+
}
|
|
674
|
+
sanitize(raw) {
|
|
675
|
+
return typeof raw === "string" ? raw : this._default;
|
|
676
|
+
}
|
|
677
|
+
isValid(raw, ctx, path) {
|
|
678
|
+
if (typeof raw === "string") return true;
|
|
679
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected string, got " + typeof raw);
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
var Num = class extends Base {
|
|
684
|
+
constructor(_default = 0) {
|
|
685
|
+
super();
|
|
686
|
+
this._default = _default;
|
|
687
|
+
}
|
|
688
|
+
sanitize(raw) {
|
|
689
|
+
return typeof raw === "number" && isFinite(raw) ? raw : this._default;
|
|
690
|
+
}
|
|
691
|
+
isValid(raw, ctx, path) {
|
|
692
|
+
if (typeof raw === "number" && isFinite(raw)) return true;
|
|
693
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected finite number, got " + JSON.stringify(raw));
|
|
694
|
+
return false;
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
var Bool = class extends Base {
|
|
698
|
+
constructor(_default = false) {
|
|
699
|
+
super();
|
|
700
|
+
this._default = _default;
|
|
701
|
+
}
|
|
702
|
+
sanitize(raw) {
|
|
703
|
+
return typeof raw === "boolean" ? raw : this._default;
|
|
704
|
+
}
|
|
705
|
+
isValid(raw, ctx, path) {
|
|
706
|
+
if (typeof raw === "boolean") return true;
|
|
707
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected boolean, got " + typeof raw);
|
|
708
|
+
return false;
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
var Literal = class extends Base {
|
|
712
|
+
constructor(value) {
|
|
713
|
+
super();
|
|
714
|
+
this.value = value;
|
|
715
|
+
this._default = value;
|
|
716
|
+
}
|
|
717
|
+
sanitize(raw) {
|
|
718
|
+
return raw === this.value ? this.value : this._default;
|
|
719
|
+
}
|
|
720
|
+
isValid(raw, ctx, path) {
|
|
721
|
+
if (raw === this.value) return true;
|
|
722
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected " + JSON.stringify(this.value) + ", got " + JSON.stringify(raw));
|
|
723
|
+
return false;
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
var Enum = class extends Base {
|
|
727
|
+
constructor(values, defaultVal) {
|
|
728
|
+
super();
|
|
729
|
+
this.values = values;
|
|
730
|
+
this._default = defaultVal != null ? defaultVal : values[0];
|
|
731
|
+
}
|
|
732
|
+
sanitize(raw) {
|
|
733
|
+
return this.values.includes(raw) ? raw : this._default;
|
|
734
|
+
}
|
|
735
|
+
isValid(raw, ctx, path) {
|
|
736
|
+
if (this.values.includes(raw)) return true;
|
|
737
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected one of " + this.values.map((v) => JSON.stringify(v)).join(" | ") + ", got " + JSON.stringify(raw));
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
var Union = class extends Base {
|
|
742
|
+
constructor(schemas, defaultVal) {
|
|
743
|
+
super();
|
|
744
|
+
this.schemas = schemas;
|
|
745
|
+
this._default = defaultVal != null ? defaultVal : schemas[0]._default;
|
|
746
|
+
}
|
|
747
|
+
sanitize(raw) {
|
|
748
|
+
for (const s of this.schemas) {
|
|
749
|
+
if (s.isValid(raw)) return s.sanitize(raw);
|
|
750
|
+
}
|
|
751
|
+
return this._default;
|
|
752
|
+
}
|
|
753
|
+
isValid(raw, ctx, path) {
|
|
754
|
+
var _a;
|
|
755
|
+
if (this.schemas.some((s) => s.isValid(raw))) return true;
|
|
756
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 60));
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
_canSanitize(raw) {
|
|
760
|
+
return this.schemas.some((s) => s._canSanitize(raw));
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
var DiscriminatedUnion = class extends Base {
|
|
764
|
+
constructor(_key, _schemas, defaultVal) {
|
|
765
|
+
super();
|
|
766
|
+
this._key = _key;
|
|
767
|
+
this._schemas = _schemas;
|
|
768
|
+
this._default = defaultVal != null ? defaultVal : _schemas[0]._default;
|
|
769
|
+
this._map = /* @__PURE__ */ new Map();
|
|
770
|
+
for (const s of _schemas) {
|
|
771
|
+
const keySchema = s._shape[_key];
|
|
772
|
+
if (keySchema) this._map.set(keySchema._default, s);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
_findSchema(raw) {
|
|
776
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
777
|
+
const val = raw[this._key];
|
|
778
|
+
if (val === void 0 || val === null) return void 0;
|
|
779
|
+
return this._map.get(val);
|
|
780
|
+
}
|
|
781
|
+
sanitize(raw) {
|
|
782
|
+
var _a;
|
|
783
|
+
return ((_a = this._findSchema(raw)) != null ? _a : this._schemas[0]).sanitize(raw);
|
|
784
|
+
}
|
|
785
|
+
isValid(raw, ctx, path) {
|
|
786
|
+
const schema = this._findSchema(raw);
|
|
787
|
+
if (!schema) {
|
|
788
|
+
const val = raw !== null && typeof raw === "object" && !Array.isArray(raw) ? raw[this._key] : void 0;
|
|
789
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no discriminated union member matched " + this._key + "=" + JSON.stringify(val));
|
|
790
|
+
return false;
|
|
791
|
+
}
|
|
792
|
+
return schema.isValid(raw, ctx, path);
|
|
793
|
+
}
|
|
794
|
+
_canSanitize(raw) {
|
|
795
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return false;
|
|
796
|
+
const schema = this._findSchema(raw);
|
|
797
|
+
return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
var Obj = class extends Base {
|
|
801
|
+
constructor(_shape) {
|
|
802
|
+
super();
|
|
803
|
+
this._shape = _shape;
|
|
804
|
+
const d = {};
|
|
805
|
+
for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
|
|
806
|
+
this._default = d;
|
|
807
|
+
}
|
|
808
|
+
sanitize(raw) {
|
|
809
|
+
const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
810
|
+
const out = {};
|
|
811
|
+
for (const key of Object.keys(this._shape)) {
|
|
812
|
+
out[key] = this._shape[key].sanitize(src[key]);
|
|
813
|
+
}
|
|
814
|
+
return out;
|
|
815
|
+
}
|
|
816
|
+
isValid(raw, ctx, path) {
|
|
817
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
818
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
819
|
+
return false;
|
|
820
|
+
}
|
|
821
|
+
const obj = raw;
|
|
822
|
+
const p = path != null ? path : [];
|
|
823
|
+
let ok = true;
|
|
824
|
+
for (const key of Object.keys(this._shape)) {
|
|
825
|
+
p.push(key);
|
|
826
|
+
if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;
|
|
827
|
+
p.pop();
|
|
828
|
+
}
|
|
829
|
+
if (ctx == null ? void 0 : ctx.strict) {
|
|
830
|
+
for (const key of Object.keys(obj)) {
|
|
831
|
+
if (key in this._shape) continue;
|
|
832
|
+
p.push(key);
|
|
833
|
+
ctx.errors.push(pathStr(p) + ": unexpected extra key");
|
|
834
|
+
p.pop();
|
|
835
|
+
ok = false;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
return ok;
|
|
839
|
+
}
|
|
840
|
+
_canSanitize(raw) {
|
|
841
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
var OpenObj = class extends Base {
|
|
845
|
+
constructor(_shape, _openSchema) {
|
|
846
|
+
super();
|
|
847
|
+
this._shape = _shape;
|
|
848
|
+
this._openSchema = _openSchema;
|
|
849
|
+
const d = {};
|
|
850
|
+
for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
|
|
851
|
+
this._default = d;
|
|
852
|
+
}
|
|
853
|
+
sanitize(raw) {
|
|
854
|
+
const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
855
|
+
const out = __spreadValues({}, src);
|
|
856
|
+
for (const key of Object.keys(this._shape)) {
|
|
857
|
+
out[key] = this._shape[key].sanitize(src[key]);
|
|
858
|
+
}
|
|
859
|
+
if (this._openSchema) {
|
|
860
|
+
for (const key of Object.keys(src)) {
|
|
861
|
+
if (!(key in this._shape)) out[key] = this._openSchema.sanitize(src[key]);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
return out;
|
|
865
|
+
}
|
|
866
|
+
isValid(raw, ctx, path) {
|
|
867
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
868
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
869
|
+
return false;
|
|
870
|
+
}
|
|
871
|
+
const obj = raw;
|
|
872
|
+
const p = path != null ? path : [];
|
|
873
|
+
let ok = true;
|
|
874
|
+
for (const key of Object.keys(this._shape)) {
|
|
875
|
+
p.push(key);
|
|
876
|
+
if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;
|
|
877
|
+
p.pop();
|
|
878
|
+
}
|
|
879
|
+
if (this._openSchema) {
|
|
880
|
+
for (const key of Object.keys(obj)) {
|
|
881
|
+
if (key in this._shape) continue;
|
|
882
|
+
p.push(key);
|
|
883
|
+
if (!this._openSchema.isValid(obj[key], ctx, p)) ok = false;
|
|
884
|
+
p.pop();
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
return ok;
|
|
888
|
+
}
|
|
889
|
+
_canSanitize(raw) {
|
|
890
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
var Arr = class extends Base {
|
|
894
|
+
constructor(item) {
|
|
895
|
+
super();
|
|
896
|
+
this.item = item;
|
|
897
|
+
this._default = [];
|
|
898
|
+
}
|
|
899
|
+
sanitize(raw) {
|
|
900
|
+
if (!Array.isArray(raw)) return [];
|
|
901
|
+
const out = [];
|
|
902
|
+
for (const el of raw) {
|
|
903
|
+
if (this.item._canSanitize(el)) out.push(this.item.sanitize(el));
|
|
904
|
+
}
|
|
905
|
+
return out;
|
|
906
|
+
}
|
|
907
|
+
isValid(raw, ctx, path) {
|
|
908
|
+
if (!Array.isArray(raw)) {
|
|
909
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected array, got " + typeof raw);
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
const p = path != null ? path : [];
|
|
913
|
+
let ok = true;
|
|
914
|
+
for (let i = 0; i < raw.length; i++) {
|
|
915
|
+
p.push("[" + i + "]");
|
|
916
|
+
if (!this.item.isValid(raw[i], ctx, p)) ok = false;
|
|
917
|
+
p.pop();
|
|
918
|
+
}
|
|
919
|
+
return ok;
|
|
920
|
+
}
|
|
921
|
+
_canSanitize(raw) {
|
|
922
|
+
return Array.isArray(raw);
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
var Rec = class extends Base {
|
|
926
|
+
constructor(value) {
|
|
927
|
+
super();
|
|
928
|
+
this.value = value;
|
|
929
|
+
this._default = {};
|
|
930
|
+
}
|
|
931
|
+
sanitize(raw) {
|
|
932
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
933
|
+
const out = {};
|
|
934
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
935
|
+
if (this.value._canSanitize(v)) out[k] = this.value.sanitize(v);
|
|
936
|
+
}
|
|
937
|
+
return out;
|
|
938
|
+
}
|
|
939
|
+
isValid(raw, ctx, path) {
|
|
940
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
941
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object/record, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
942
|
+
return false;
|
|
943
|
+
}
|
|
944
|
+
const p = path != null ? path : [];
|
|
945
|
+
let ok = true;
|
|
946
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
947
|
+
p.push(k);
|
|
948
|
+
if (!this.value.isValid(v, ctx, p)) ok = false;
|
|
949
|
+
p.pop();
|
|
950
|
+
}
|
|
951
|
+
return ok;
|
|
952
|
+
}
|
|
953
|
+
_canSanitize(raw) {
|
|
954
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
var Any = class extends Base {
|
|
958
|
+
constructor() {
|
|
959
|
+
super(...arguments);
|
|
960
|
+
this._default = void 0;
|
|
961
|
+
}
|
|
962
|
+
sanitize(raw) {
|
|
963
|
+
return raw;
|
|
964
|
+
}
|
|
965
|
+
isValid(_raw, _ctx, _path) {
|
|
966
|
+
return true;
|
|
967
|
+
}
|
|
968
|
+
_canSanitize(_raw) {
|
|
969
|
+
return true;
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
var Lazy = class extends Base {
|
|
973
|
+
constructor(fn, _default) {
|
|
974
|
+
super();
|
|
975
|
+
this.fn = fn;
|
|
976
|
+
this._default = _default;
|
|
977
|
+
this.resolved = null;
|
|
978
|
+
}
|
|
979
|
+
get schema() {
|
|
980
|
+
var _a;
|
|
981
|
+
return (_a = this.resolved) != null ? _a : this.resolved = this.fn();
|
|
982
|
+
}
|
|
983
|
+
sanitize(raw) {
|
|
984
|
+
return this.schema.sanitize(raw);
|
|
985
|
+
}
|
|
986
|
+
isValid(raw, ctx, path) {
|
|
987
|
+
return this.schema.isValid(raw, ctx, path);
|
|
988
|
+
}
|
|
989
|
+
_canSanitize(raw) {
|
|
990
|
+
return this.schema._canSanitize(raw);
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
var Tuple = class extends Base {
|
|
994
|
+
constructor(schemas) {
|
|
995
|
+
super();
|
|
996
|
+
this.schemas = schemas;
|
|
997
|
+
this._default = schemas.map((s) => s._default);
|
|
998
|
+
}
|
|
999
|
+
sanitize(raw) {
|
|
1000
|
+
if (!Array.isArray(raw) || raw.length !== this.schemas.length) return this._default;
|
|
1001
|
+
return this.schemas.map((s, i) => s.sanitize(raw[i]));
|
|
1002
|
+
}
|
|
1003
|
+
isValid(raw, ctx, path) {
|
|
1004
|
+
if (!Array.isArray(raw) || raw.length !== this.schemas.length) {
|
|
1005
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected tuple of length " + this.schemas.length + ", got " + (Array.isArray(raw) ? "array[" + raw.length + "]" : typeof raw));
|
|
1006
|
+
return false;
|
|
1007
|
+
}
|
|
1008
|
+
const p = path != null ? path : [];
|
|
1009
|
+
let ok = true;
|
|
1010
|
+
for (let i = 0; i < this.schemas.length; i++) {
|
|
1011
|
+
p.push("[" + i + "]");
|
|
1012
|
+
if (!this.schemas[i].isValid(raw[i], ctx, p)) ok = false;
|
|
1013
|
+
p.pop();
|
|
1014
|
+
}
|
|
1015
|
+
return ok;
|
|
1016
|
+
}
|
|
1017
|
+
// Require exact length so wrong-length arrays are dropped rather than repaired to default.
|
|
1018
|
+
_canSanitize(raw) {
|
|
1019
|
+
return Array.isArray(raw) && raw.length === this.schemas.length;
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
function implementsInterface() {
|
|
1023
|
+
return (schema) => schema;
|
|
1024
|
+
}
|
|
1025
|
+
function schemaKeys(schema) {
|
|
1026
|
+
return Object.fromEntries(
|
|
1027
|
+
Object.keys(schema["_shape"]).map((k) => [k, k])
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
1030
|
+
function describeSchema(schema) {
|
|
1031
|
+
var _a;
|
|
1032
|
+
const s = schema;
|
|
1033
|
+
if ("_shape" in s) return { kind: "shape", shape: s._shape };
|
|
1034
|
+
if ("item" in s) return { kind: "array", item: s.item };
|
|
1035
|
+
if ("inner" in s) return { kind: "optional", inner: s.inner };
|
|
1036
|
+
if ("fn" in s) return { kind: "lazy", resolved: (_a = s.resolved) != null ? _a : s.fn() };
|
|
1037
|
+
return { kind: "leaf" };
|
|
1038
|
+
}
|
|
1039
|
+
var px = {
|
|
1040
|
+
/** Matches a string. Default: '' or provided value. */
|
|
1041
|
+
string: (defaultVal = "") => new Str(defaultVal),
|
|
1042
|
+
/** Matches a finite number. Default: 0 or provided value. */
|
|
1043
|
+
number: (defaultVal = 0) => new Num(defaultVal),
|
|
1044
|
+
/** Matches a boolean. Default: false or provided value. */
|
|
1045
|
+
boolean: (defaultVal = false) => new Bool(defaultVal),
|
|
1046
|
+
/** Matches one exact primitive value; its default is the value itself. */
|
|
1047
|
+
literal: (value) => new Literal(value),
|
|
1048
|
+
/** Matches one of a fixed set of string/number values. Default: first value. */
|
|
1049
|
+
enum: (values, defaultVal) => new Enum(values, defaultVal),
|
|
1050
|
+
/**
|
|
1051
|
+
* Returns the first schema whose isValid passes.
|
|
1052
|
+
* TypeScript infers the union of all member types automatically.
|
|
1053
|
+
*/
|
|
1054
|
+
union: (schemas, defaultVal) => new Union(schemas, defaultVal),
|
|
1055
|
+
/**
|
|
1056
|
+
* Discriminated union — reads `raw[key]`, finds the member schema whose
|
|
1057
|
+
* literal at `key` matches, then delegates sanitize/isValid to that member.
|
|
1058
|
+
* Each member must be an object schema with a `px.literal(...)` at `key`.
|
|
1059
|
+
* TypeScript infers the union of all member types automatically.
|
|
1060
|
+
*/
|
|
1061
|
+
discriminatedUnion: (key, schemas) => new DiscriminatedUnion(key, schemas),
|
|
1062
|
+
/** Typed object — unknown keys are stripped. Required fields fall back to their default. */
|
|
1063
|
+
object: (shape) => new Obj(shape),
|
|
1064
|
+
/**
|
|
1065
|
+
* Open object — validates known keys; passes unknown keys through as-is,
|
|
1066
|
+
* or validates/sanitizes them against `openSchema` when provided.
|
|
1067
|
+
*/
|
|
1068
|
+
openObject: (shape, openSchema) => new OpenObj(shape, openSchema),
|
|
1069
|
+
/**
|
|
1070
|
+
* Creates a new closed object schema by merging a base schema's shape with additional fields.
|
|
1071
|
+
* The base can be the result of px.object() or px.openObject() — anything with a _shape property.
|
|
1072
|
+
*
|
|
1073
|
+
* @example
|
|
1074
|
+
* const PxSvgNodeSchema = px.extendedObject(PxNodeBase, { width: px.number().optional() });
|
|
1075
|
+
*/
|
|
1076
|
+
extendedObject: (base, extra) => new Obj(__spreadValues(__spreadValues({}, base._shape), extra)),
|
|
1077
|
+
/** Array whose unrecoverable items are filtered out. Default: []. */
|
|
1078
|
+
array: (item) => new Arr(item),
|
|
1079
|
+
/** String-keyed record whose unrecoverable values are dropped. Default: {}. */
|
|
1080
|
+
record: (value) => new Rec(value),
|
|
1081
|
+
/** Passes anything through unchanged — always valid. */
|
|
1082
|
+
any: () => new Any(),
|
|
1083
|
+
/** Fixed-length tuple — validates element count and each position individually. */
|
|
1084
|
+
tuple: (schemas) => new Tuple(schemas),
|
|
1085
|
+
/** Defers schema creation — required for recursive types. Must supply a default value. */
|
|
1086
|
+
lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
|
|
1087
|
+
};
|
|
1088
|
+
|
|
1089
|
+
// src/PxAnimatorTypes.ts
|
|
1090
|
+
var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
|
|
1091
|
+
var PX_ANIM_ATTR_NAME = "_px_animator";
|
|
1092
|
+
var TEXT_ATTR = "text";
|
|
1093
|
+
var TEXT_CONTENT_ATTR = "textContent";
|
|
1094
|
+
var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
|
|
1095
|
+
"type",
|
|
1096
|
+
"children",
|
|
1097
|
+
"animator",
|
|
1098
|
+
"meta",
|
|
1099
|
+
"animate",
|
|
1100
|
+
TEXT_ATTR,
|
|
1101
|
+
TEXT_CONTENT_ATTR
|
|
1102
|
+
]);
|
|
1103
|
+
var PxEasingOrRefSchema = px.union([
|
|
1104
|
+
px.string(),
|
|
1105
|
+
px.tuple([px.number(), px.number(), px.number(), px.number()])
|
|
1106
|
+
]);
|
|
1107
|
+
var PxKeyframeValueSchema = implementsInterface()(px.union([
|
|
1108
|
+
px.string(),
|
|
1109
|
+
// e.g. for colors
|
|
1110
|
+
px.number(),
|
|
1111
|
+
px.array(px.number()),
|
|
1112
|
+
px.lazy(() => PxTransformPartsSchema, {}),
|
|
1113
|
+
px.object({ path: px.string() }),
|
|
1114
|
+
px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] })
|
|
1115
|
+
]));
|
|
1116
|
+
var PxKeyframeSchema = implementsInterface()(px.object({
|
|
1117
|
+
time: px.number().optional(),
|
|
1118
|
+
t: px.number().optional(),
|
|
1119
|
+
value: px.any().optional(),
|
|
1120
|
+
v: px.any().optional(),
|
|
1121
|
+
easing: PxEasingOrRefSchema.optional(),
|
|
1122
|
+
e: PxEasingOrRefSchema.optional(),
|
|
1123
|
+
tangentOut: px.tuple([px.number(), px.number()]).optional(),
|
|
1124
|
+
to: px.tuple([px.number(), px.number()]).optional(),
|
|
1125
|
+
// short alias
|
|
1126
|
+
tangentIn: px.tuple([px.number(), px.number()]).optional(),
|
|
1127
|
+
ti: px.tuple([px.number(), px.number()]).optional(),
|
|
1128
|
+
// short alias
|
|
1129
|
+
selected: px.boolean().optional()
|
|
1130
|
+
// editor-side UI state (Player ignores it)
|
|
1131
|
+
}));
|
|
1132
|
+
var PxLoopSchema = implementsInterface()(px.object({
|
|
1133
|
+
segmentCount: px.number().optional(),
|
|
1134
|
+
before: px.boolean().optional(),
|
|
1135
|
+
alternate: px.boolean().optional()
|
|
1136
|
+
}));
|
|
1137
|
+
var PxPropertyAnimationSchema = implementsInterface()(px.object({
|
|
1138
|
+
keyframes: px.array(PxKeyframeSchema).optional(),
|
|
1139
|
+
kfs: px.array(PxKeyframeSchema).optional(),
|
|
1140
|
+
loop: px.union([PxLoopSchema, px.boolean()]).optional(),
|
|
1141
|
+
autoOrient: px.boolean().optional()
|
|
1142
|
+
}));
|
|
1143
|
+
var PX_TRANSFORM_PART_KEYS = ["translate", "rotate", "scale", "origin"];
|
|
1144
|
+
var PxTransformPartsSchema = implementsInterface()(px.object({
|
|
1145
|
+
translate: px.tuple([px.number(), px.number()]).optional(),
|
|
1146
|
+
rotate: px.number().optional(),
|
|
1147
|
+
scale: px.tuple([px.number(), px.number()]).optional(),
|
|
1148
|
+
origin: px.tuple([px.number(), px.number()]).optional()
|
|
1149
|
+
}));
|
|
1150
|
+
var PxTransformValueSchema = px.union([
|
|
1151
|
+
px.string(),
|
|
1152
|
+
px.object({ value: PxTransformPartsSchema }),
|
|
1153
|
+
PxPropertyAnimationSchema
|
|
1154
|
+
]);
|
|
1155
|
+
var PxAnimationDefinitionSchema = implementsInterface()(
|
|
1156
|
+
px.record(PxPropertyAnimationSchema)
|
|
1157
|
+
);
|
|
1158
|
+
var PxElementAnimationSchema = implementsInterface()(px.union([
|
|
1159
|
+
px.string(),
|
|
1160
|
+
px.array(px.union([px.string(), PxAnimationDefinitionSchema])),
|
|
1161
|
+
PxAnimationDefinitionSchema
|
|
1162
|
+
]));
|
|
1163
|
+
var PxTriggerSchema = implementsInterface()(px.object({
|
|
1164
|
+
startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
|
|
1165
|
+
outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
|
|
1166
|
+
scrollIntoViewThreshold: px.number().optional()
|
|
1167
|
+
}));
|
|
1168
|
+
var PxDefsSchema = implementsInterface()(px.object({
|
|
1169
|
+
easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
|
|
1170
|
+
animations: px.record(PxAnimationDefinitionSchema).optional(),
|
|
1171
|
+
styles: px.record(px.any()).optional()
|
|
1172
|
+
}));
|
|
1173
|
+
var PxAnimatorConfigSchema = implementsInterface()(px.object({
|
|
1174
|
+
mode: px.enum(["auto", "webapi", "frames"]).optional(),
|
|
1175
|
+
duration: px.number().optional(),
|
|
1176
|
+
delay: px.number().optional(),
|
|
1177
|
+
iterations: px.union([px.number(), px.literal("infinite")]).optional(),
|
|
1178
|
+
fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
|
|
1179
|
+
direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional(),
|
|
1180
|
+
frameRate: px.number().optional(),
|
|
1181
|
+
trigger: PxTriggerSchema.optional(),
|
|
1182
|
+
definitions: PxDefsSchema.optional(),
|
|
1183
|
+
animate: px.record(PxElementAnimationSchema).optional(),
|
|
1184
|
+
debug: px.boolean().optional(),
|
|
1185
|
+
debugInstName: px.string().optional()
|
|
1186
|
+
}));
|
|
1187
|
+
var PxBindingSchema = implementsInterface()(px.object({
|
|
1188
|
+
id: px.string(),
|
|
1189
|
+
animate: PxElementAnimationSchema
|
|
1190
|
+
}));
|
|
1191
|
+
var PxAttrValueSchema = px.union([
|
|
1192
|
+
px.string(),
|
|
1193
|
+
px.number(),
|
|
1194
|
+
px.object({ value: px.any() }),
|
|
1195
|
+
PxPropertyAnimationSchema
|
|
1196
|
+
]);
|
|
1197
|
+
var PxAnimatableNumberSchema = px.union([
|
|
1198
|
+
px.number(),
|
|
1199
|
+
px.object({ value: px.number() }),
|
|
1200
|
+
px.object({
|
|
1201
|
+
keyframes: px.array(PxKeyframeSchema),
|
|
1202
|
+
autoOrient: px.boolean().optional()
|
|
1203
|
+
})
|
|
1204
|
+
]);
|
|
1205
|
+
var PxAnimatableVec2Schema = px.union([
|
|
1206
|
+
px.tuple([px.number(), px.number()]),
|
|
1207
|
+
px.object({ value: px.tuple([px.number(), px.number()]) }),
|
|
1208
|
+
px.object({
|
|
1209
|
+
keyframes: px.array(PxKeyframeSchema),
|
|
1210
|
+
autoOrient: px.boolean().optional()
|
|
1211
|
+
})
|
|
1212
|
+
]);
|
|
1213
|
+
var PxTransformationEffectSchema = px.object({
|
|
1214
|
+
translate: PxAnimatableVec2Schema.optional(),
|
|
1215
|
+
rotate: PxAnimatableNumberSchema.optional(),
|
|
1216
|
+
scale: PxAnimatableVec2Schema.optional(),
|
|
1217
|
+
skew: PxAnimatableVec2Schema.optional(),
|
|
1218
|
+
origin: PxAnimatableVec2Schema.optional()
|
|
1219
|
+
});
|
|
1220
|
+
var PxRepeaterEffectSchema = px.object({
|
|
1221
|
+
copies: px.number().optional(),
|
|
1222
|
+
translate: px.tuple([px.number(), px.number()]).optional(),
|
|
1223
|
+
rotate: px.number().optional(),
|
|
1224
|
+
scale: px.tuple([px.number(), px.number()]).optional(),
|
|
1225
|
+
// per-copy scale, PERCENT (85 → 0.85)
|
|
1226
|
+
origin: px.tuple([px.number(), px.number()]).optional()
|
|
1227
|
+
});
|
|
1228
|
+
var PxMaskedByEffectSchema = px.object({
|
|
1229
|
+
href: px.string().optional(),
|
|
1230
|
+
maskType: px.string().optional(),
|
|
1231
|
+
maskUnits: px.string().optional(),
|
|
1232
|
+
maskContentUnits: px.string().optional()
|
|
1233
|
+
});
|
|
1234
|
+
var PxTrimPathEffectSchema = px.any();
|
|
1235
|
+
var PxRetimeEffectSchema = px.object({
|
|
1236
|
+
baseId: px.string().optional(),
|
|
1237
|
+
start: px.number().optional(),
|
|
1238
|
+
stretch: px.number().optional(),
|
|
1239
|
+
timeCrop: px.tuple([px.number(), px.number()]).optional()
|
|
1240
|
+
});
|
|
1241
|
+
var PxRefEffectSchema = px.object({
|
|
1242
|
+
baseId: px.string().optional(),
|
|
1243
|
+
type: px.string().optional()
|
|
1244
|
+
});
|
|
1245
|
+
var PxEffectsSchema = px.object({
|
|
1246
|
+
transformation: PxTransformationEffectSchema.optional(),
|
|
1247
|
+
repeater: PxRepeaterEffectSchema.optional(),
|
|
1248
|
+
maskedBy: PxMaskedByEffectSchema.optional(),
|
|
1249
|
+
trimPath: PxTrimPathEffectSchema.optional(),
|
|
1250
|
+
retime: PxRetimeEffectSchema.optional(),
|
|
1251
|
+
isCombinedShape: px.boolean().optional(),
|
|
1252
|
+
ref: PxRefEffectSchema.optional()
|
|
1253
|
+
});
|
|
1254
|
+
function validateNodeEffects(root, opts) {
|
|
1255
|
+
const warnings = [];
|
|
1256
|
+
const walk = (node, path) => {
|
|
1257
|
+
if (node && node.effects) {
|
|
1258
|
+
const ctx = { errors: [], warnings: [], strict: !!(opts == null ? void 0 : opts.strict) };
|
|
1259
|
+
const ok = PxEffectsSchema.isValid(node.effects, ctx, [path + ".effects"]);
|
|
1260
|
+
if (!ok) {
|
|
1261
|
+
for (const err of ctx.errors) warnings.push(err);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
if (node && Array.isArray(node.children)) {
|
|
1265
|
+
node.children.forEach((c, i) => walk(c, path + ".children[" + i + "]"));
|
|
1266
|
+
}
|
|
1267
|
+
};
|
|
1268
|
+
walk(root, "root");
|
|
1269
|
+
return warnings;
|
|
1270
|
+
}
|
|
1271
|
+
var PxNodeBase = px.openObject({
|
|
1272
|
+
type: px.string(),
|
|
1273
|
+
id: px.string().optional(),
|
|
1274
|
+
meta: px.any().optional(),
|
|
1275
|
+
// Player-effects bucket emitted by the Editor's lightweight design format.
|
|
1276
|
+
// Consumed and removed by `applyPlayerEffects` before any other normalisation
|
|
1277
|
+
// (see `createAnimatorImpl`), so downstream code never sees it.
|
|
1278
|
+
effects: PxEffectsSchema.optional(),
|
|
1279
|
+
animate: PxAnimationDefinitionSchema.optional(),
|
|
1280
|
+
style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
|
|
1281
|
+
}, PxAttrValueSchema);
|
|
1282
|
+
var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBase._shape), {
|
|
1283
|
+
children: px.lazy(() => px.array(PxNodeSchema), []).optional()
|
|
1284
|
+
}), PxAttrValueSchema);
|
|
1285
|
+
var PxSvgNodeExtra = px.object({
|
|
1286
|
+
width: px.number().optional(),
|
|
1287
|
+
height: px.number().optional(),
|
|
1288
|
+
viewBox: px.string().optional(),
|
|
1289
|
+
animator: PxAnimatorConfigSchema.optional()
|
|
1290
|
+
});
|
|
1291
|
+
var PxAnimatedSvgDocumentSchema = px.openObject(__spreadProps(__spreadValues(__spreadValues({}, PxNodeBase._shape), PxSvgNodeExtra._shape), {
|
|
1292
|
+
type: px.literal("svg"),
|
|
1293
|
+
// override string → literal to require 'svg'
|
|
1294
|
+
children: px.array(PxNodeSchema).optional()
|
|
1295
|
+
}), PxAttrValueSchema);
|
|
1296
|
+
var PxBezierPathSchema = implementsInterface()(px.object({
|
|
1297
|
+
v: px.array(px.array(px.number())),
|
|
1298
|
+
i: px.array(px.array(px.number())).optional(),
|
|
1299
|
+
o: px.array(px.array(px.number())).optional(),
|
|
1300
|
+
c: px.boolean().optional()
|
|
1301
|
+
}));
|
|
1302
|
+
function isPxElementFileFormat(fileJson) {
|
|
1303
|
+
if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
|
|
1304
|
+
return false;
|
|
1305
|
+
}
|
|
1306
|
+
return fileJson["type"] === "svg" || fileJson["tagName"] === "svg";
|
|
1307
|
+
}
|
|
1308
|
+
function isPxElementFileFormatDeep(fileJson) {
|
|
1309
|
+
const valid = PxAnimatedSvgDocumentSchema.isValid(fileJson);
|
|
1310
|
+
return { valid, errors: valid ? [] : ["Document failed schema validation"] };
|
|
1311
|
+
}
|
|
1312
|
+
function getAnimatorConfig(doc) {
|
|
1313
|
+
var _a, _b;
|
|
1314
|
+
return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator) || (doc == null ? void 0 : doc.animation) || ((_b = doc == null ? void 0 : doc.meta) == null ? void 0 : _b.animation);
|
|
1315
|
+
}
|
|
1316
|
+
function getDefs(doc) {
|
|
1317
|
+
var _a;
|
|
1318
|
+
if (!doc) return void 0;
|
|
1319
|
+
return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
|
|
1320
|
+
}
|
|
1321
|
+
function getBindings(doc) {
|
|
1322
|
+
var _a;
|
|
1323
|
+
if (!doc) return void 0;
|
|
1324
|
+
const animate = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animate;
|
|
1325
|
+
if (!animate) return void 0;
|
|
1326
|
+
return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));
|
|
1327
|
+
}
|
|
1328
|
+
function getChildren(doc) {
|
|
1329
|
+
return doc == null ? void 0 : doc.children;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
33
1332
|
// src/PxAnimatorUtil.ts
|
|
34
1333
|
function bezierToSvgPath(path) {
|
|
35
1334
|
var _a, _b, _c, _d;
|
|
@@ -119,50 +1418,104 @@ function remap(value, inMin, inMax, outMin, outMax) {
|
|
|
119
1418
|
const t = (value - inMin) / (inMax - inMin);
|
|
120
1419
|
return outMin + t * (outMax - outMin);
|
|
121
1420
|
}
|
|
122
|
-
function
|
|
123
|
-
|
|
1421
|
+
function solveCubicBezierX(p1x, p2x, x) {
|
|
1422
|
+
if (x <= 0) return 0;
|
|
1423
|
+
if (x >= 1) return 1;
|
|
124
1424
|
const cx = 3 * p1x;
|
|
125
1425
|
const bx = 3 * (p2x - p1x) - cx;
|
|
126
1426
|
const ax = 1 - cx - bx;
|
|
1427
|
+
function sampleX(t) {
|
|
1428
|
+
return ((ax * t + bx) * t + cx) * t;
|
|
1429
|
+
}
|
|
1430
|
+
function sampleDX(t) {
|
|
1431
|
+
return (3 * ax * t + 2 * bx) * t + cx;
|
|
1432
|
+
}
|
|
1433
|
+
let t2 = x;
|
|
1434
|
+
let t0 = 0;
|
|
1435
|
+
let t1 = 1;
|
|
1436
|
+
for (let i = 0; i < 8; i++) {
|
|
1437
|
+
const x2 = sampleX(t2) - x;
|
|
1438
|
+
if (Math.abs(x2) < 1e-6) return t2;
|
|
1439
|
+
const d2 = sampleDX(t2);
|
|
1440
|
+
if (Math.abs(d2) < 1e-6) break;
|
|
1441
|
+
t2 -= x2 / d2;
|
|
1442
|
+
}
|
|
1443
|
+
t2 = x;
|
|
1444
|
+
while (t0 < t1) {
|
|
1445
|
+
const x2 = sampleX(t2);
|
|
1446
|
+
if (Math.abs(x2 - x) < 1e-6) return t2;
|
|
1447
|
+
if (x > x2) t0 = t2;
|
|
1448
|
+
else t1 = t2;
|
|
1449
|
+
t2 = (t1 + t0) / 2;
|
|
1450
|
+
}
|
|
1451
|
+
return t2;
|
|
1452
|
+
}
|
|
1453
|
+
function cubicBezier(easing) {
|
|
1454
|
+
const [p1x, p1y, p2x, p2y] = easing;
|
|
127
1455
|
const cy = 3 * p1y;
|
|
128
1456
|
const by = 3 * (p2y - p1y) - cy;
|
|
129
1457
|
const ay = 1 - cy - by;
|
|
130
|
-
function sampleCurveX(t) {
|
|
131
|
-
return ((ax * t + bx) * t + cx) * t;
|
|
132
|
-
}
|
|
133
1458
|
function sampleCurveY(t) {
|
|
134
1459
|
return ((ay * t + by) * t + cy) * t;
|
|
135
1460
|
}
|
|
136
|
-
function sampleCurveDerivativeX(t) {
|
|
137
|
-
return (3 * ax * t + 2 * bx) * t + cx;
|
|
138
|
-
}
|
|
139
|
-
function solveCurveX(x) {
|
|
140
|
-
if (x <= 0) return 0;
|
|
141
|
-
if (x >= 1) return 1;
|
|
142
|
-
let t2 = x;
|
|
143
|
-
let t0 = 0;
|
|
144
|
-
let t1 = 1;
|
|
145
|
-
for (let i = 0; i < 8; i++) {
|
|
146
|
-
const x2 = sampleCurveX(t2) - x;
|
|
147
|
-
if (Math.abs(x2) < 1e-6) return t2;
|
|
148
|
-
const d2 = sampleCurveDerivativeX(t2);
|
|
149
|
-
if (Math.abs(d2) < 1e-6) break;
|
|
150
|
-
t2 -= x2 / d2;
|
|
151
|
-
}
|
|
152
|
-
t2 = x;
|
|
153
|
-
while (t0 < t1) {
|
|
154
|
-
const x2 = sampleCurveX(t2);
|
|
155
|
-
if (Math.abs(x2 - x) < 1e-6) return t2;
|
|
156
|
-
if (x > x2) t0 = t2;
|
|
157
|
-
else t1 = t2;
|
|
158
|
-
t2 = (t1 + t0) / 2;
|
|
159
|
-
}
|
|
160
|
-
return t2;
|
|
161
|
-
}
|
|
162
1461
|
return function(x) {
|
|
163
|
-
return sampleCurveY(
|
|
1462
|
+
return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
|
|
1463
|
+
};
|
|
1464
|
+
}
|
|
1465
|
+
function lerp2(a, b, t) {
|
|
1466
|
+
return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
|
|
1467
|
+
}
|
|
1468
|
+
function subdivideCubicBezier(p0, p1, p2, p3, t) {
|
|
1469
|
+
const q0 = lerp2(p0, p1, t);
|
|
1470
|
+
const q1 = lerp2(p1, p2, t);
|
|
1471
|
+
const q2 = lerp2(p2, p3, t);
|
|
1472
|
+
const r0 = lerp2(q0, q1, t);
|
|
1473
|
+
const r1 = lerp2(q1, q2, t);
|
|
1474
|
+
const s = lerp2(r0, r1, t);
|
|
1475
|
+
return {
|
|
1476
|
+
left: [p0, q0, r0, s],
|
|
1477
|
+
right: [s, r1, q2, p3]
|
|
164
1478
|
};
|
|
165
1479
|
}
|
|
1480
|
+
function splitEasing(easing, xFraction) {
|
|
1481
|
+
if (!easing) return { left: void 0, right: void 0 };
|
|
1482
|
+
if (xFraction <= 0) return { left: void 0, right: easing };
|
|
1483
|
+
if (xFraction >= 1) return { left: easing, right: void 0 };
|
|
1484
|
+
const [x1, y1, x2, y2] = easing;
|
|
1485
|
+
const t = solveCubicBezierX(x1, x2, xFraction);
|
|
1486
|
+
const p0 = [0, 0];
|
|
1487
|
+
const p1 = [x1, y1];
|
|
1488
|
+
const p2 = [x2, y2];
|
|
1489
|
+
const p3 = [1, 1];
|
|
1490
|
+
const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
|
|
1491
|
+
const sx = left[3][0];
|
|
1492
|
+
const sy = left[3][1];
|
|
1493
|
+
let leftEasing;
|
|
1494
|
+
if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
|
|
1495
|
+
leftEasing = [
|
|
1496
|
+
left[1][0] / sx,
|
|
1497
|
+
left[1][1] / sy,
|
|
1498
|
+
left[2][0] / sx,
|
|
1499
|
+
left[2][1] / sy
|
|
1500
|
+
];
|
|
1501
|
+
}
|
|
1502
|
+
let rightEasing;
|
|
1503
|
+
const rx = 1 - sx;
|
|
1504
|
+
const ry = 1 - sy;
|
|
1505
|
+
if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
|
|
1506
|
+
rightEasing = [
|
|
1507
|
+
(right[1][0] - sx) / rx,
|
|
1508
|
+
(right[1][1] - sy) / ry,
|
|
1509
|
+
(right[2][0] - sx) / rx,
|
|
1510
|
+
(right[2][1] - sy) / ry
|
|
1511
|
+
];
|
|
1512
|
+
}
|
|
1513
|
+
return { left: leftEasing, right: rightEasing };
|
|
1514
|
+
}
|
|
1515
|
+
function reverseEasing(easing) {
|
|
1516
|
+
if (!easing) return void 0;
|
|
1517
|
+
return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
|
|
1518
|
+
}
|
|
166
1519
|
function toRGBA(color) {
|
|
167
1520
|
const r = Math.round(color[0] * 255);
|
|
168
1521
|
const g = Math.round(color[1] * 255);
|
|
@@ -209,6 +1562,24 @@ function parseColor(s) {
|
|
|
209
1562
|
var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
|
|
210
1563
|
var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
|
|
211
1564
|
var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
1565
|
+
function composeTransformParts(parts, opts) {
|
|
1566
|
+
var _a;
|
|
1567
|
+
if (!parts) return "";
|
|
1568
|
+
const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
|
|
1569
|
+
const segs = [];
|
|
1570
|
+
const t = parts.translate;
|
|
1571
|
+
const o = parts.origin;
|
|
1572
|
+
const r = parts.rotate;
|
|
1573
|
+
const s = parts.scale;
|
|
1574
|
+
const tu = withUnits ? "px" : "";
|
|
1575
|
+
const ru = withUnits ? "deg" : "";
|
|
1576
|
+
if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
|
|
1577
|
+
if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
|
|
1578
|
+
if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
|
|
1579
|
+
if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
|
|
1580
|
+
if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
|
|
1581
|
+
return segs.join("");
|
|
1582
|
+
}
|
|
212
1583
|
var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
213
1584
|
var DEFAULT_DURATION_MS = 1e3;
|
|
214
1585
|
function kebabToCamelCaseWord(kebab) {
|
|
@@ -268,14 +1639,260 @@ function camelCaseToKebabWordIfNeeded(camel) {
|
|
|
268
1639
|
function clamp(value, min, max) {
|
|
269
1640
|
return Math.max(min, Math.min(value, max));
|
|
270
1641
|
}
|
|
1642
|
+
function bezier2D_pointAt(P0, P1, P2, P3, t) {
|
|
1643
|
+
if (t <= 0) return [P0[0], P0[1]];
|
|
1644
|
+
if (t >= 1) return [P3[0], P3[1]];
|
|
1645
|
+
const u = 1 - t;
|
|
1646
|
+
const u2 = u * u;
|
|
1647
|
+
const u3 = u2 * u;
|
|
1648
|
+
const t2 = t * t;
|
|
1649
|
+
const t3 = t2 * t;
|
|
1650
|
+
const w0 = u3;
|
|
1651
|
+
const w1 = 3 * t * u2;
|
|
1652
|
+
const w2 = 3 * t2 * u;
|
|
1653
|
+
const w3 = t3;
|
|
1654
|
+
return [
|
|
1655
|
+
w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
|
|
1656
|
+
w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
|
|
1657
|
+
];
|
|
1658
|
+
}
|
|
1659
|
+
var BEZIER_T_NUDGE = 1e-4;
|
|
1660
|
+
function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
|
|
1661
|
+
const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
|
|
1662
|
+
if (result[0] === 0 && result[1] === 0) {
|
|
1663
|
+
const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
|
|
1664
|
+
return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
|
|
1665
|
+
}
|
|
1666
|
+
return result;
|
|
1667
|
+
}
|
|
1668
|
+
function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
|
|
1669
|
+
const u = 1 - t;
|
|
1670
|
+
const a = 3 * u * u;
|
|
1671
|
+
const b = 6 * t * u;
|
|
1672
|
+
const c = 3 * t * t;
|
|
1673
|
+
return [
|
|
1674
|
+
a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
|
|
1675
|
+
a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
|
|
1676
|
+
];
|
|
1677
|
+
}
|
|
1678
|
+
function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
|
|
1679
|
+
const n = steps + 1;
|
|
1680
|
+
const ts = new Float64Array(n);
|
|
1681
|
+
const ds = new Float64Array(n);
|
|
1682
|
+
let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
|
|
1683
|
+
ts[0] = 0;
|
|
1684
|
+
ds[0] = 0;
|
|
1685
|
+
let cum = 0;
|
|
1686
|
+
for (let i = 1; i < n; i++) {
|
|
1687
|
+
const t = i / steps;
|
|
1688
|
+
const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
|
|
1689
|
+
const dx = cur[0] - prev[0];
|
|
1690
|
+
const dy = cur[1] - prev[1];
|
|
1691
|
+
cum += Math.sqrt(dx * dx + dy * dy);
|
|
1692
|
+
ts[i] = t;
|
|
1693
|
+
ds[i] = cum;
|
|
1694
|
+
prev = cur;
|
|
1695
|
+
}
|
|
1696
|
+
return { ts, ds };
|
|
1697
|
+
}
|
|
1698
|
+
function bezier2D_tForDistance(lut, distance) {
|
|
1699
|
+
const { ts, ds } = lut;
|
|
1700
|
+
const last = ds.length - 1;
|
|
1701
|
+
if (distance <= 0) return ts[0];
|
|
1702
|
+
if (distance >= ds[last]) return ts[last];
|
|
1703
|
+
let lo = 1;
|
|
1704
|
+
let hi = last;
|
|
1705
|
+
while (lo < hi) {
|
|
1706
|
+
const mid = lo + hi >>> 1;
|
|
1707
|
+
if (ds[mid] < distance) lo = mid + 1;
|
|
1708
|
+
else hi = mid;
|
|
1709
|
+
}
|
|
1710
|
+
const dPrev = ds[hi - 1];
|
|
1711
|
+
const dCur = ds[hi];
|
|
1712
|
+
const span = dCur - dPrev;
|
|
1713
|
+
const frac = span > 0 ? (distance - dPrev) / span : 0;
|
|
1714
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
1715
|
+
}
|
|
271
1716
|
|
|
272
1717
|
// src/PxAnimatorDOM.ts
|
|
273
1718
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
274
|
-
var
|
|
275
|
-
|
|
1719
|
+
var ALLOWED_SVG_TAGS_LOWER_CASE = new Set([
|
|
1720
|
+
"svg",
|
|
1721
|
+
"g",
|
|
1722
|
+
"path",
|
|
1723
|
+
"circle",
|
|
1724
|
+
"ellipse",
|
|
1725
|
+
"rect",
|
|
1726
|
+
"line",
|
|
1727
|
+
"polyline",
|
|
1728
|
+
"polygon",
|
|
1729
|
+
"text",
|
|
1730
|
+
"tspan",
|
|
1731
|
+
"textPath",
|
|
1732
|
+
"defs",
|
|
1733
|
+
"clipPath",
|
|
1734
|
+
"mask",
|
|
1735
|
+
"pattern",
|
|
1736
|
+
"linearGradient",
|
|
1737
|
+
"radialGradient",
|
|
1738
|
+
"stop",
|
|
1739
|
+
"use",
|
|
1740
|
+
"symbol",
|
|
1741
|
+
"marker",
|
|
1742
|
+
"filter",
|
|
1743
|
+
"feGaussianBlur",
|
|
1744
|
+
"feOffset",
|
|
1745
|
+
"feBlend",
|
|
1746
|
+
"feColorMatrix",
|
|
1747
|
+
"feMerge",
|
|
1748
|
+
"feMergeNode"
|
|
1749
|
+
].map((tagName) => tagName.toLowerCase()));
|
|
1750
|
+
var ALLOWED_RESOURCE_ATTRIBUTES = [
|
|
1751
|
+
"href",
|
|
1752
|
+
// <use>
|
|
1753
|
+
"src",
|
|
1754
|
+
// <image>
|
|
1755
|
+
"filter",
|
|
1756
|
+
// url(#filterId)
|
|
1757
|
+
"clipPath",
|
|
1758
|
+
// clip-path="url(#clipPathId)"
|
|
1759
|
+
"mask",
|
|
1760
|
+
// url(#maskId)
|
|
1761
|
+
"markerStart",
|
|
1762
|
+
// marker-start="url(#markerId)"
|
|
1763
|
+
"markerMid",
|
|
1764
|
+
// marker-mid="url(#markerId)"
|
|
1765
|
+
"markerEnd"
|
|
1766
|
+
// marker-end="url(#markerId)"
|
|
1767
|
+
// 'fill', // url(#gradientId) or url(#patternId)
|
|
1768
|
+
// 'stroke', // url(#gradientId) or url(#patternId)
|
|
1769
|
+
// Don't allow 'cursor', can use external SVG, // url(cursor.svg)
|
|
1770
|
+
];
|
|
1771
|
+
var ALLOWED_RESOURCE_ATTRIBUTES_SET = new Set(ALLOWED_RESOURCE_ATTRIBUTES);
|
|
1772
|
+
var ALLOWED_ATTRIBUTES = [
|
|
1773
|
+
"href",
|
|
1774
|
+
"src",
|
|
1775
|
+
// Presentation
|
|
1776
|
+
"fill",
|
|
1777
|
+
"fillOpacity",
|
|
1778
|
+
"fillRule",
|
|
1779
|
+
"stroke",
|
|
1780
|
+
"strokeWidth",
|
|
1781
|
+
"strokeOpacity",
|
|
1782
|
+
"strokeLinecap",
|
|
1783
|
+
"strokeLinejoin",
|
|
1784
|
+
"strokeMiterlimit",
|
|
1785
|
+
"strokeDasharray",
|
|
1786
|
+
"strokeDashoffset",
|
|
1787
|
+
"opacity",
|
|
1788
|
+
"transform",
|
|
1789
|
+
// Geometry
|
|
1790
|
+
"x",
|
|
1791
|
+
"y",
|
|
1792
|
+
"cx",
|
|
1793
|
+
"cy",
|
|
1794
|
+
"r",
|
|
1795
|
+
"rx",
|
|
1796
|
+
"ry",
|
|
1797
|
+
"width",
|
|
1798
|
+
"height",
|
|
1799
|
+
"d",
|
|
1800
|
+
"x1",
|
|
1801
|
+
"y1",
|
|
1802
|
+
"x2",
|
|
1803
|
+
"y2",
|
|
1804
|
+
"points",
|
|
1805
|
+
"dx",
|
|
1806
|
+
"dy",
|
|
1807
|
+
// Font
|
|
1808
|
+
"fontSize",
|
|
1809
|
+
"fontFamily",
|
|
1810
|
+
"fontWeight",
|
|
1811
|
+
"fontStyle",
|
|
1812
|
+
// Text
|
|
1813
|
+
"textAnchor",
|
|
1814
|
+
"letterSpacing",
|
|
1815
|
+
"wordSpacing",
|
|
1816
|
+
"space",
|
|
1817
|
+
"xml:space",
|
|
1818
|
+
"textDecoration",
|
|
1819
|
+
"textTransform",
|
|
1820
|
+
"whiteSpace",
|
|
1821
|
+
"white-space",
|
|
1822
|
+
"dominantBaseline",
|
|
1823
|
+
"alignmentBaseline",
|
|
1824
|
+
"rotate",
|
|
1825
|
+
// per-glyph rotation array, currently not supported
|
|
1826
|
+
// Structure
|
|
1827
|
+
"id",
|
|
1828
|
+
"class",
|
|
1829
|
+
"viewBox",
|
|
1830
|
+
"preserveAspectRatio",
|
|
1831
|
+
// Gradient/Pattern
|
|
1832
|
+
"offset",
|
|
1833
|
+
"stopColor",
|
|
1834
|
+
"stopOpacity",
|
|
1835
|
+
"gradientTransform",
|
|
1836
|
+
// Clippath/Mask
|
|
1837
|
+
"clipPath",
|
|
1838
|
+
"mask",
|
|
1839
|
+
// Motion path
|
|
1840
|
+
"offsetPath",
|
|
1841
|
+
"offsetDistance",
|
|
1842
|
+
"offsetRotate",
|
|
1843
|
+
"offsetAnchor",
|
|
1844
|
+
"offsetPosition",
|
|
1845
|
+
// Text path
|
|
1846
|
+
"startOffset",
|
|
1847
|
+
"textLength",
|
|
1848
|
+
"lengthAdjust",
|
|
1849
|
+
// Filter
|
|
1850
|
+
"filter",
|
|
1851
|
+
"stdDeviation",
|
|
1852
|
+
"in",
|
|
1853
|
+
"in2",
|
|
1854
|
+
"result",
|
|
1855
|
+
"mode",
|
|
1856
|
+
...ALLOWED_RESOURCE_ATTRIBUTES
|
|
1857
|
+
];
|
|
1858
|
+
var ALLOWED_ATTRIBUTES_LOW_SET = new Set(ALLOWED_ATTRIBUTES.map((str) => str.toLowerCase()));
|
|
1859
|
+
function sanitiseAttributeValue(name, value) {
|
|
1860
|
+
const nameLower = name.toLowerCase();
|
|
1861
|
+
if (!ALLOWED_ATTRIBUTES_LOW_SET.has(nameLower)) {
|
|
1862
|
+
console.warn("Attribute not in whitelist: ", nameLower);
|
|
1863
|
+
return void 0;
|
|
1864
|
+
}
|
|
1865
|
+
if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopColor") {
|
|
1866
|
+
const str = String(value);
|
|
1867
|
+
if (str.includes("url(") && !/^url\(#[^)]+\)$/.test(str)) {
|
|
1868
|
+
console.warn('Attribute "' + nameLower + '" blocked: url() references must be internal url(#id), got:', value);
|
|
1869
|
+
return void 0;
|
|
1870
|
+
}
|
|
1871
|
+
return value;
|
|
1872
|
+
}
|
|
1873
|
+
if (ALLOWED_RESOURCE_ATTRIBUTES_SET.has(nameLower)) {
|
|
1874
|
+
const str = String(value);
|
|
1875
|
+
if (str.startsWith("#")) {
|
|
1876
|
+
return value;
|
|
1877
|
+
}
|
|
1878
|
+
if (/^url\(#[^)]+\)$/.test(str)) {
|
|
1879
|
+
return value;
|
|
1880
|
+
}
|
|
1881
|
+
return void 0;
|
|
1882
|
+
}
|
|
1883
|
+
return value;
|
|
1884
|
+
}
|
|
1885
|
+
function createElement(tagName, normalisedProps, style, children, textContent) {
|
|
1886
|
+
if (!ALLOWED_SVG_TAGS_LOWER_CASE.has(tagName.toLowerCase())) {
|
|
1887
|
+
console.warn("Attribute not in whitelist: ", tagName);
|
|
1888
|
+
return null;
|
|
1889
|
+
}
|
|
276
1890
|
const element = document.createElementNS(SVG_NS, tagName);
|
|
277
|
-
for (const propName in
|
|
278
|
-
element.setAttribute(
|
|
1891
|
+
for (const propName in normalisedProps) {
|
|
1892
|
+
element.setAttribute(
|
|
1893
|
+
camelCaseToKebabWordIfNeeded(propName),
|
|
1894
|
+
sanitiseAttributeValue(propName, normalisedProps[propName])
|
|
1895
|
+
);
|
|
279
1896
|
}
|
|
280
1897
|
if (style) {
|
|
281
1898
|
for (const styleProp in style) {
|
|
@@ -287,6 +1904,7 @@ function createElement(tagName, props, style, children) {
|
|
|
287
1904
|
element.appendChild(child);
|
|
288
1905
|
}
|
|
289
1906
|
}
|
|
1907
|
+
if (textContent) element.textContent = textContent;
|
|
290
1908
|
return element;
|
|
291
1909
|
}
|
|
292
1910
|
function resolveStyle(style, defs) {
|
|
@@ -301,9 +1919,12 @@ function getNormalizedProps(props) {
|
|
|
301
1919
|
const propsCopy = {};
|
|
302
1920
|
for (const key of Object.keys(props)) {
|
|
303
1921
|
if (INTERNAL_ATTRS.has(key)) continue;
|
|
1922
|
+
if (key === "style") continue;
|
|
304
1923
|
let value = props[key];
|
|
305
1924
|
if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
|
|
306
1925
|
propsCopy[key] = toRGBA(value);
|
|
1926
|
+
} else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
|
|
1927
|
+
propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
|
|
307
1928
|
} else if (TRANSFORM_FN_NAMES.has(key)) {
|
|
308
1929
|
if (Array.isArray(value)) {
|
|
309
1930
|
if (key === "translate") value = value.map((v) => v + "px");
|
|
@@ -319,8 +1940,8 @@ function getNormalizedProps(props) {
|
|
|
319
1940
|
}
|
|
320
1941
|
function renderNode(node, defs) {
|
|
321
1942
|
if (!node) return null;
|
|
322
|
-
const _a = node, { type, children,
|
|
323
|
-
const nodeDefs = node
|
|
1943
|
+
const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
|
|
1944
|
+
const nodeDefs = getDefs(node) || defs;
|
|
324
1945
|
const resolvedStyle = resolveStyle(style, nodeDefs);
|
|
325
1946
|
let childElements;
|
|
326
1947
|
if (children) {
|
|
@@ -336,7 +1957,8 @@ function renderNode(node, defs) {
|
|
|
336
1957
|
type || "g",
|
|
337
1958
|
getNormalizedProps(props),
|
|
338
1959
|
resolvedStyle,
|
|
339
|
-
childElements
|
|
1960
|
+
childElements,
|
|
1961
|
+
props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
|
|
340
1962
|
);
|
|
341
1963
|
}
|
|
342
1964
|
|
|
@@ -417,284 +2039,45 @@ function setupAnimationTriggers(api, config) {
|
|
|
417
2039
|
return api;
|
|
418
2040
|
}
|
|
419
2041
|
|
|
420
|
-
// src/
|
|
421
|
-
|
|
422
|
-
var
|
|
423
|
-
|
|
424
|
-
if (!
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
}
|
|
429
|
-
function isObject(v) {
|
|
430
|
-
return v && typeof v === "object" && !Array.isArray(v);
|
|
431
|
-
}
|
|
432
|
-
function validateFillMode(v, path, errors) {
|
|
433
|
-
if (v === "forwards" || v === "backwards" || v === "both" || v === "none") return true;
|
|
434
|
-
errors.push(path + ': invalid FillMode "' + v + `", expected 'forwards'|'backwards'|'both'|'none'`);
|
|
435
|
-
return false;
|
|
436
|
-
}
|
|
437
|
-
function validatePlaybackDirection(v, path, errors) {
|
|
438
|
-
if (v === "normal" || v === "reverse" || v === "alternate" || v === "alternate-reverse") return true;
|
|
439
|
-
errors.push(path + ': invalid PlaybackDirection "' + v + `", expected 'normal'|'reverse'|'alternate'|'alternate-reverse'`);
|
|
440
|
-
return false;
|
|
441
|
-
}
|
|
442
|
-
function validatePxEasingOrRef(v, path, errors) {
|
|
443
|
-
if (typeof v === "string") return true;
|
|
444
|
-
if (Array.isArray(v) && v.length === 4 && v.every((n) => typeof n === "number")) return true;
|
|
445
|
-
errors.push(path + ": invalid easing, expected string or [number, number, number, number]");
|
|
446
|
-
return false;
|
|
447
|
-
}
|
|
448
|
-
function validatePxKeyframe(v, path, errors) {
|
|
449
|
-
if (!isObject(v)) {
|
|
450
|
-
errors.push(path + ": expected object");
|
|
451
|
-
return false;
|
|
452
|
-
}
|
|
453
|
-
let valid = true;
|
|
454
|
-
if (v.time !== void 0 && typeof v.time !== "number") {
|
|
455
|
-
errors.push(path + ".time: expected number, got " + typeof v.time);
|
|
456
|
-
valid = false;
|
|
457
|
-
}
|
|
458
|
-
if (v.t !== void 0 && typeof v.t !== "number") {
|
|
459
|
-
errors.push(path + ".t: expected number, got " + typeof v.t);
|
|
460
|
-
valid = false;
|
|
461
|
-
}
|
|
462
|
-
if (v.easing !== void 0 && !validatePxEasingOrRef(v.easing, path + ".easing", errors)) valid = false;
|
|
463
|
-
if (v.e !== void 0 && !validatePxEasingOrRef(v.e, path + ".e", errors)) valid = false;
|
|
464
|
-
return valid;
|
|
465
|
-
}
|
|
466
|
-
function validatePxPropertyAnimation(v, path, errors) {
|
|
467
|
-
if (!isObject(v)) {
|
|
468
|
-
errors.push(path + ": expected object");
|
|
469
|
-
return false;
|
|
470
|
-
}
|
|
471
|
-
let valid = true;
|
|
472
|
-
if (v.keyframes !== void 0) {
|
|
473
|
-
if (!Array.isArray(v.keyframes)) {
|
|
474
|
-
errors.push(path + ".keyframes: expected array");
|
|
475
|
-
valid = false;
|
|
476
|
-
} else {
|
|
477
|
-
v.keyframes.forEach((kf, i) => {
|
|
478
|
-
if (!validatePxKeyframe(kf, path + ".keyframes[" + i + "]", errors)) valid = false;
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
if (v.kfs !== void 0) {
|
|
483
|
-
if (!Array.isArray(v.kfs)) {
|
|
484
|
-
errors.push(path + ".kfs: expected array");
|
|
485
|
-
valid = false;
|
|
486
|
-
} else {
|
|
487
|
-
v.kfs.forEach((kf, i) => {
|
|
488
|
-
if (!validatePxKeyframe(kf, path + ".kfs[" + i + "]", errors)) valid = false;
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
return valid;
|
|
493
|
-
}
|
|
494
|
-
function validatePxAnimationDefinition(v, path, errors) {
|
|
495
|
-
if (!isObject(v)) {
|
|
496
|
-
errors.push(path + ": expected object");
|
|
497
|
-
return false;
|
|
498
|
-
}
|
|
499
|
-
let valid = true;
|
|
500
|
-
for (const key of Object.keys(v)) {
|
|
501
|
-
if (!validatePxPropertyAnimation(v[key], path + "." + key, errors)) valid = false;
|
|
502
|
-
}
|
|
503
|
-
return valid;
|
|
504
|
-
}
|
|
505
|
-
function validatePxElementAnimation(v, path, errors) {
|
|
506
|
-
if (typeof v === "string") return true;
|
|
507
|
-
if (Array.isArray(v)) {
|
|
508
|
-
let valid = true;
|
|
509
|
-
v.forEach((item, i) => {
|
|
510
|
-
if (typeof item !== "string" && !validatePxAnimationDefinition(item, path + "[" + i + "]", errors)) {
|
|
511
|
-
valid = false;
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
return valid;
|
|
2042
|
+
// src/PxMotionPath.ts
|
|
2043
|
+
function propAnimIsMotionPath(anim) {
|
|
2044
|
+
var _a;
|
|
2045
|
+
const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
|
|
2046
|
+
if (!Array.isArray(kfs)) return false;
|
|
2047
|
+
if (anim.autoOrient) return true;
|
|
2048
|
+
for (const kf of kfs) {
|
|
2049
|
+
if (kf.tangentIn || kf.tangentOut) return true;
|
|
515
2050
|
}
|
|
516
|
-
if (isObject(v)) return validatePxAnimationDefinition(v, path, errors);
|
|
517
|
-
errors.push(path + ": expected string, array, or PxAnimationDefinition object");
|
|
518
2051
|
return false;
|
|
519
2052
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
-
let valid = true;
|
|
550
|
-
if (v.mode !== void 0 && !["auto", "webapi", "frames"].includes(v.mode)) {
|
|
551
|
-
errors.push(path + '.mode: invalid value "' + v.mode + `", expected 'auto'|'webapi'|'frames'`);
|
|
552
|
-
valid = false;
|
|
553
|
-
}
|
|
554
|
-
if (v.duration !== void 0 && typeof v.duration !== "number") {
|
|
555
|
-
errors.push(path + ".duration: expected number, got " + typeof v.duration);
|
|
556
|
-
valid = false;
|
|
557
|
-
}
|
|
558
|
-
if (v.delay !== void 0 && typeof v.delay !== "number") {
|
|
559
|
-
errors.push(path + ".delay: expected number, got " + typeof v.delay);
|
|
560
|
-
valid = false;
|
|
561
|
-
}
|
|
562
|
-
if (v.iterations !== void 0 && typeof v.iterations !== "number" && v.iterations !== "infinite") {
|
|
563
|
-
errors.push(path + ".iterations: expected number or 'infinite', got " + typeof v.iterations);
|
|
564
|
-
valid = false;
|
|
565
|
-
}
|
|
566
|
-
if (v.fill !== void 0 && !validateFillMode(v.fill, path + ".fill", errors)) valid = false;
|
|
567
|
-
if (v.direction !== void 0 && !validatePlaybackDirection(v.direction, path + ".direction", errors)) valid = false;
|
|
568
|
-
if (v.frameRate !== void 0 && typeof v.frameRate !== "number") {
|
|
569
|
-
errors.push(path + ".frameRate: expected number, got " + typeof v.frameRate);
|
|
570
|
-
valid = false;
|
|
571
|
-
}
|
|
572
|
-
if (v.trigger !== void 0 && !validatePxTrigger(v.trigger, path + ".trigger", errors)) valid = false;
|
|
573
|
-
return valid;
|
|
574
|
-
}
|
|
575
|
-
function validatePxDefs(v, path, errors) {
|
|
576
|
-
if (!isObject(v)) {
|
|
577
|
-
errors.push(path + ": expected object");
|
|
578
|
-
return false;
|
|
579
|
-
}
|
|
580
|
-
let valid = true;
|
|
581
|
-
if (v.easings !== void 0) {
|
|
582
|
-
if (!isObject(v.easings)) {
|
|
583
|
-
errors.push(path + ".easings: expected object");
|
|
584
|
-
valid = false;
|
|
585
|
-
} else {
|
|
586
|
-
for (const key of Object.keys(v.easings)) {
|
|
587
|
-
if (!validatePxEasingOrRef(v.easings[key], path + ".easings." + key, errors)) valid = false;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
if (v.animations !== void 0) {
|
|
592
|
-
if (!isObject(v.animations)) {
|
|
593
|
-
errors.push(path + ".animations: expected object");
|
|
594
|
-
valid = false;
|
|
595
|
-
} else {
|
|
596
|
-
for (const key of Object.keys(v.animations)) {
|
|
597
|
-
if (!validatePxAnimationDefinition(v.animations[key], path + ".animations." + key, errors)) valid = false;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
if (v.styles !== void 0 && !isObject(v.styles)) {
|
|
602
|
-
errors.push(path + ".styles: expected object");
|
|
603
|
-
valid = false;
|
|
604
|
-
}
|
|
605
|
-
return valid;
|
|
606
|
-
}
|
|
607
|
-
function validatePxBinding(v, path, errors) {
|
|
608
|
-
if (!isObject(v)) {
|
|
609
|
-
errors.push(path + ": expected object");
|
|
610
|
-
return false;
|
|
611
|
-
}
|
|
612
|
-
let valid = true;
|
|
613
|
-
if (typeof v.id !== "string") {
|
|
614
|
-
errors.push(path + ".id: expected string, got " + typeof v.id);
|
|
615
|
-
valid = false;
|
|
616
|
-
}
|
|
617
|
-
if (!validatePxElementAnimation(v.animate, path + ".animate", errors)) valid = false;
|
|
618
|
-
return valid;
|
|
619
|
-
}
|
|
620
|
-
function validatePxNode(v, path, errors) {
|
|
621
|
-
if (!isObject(v)) {
|
|
622
|
-
errors.push(path + ": expected object");
|
|
623
|
-
return false;
|
|
624
|
-
}
|
|
625
|
-
let valid = true;
|
|
626
|
-
if (typeof v.type !== "string") {
|
|
627
|
-
errors.push(path + ".type: expected string, got " + typeof v.type);
|
|
628
|
-
valid = false;
|
|
629
|
-
}
|
|
630
|
-
if (v.children !== void 0) {
|
|
631
|
-
if (!Array.isArray(v.children)) {
|
|
632
|
-
errors.push(path + ".children: expected array");
|
|
633
|
-
valid = false;
|
|
634
|
-
} else {
|
|
635
|
-
v.children.forEach((child, i) => {
|
|
636
|
-
if (!validatePxNode(child, path + ".children[" + i + "]", errors)) valid = false;
|
|
637
|
-
});
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
if (v.animate !== void 0 && !validatePxElementAnimation(v.animate, path + ".animate", errors)) valid = false;
|
|
641
|
-
return valid;
|
|
642
|
-
}
|
|
643
|
-
function validatePxSvgNode(v, path, errors) {
|
|
644
|
-
if (!validatePxNode(v, path, errors)) return false;
|
|
645
|
-
let valid = true;
|
|
646
|
-
if (v.type !== "svg") {
|
|
647
|
-
errors.push(path + ".type: expected 'svg', got '" + v.type + "'");
|
|
648
|
-
valid = false;
|
|
649
|
-
}
|
|
650
|
-
if (v.width !== void 0 && typeof v.width !== "number") {
|
|
651
|
-
errors.push(path + ".width: expected number, got " + typeof v.width);
|
|
652
|
-
valid = false;
|
|
653
|
-
}
|
|
654
|
-
if (v.height !== void 0 && typeof v.height !== "number") {
|
|
655
|
-
errors.push(path + ".height: expected number, got " + typeof v.height);
|
|
656
|
-
valid = false;
|
|
657
|
-
}
|
|
658
|
-
if (v.viewBox !== void 0 && typeof v.viewBox !== "string") {
|
|
659
|
-
errors.push(path + ".viewBox: expected string, got " + typeof v.viewBox);
|
|
660
|
-
valid = false;
|
|
661
|
-
}
|
|
662
|
-
if (v.animator !== void 0 && !validatePxAnimatorConfig(v.animator, path + ".animator", errors)) valid = false;
|
|
663
|
-
if (v.defs !== void 0 && !validatePxDefs(v.defs, path + ".defs", errors)) valid = false;
|
|
664
|
-
if (v.bindings !== void 0) {
|
|
665
|
-
if (!Array.isArray(v.bindings)) {
|
|
666
|
-
errors.push(path + ".bindings: expected array");
|
|
667
|
-
valid = false;
|
|
668
|
-
} else {
|
|
669
|
-
v.bindings.forEach((binding, i) => {
|
|
670
|
-
if (!validatePxBinding(binding, path + ".bindings[" + i + "]", errors)) valid = false;
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
if (v.design !== void 0 && !validatePxNode(v.design, path + ".design", errors)) valid = false;
|
|
675
|
-
return valid;
|
|
676
|
-
}
|
|
677
|
-
function isPxElementFileFormatDeep(fileJson) {
|
|
678
|
-
const errors = [];
|
|
679
|
-
const valid = validatePxSvgNode(fileJson, "root", errors);
|
|
680
|
-
return { valid, errors };
|
|
681
|
-
}
|
|
682
|
-
function getAnimatorConfig(doc) {
|
|
683
|
-
var _a, _b;
|
|
684
|
-
return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator) || (doc == null ? void 0 : doc.animation) || ((_b = doc == null ? void 0 : doc.meta) == null ? void 0 : _b.animation);
|
|
685
|
-
}
|
|
686
|
-
function getDefs(doc) {
|
|
687
|
-
var _a;
|
|
688
|
-
if (!doc) return void 0;
|
|
689
|
-
return doc.defs || ((_a = doc.meta) == null ? void 0 : _a.defs);
|
|
690
|
-
}
|
|
691
|
-
function getBindings(doc) {
|
|
692
|
-
var _a;
|
|
693
|
-
if (!doc) return void 0;
|
|
694
|
-
return doc.bindings || ((_a = doc.meta) == null ? void 0 : _a.bindings);
|
|
695
|
-
}
|
|
696
|
-
function getChildren(doc) {
|
|
697
|
-
return doc == null ? void 0 : doc.children;
|
|
2053
|
+
var _segmentCache = /* @__PURE__ */ new WeakMap();
|
|
2054
|
+
function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
|
|
2055
|
+
const existing = _segmentCache.get(prevKf);
|
|
2056
|
+
if (existing) return existing;
|
|
2057
|
+
const to = prevKf.tangentOut;
|
|
2058
|
+
const ti = nextKf.tangentIn;
|
|
2059
|
+
const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
|
|
2060
|
+
const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
|
|
2061
|
+
const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
|
|
2062
|
+
const entry = {
|
|
2063
|
+
P0: prevPos,
|
|
2064
|
+
P1,
|
|
2065
|
+
P2,
|
|
2066
|
+
P3: nextPos,
|
|
2067
|
+
lut,
|
|
2068
|
+
totalArc: lut.ds[lut.ds.length - 1]
|
|
2069
|
+
};
|
|
2070
|
+
_segmentCache.set(prevKf, entry);
|
|
2071
|
+
return entry;
|
|
2072
|
+
}
|
|
2073
|
+
function evaluateMotionPathSegment(prevKf, nextKf, prevPos, nextPos, localProgress, autoOrient) {
|
|
2074
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
2075
|
+
const t = seg.totalArc === 0 ? localProgress : bezier2D_tForDistance(seg.lut, localProgress * seg.totalArc);
|
|
2076
|
+
const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2077
|
+
if (!autoOrient) return { translate: point };
|
|
2078
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2079
|
+
const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
2080
|
+
return { translate: point, rotateDeg };
|
|
698
2081
|
}
|
|
699
2082
|
|
|
700
2083
|
// src/PxDefinitions.ts
|
|
@@ -760,6 +2143,8 @@ function parseSvgPathToBezier(d) {
|
|
|
760
2143
|
currentPath.o.push([x2, y2]);
|
|
761
2144
|
} else if (type === "Z" || type === "z") {
|
|
762
2145
|
currentPath.c = true;
|
|
2146
|
+
} else {
|
|
2147
|
+
console.warn('Unsupported path command "' + type + '"');
|
|
763
2148
|
}
|
|
764
2149
|
}
|
|
765
2150
|
return res;
|
|
@@ -777,13 +2162,17 @@ function isPathString(value) {
|
|
|
777
2162
|
return typeof value === "string" && extractPathData(value) !== void 0;
|
|
778
2163
|
}
|
|
779
2164
|
function normalizePathValue(value) {
|
|
2165
|
+
if (value && typeof value === "object" && typeof value.path === "string") {
|
|
2166
|
+
const d = extractPathData(value.path);
|
|
2167
|
+
return d ? { paths: parseSvgPathToBezier(d) } : value;
|
|
2168
|
+
}
|
|
780
2169
|
if (value && typeof value === "object" && "paths" in value) {
|
|
781
2170
|
const pathsArray = value.paths;
|
|
782
2171
|
if (Array.isArray(pathsArray) && pathsArray.length > 0) {
|
|
783
2172
|
if (isPathString(pathsArray[0])) {
|
|
784
2173
|
const paths = [];
|
|
785
|
-
for (const
|
|
786
|
-
const d = extractPathData(
|
|
2174
|
+
for (const pathStr2 of pathsArray) {
|
|
2175
|
+
const d = extractPathData(pathStr2);
|
|
787
2176
|
if (d) {
|
|
788
2177
|
paths.push(...parseSvgPathToBezier(d));
|
|
789
2178
|
}
|
|
@@ -796,8 +2185,8 @@ function normalizePathValue(value) {
|
|
|
796
2185
|
if (Array.isArray(value)) {
|
|
797
2186
|
if (value.length > 0 && isPathString(value[0])) {
|
|
798
2187
|
const paths = [];
|
|
799
|
-
for (const
|
|
800
|
-
const d = extractPathData(
|
|
2188
|
+
for (const pathStr2 of value) {
|
|
2189
|
+
const d = extractPathData(pathStr2);
|
|
801
2190
|
if (d) {
|
|
802
2191
|
paths.push(...parseSvgPathToBezier(d));
|
|
803
2192
|
}
|
|
@@ -851,6 +2240,111 @@ function resolveElementAnimation(animate, defs) {
|
|
|
851
2240
|
}
|
|
852
2241
|
return results;
|
|
853
2242
|
}
|
|
2243
|
+
function interpolateValue(propName, a, b, t) {
|
|
2244
|
+
var _a, _b;
|
|
2245
|
+
if (propName === "d") {
|
|
2246
|
+
const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
|
|
2247
|
+
const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
|
|
2248
|
+
return { paths: interpolateBeziers(aPaths, bPaths, t) };
|
|
2249
|
+
}
|
|
2250
|
+
if (COLOUR_ATTR_NAMES.has(propName)) {
|
|
2251
|
+
return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
|
|
2252
|
+
}
|
|
2253
|
+
if (TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
|
|
2254
|
+
return interpolateVec(a || [], b || [], t);
|
|
2255
|
+
}
|
|
2256
|
+
return interpolateNum(+(a || 0), +(b || 0), t);
|
|
2257
|
+
}
|
|
2258
|
+
function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
2259
|
+
var _a, _b, _c, _d, _e;
|
|
2260
|
+
const totalIntervals = keyframes.length - 1;
|
|
2261
|
+
const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
|
|
2262
|
+
let segKfs;
|
|
2263
|
+
if (loop.before) {
|
|
2264
|
+
segKfs = keyframes.slice(0, segCount + 1);
|
|
2265
|
+
} else {
|
|
2266
|
+
segKfs = keyframes.slice(totalIntervals - segCount);
|
|
2267
|
+
}
|
|
2268
|
+
const firstT = (_b = keyframes[0].t) != null ? _b : 0;
|
|
2269
|
+
const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
|
|
2270
|
+
let fillStart, fillEnd;
|
|
2271
|
+
if (loop.before) {
|
|
2272
|
+
fillStart = 0;
|
|
2273
|
+
fillEnd = firstT;
|
|
2274
|
+
} else {
|
|
2275
|
+
fillStart = lastT;
|
|
2276
|
+
fillEnd = duration;
|
|
2277
|
+
}
|
|
2278
|
+
const fillDuration = fillEnd - fillStart;
|
|
2279
|
+
if (fillDuration <= 0) return keyframes;
|
|
2280
|
+
const segStartT = (_d = segKfs[0].t) != null ? _d : 0;
|
|
2281
|
+
const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
|
|
2282
|
+
const segDuration = segEndT - segStartT;
|
|
2283
|
+
if (segDuration <= 0) return keyframes;
|
|
2284
|
+
const template = segKfs.map((kf) => ({
|
|
2285
|
+
relT: (kf.t - segStartT) / segDuration,
|
|
2286
|
+
v: kf.v,
|
|
2287
|
+
e: kf.e
|
|
2288
|
+
}));
|
|
2289
|
+
const fullReps = Math.floor(fillDuration / segDuration);
|
|
2290
|
+
const remainder = fillDuration - fullReps * segDuration;
|
|
2291
|
+
const partialFraction = remainder / segDuration;
|
|
2292
|
+
const looped = [];
|
|
2293
|
+
function appendRep(repStart, isReversed, partial) {
|
|
2294
|
+
let entries;
|
|
2295
|
+
if (isReversed) {
|
|
2296
|
+
entries = [];
|
|
2297
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
2298
|
+
entries.push({
|
|
2299
|
+
relT: 1 - template[i].relT,
|
|
2300
|
+
v: template[i].v,
|
|
2301
|
+
// Easing for reversed transition: use reversed easing from the forward "from" keyframe
|
|
2302
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0
|
|
2303
|
+
});
|
|
2304
|
+
}
|
|
2305
|
+
} else {
|
|
2306
|
+
entries = template;
|
|
2307
|
+
}
|
|
2308
|
+
const cutRelT = partial !== void 0 ? partial : 1;
|
|
2309
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2310
|
+
const entry = entries[i];
|
|
2311
|
+
if (entry.relT > cutRelT + 1e-9) {
|
|
2312
|
+
const prev = entries[i - 1];
|
|
2313
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
2314
|
+
const localFrac = (cutRelT - prev.relT) / intervalSpan;
|
|
2315
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
2316
|
+
const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
2317
|
+
const { left: leftEasing } = splitEasing(prev.e, localFrac);
|
|
2318
|
+
if (looped.length > 0 && prev.relT <= cutRelT) {
|
|
2319
|
+
looped[looped.length - 1].e = leftEasing;
|
|
2320
|
+
}
|
|
2321
|
+
looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
|
|
2322
|
+
return;
|
|
2323
|
+
}
|
|
2324
|
+
looped.push({
|
|
2325
|
+
t: repStart + entry.relT * segDuration,
|
|
2326
|
+
v: entry.v,
|
|
2327
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
2328
|
+
});
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
2332
|
+
const distFromBoundary = loop.before ? fullReps - 1 - rep : rep;
|
|
2333
|
+
const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
|
|
2334
|
+
const repStart = fillStart + rep * segDuration;
|
|
2335
|
+
appendRep(repStart, isReversed);
|
|
2336
|
+
}
|
|
2337
|
+
if (partialFraction > 1e-9) {
|
|
2338
|
+
const isReversed = !!loop.alternate && fullReps % 2 === 0;
|
|
2339
|
+
const repStart = fillStart + fullReps * segDuration;
|
|
2340
|
+
appendRep(repStart, isReversed, partialFraction);
|
|
2341
|
+
}
|
|
2342
|
+
if (loop.before) {
|
|
2343
|
+
return [...looped, ...keyframes];
|
|
2344
|
+
} else {
|
|
2345
|
+
return [...keyframes, ...looped];
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
854
2348
|
function normalizeKeyframes(propName, propAnim, duration, defs) {
|
|
855
2349
|
var _a, _b, _c, _d, _e;
|
|
856
2350
|
const keyframes = propAnim.keyframes || propAnim.kfs || [];
|
|
@@ -875,6 +2369,11 @@ function normalizeKeyframes(propName, propAnim, duration, defs) {
|
|
|
875
2369
|
var _a2, _b2;
|
|
876
2370
|
return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
|
|
877
2371
|
});
|
|
2372
|
+
const loopRaw = propAnim.loop;
|
|
2373
|
+
const loop = loopRaw === true ? {} : loopRaw || void 0;
|
|
2374
|
+
if (loop && normalized.length >= 2) {
|
|
2375
|
+
return expandLoopKeyframes(propName, normalized, loop, duration);
|
|
2376
|
+
}
|
|
878
2377
|
return normalized;
|
|
879
2378
|
}
|
|
880
2379
|
function mergeAnimationDefinitions(animations) {
|
|
@@ -925,10 +2424,11 @@ function getNormalisedBindings(doc) {
|
|
|
925
2424
|
}
|
|
926
2425
|
}
|
|
927
2426
|
const processNode = (node) => {
|
|
928
|
-
|
|
2427
|
+
const inlineAnim = node.animate;
|
|
2428
|
+
if (inlineAnim && Object.keys(inlineAnim).length > 0) {
|
|
929
2429
|
const nodeId = node.id || generateElementId();
|
|
930
2430
|
node.id = nodeId;
|
|
931
|
-
const normalized = processAnimation(nodeId,
|
|
2431
|
+
const normalized = processAnimation(nodeId, inlineAnim);
|
|
932
2432
|
if (normalized) bindings.push(normalized);
|
|
933
2433
|
}
|
|
934
2434
|
if (node.children) {
|
|
@@ -999,6 +2499,41 @@ function calcPropertyValue(propName, propAnim, progress) {
|
|
|
999
2499
|
localProgress
|
|
1000
2500
|
).join(" ");
|
|
1001
2501
|
cssAttrName = propName;
|
|
2502
|
+
} else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
|
|
2503
|
+
const partKeys = /* @__PURE__ */ new Set([
|
|
2504
|
+
...prevV ? Object.keys(prevV) : [],
|
|
2505
|
+
...nextV ? Object.keys(nextV) : []
|
|
2506
|
+
]);
|
|
2507
|
+
const partsResult = {};
|
|
2508
|
+
for (const partKey of partKeys) {
|
|
2509
|
+
const prevPart = prevV == null ? void 0 : prevV[partKey];
|
|
2510
|
+
const nextPart = nextV == null ? void 0 : nextV[partKey];
|
|
2511
|
+
if (partKey === "rotate") {
|
|
2512
|
+
partsResult.rotate = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
|
|
2513
|
+
} else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
|
|
2514
|
+
const fallback = partKey === "scale" ? [1, 1] : [0, 0];
|
|
2515
|
+
const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
|
|
2516
|
+
partsResult[partKey] = interp;
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
if (propAnimIsMotionPath(propAnim)) {
|
|
2520
|
+
const prevTr = prevV.translate;
|
|
2521
|
+
const nextTr = nextV.translate;
|
|
2522
|
+
if (Array.isArray(prevTr) && Array.isArray(nextTr)) {
|
|
2523
|
+
const sample = evaluateMotionPathSegment(
|
|
2524
|
+
prevKf,
|
|
2525
|
+
nextKf,
|
|
2526
|
+
[+prevTr[0], +prevTr[1]],
|
|
2527
|
+
[+nextTr[0], +nextTr[1]],
|
|
2528
|
+
localProgress,
|
|
2529
|
+
!!propAnim.autoOrient
|
|
2530
|
+
);
|
|
2531
|
+
partsResult.translate = [sample.translate[0], sample.translate[1]];
|
|
2532
|
+
if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
cssValue = composeTransformParts(partsResult, { withUnits: false });
|
|
2536
|
+
cssAttrName = "transform";
|
|
1002
2537
|
} else if (cssAttrName === "translate") {
|
|
1003
2538
|
const v = interpolateVec(
|
|
1004
2539
|
prevV || [0, 0],
|
|
@@ -1024,12 +2559,12 @@ function calcPropertyValue(propName, propAnim, progress) {
|
|
|
1024
2559
|
cssValue = "scale(" + v.join(",") + ")";
|
|
1025
2560
|
cssAttrName = "transform";
|
|
1026
2561
|
} else {
|
|
1027
|
-
const
|
|
2562
|
+
const num2 = interpolateNum(
|
|
1028
2563
|
+(prevV || 0),
|
|
1029
2564
|
+(nextV || 0),
|
|
1030
2565
|
localProgress
|
|
1031
2566
|
);
|
|
1032
|
-
cssValue =
|
|
2567
|
+
cssValue = num2;
|
|
1033
2568
|
}
|
|
1034
2569
|
if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
|
|
1035
2570
|
cssValue = cssValue * 100 + "%";
|
|
@@ -1309,41 +2844,91 @@ function createDomAdapter(rootElement) {
|
|
|
1309
2844
|
}
|
|
1310
2845
|
|
|
1311
2846
|
// src/PxAnimatorWebApi.ts
|
|
2847
|
+
function createCssKf(kf, t, propName, unsupportedSet) {
|
|
2848
|
+
var _a, _b;
|
|
2849
|
+
let value = (_a = kf.v) != null ? _a : kf.value;
|
|
2850
|
+
const e = (_b = kf.e) != null ? _b : kf.easing;
|
|
2851
|
+
const cssKf = {
|
|
2852
|
+
offset: t,
|
|
2853
|
+
easing: e && Array.isArray(e) ? "cubic-bezier(" + e.join(",") + ")" : void 0
|
|
2854
|
+
};
|
|
2855
|
+
let cssValue;
|
|
2856
|
+
let cssKey = propName;
|
|
2857
|
+
if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
|
|
2858
|
+
cssValue = toRGBA(value);
|
|
2859
|
+
} else if (propName === "transform" && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
2860
|
+
cssValue = composeTransformParts(value, { withUnits: true });
|
|
2861
|
+
cssKey = "transform";
|
|
2862
|
+
} else if (TRANSFORM_FN_NAMES.has(propName)) {
|
|
2863
|
+
if (Array.isArray(value)) {
|
|
2864
|
+
if (propName === "translate") value = value.map((v) => v + "px");
|
|
2865
|
+
value = value.join(",");
|
|
2866
|
+
}
|
|
2867
|
+
if (propName === "rotate") value = value + "deg";
|
|
2868
|
+
cssValue = propName + "(" + value + ")";
|
|
2869
|
+
cssKey = "transform";
|
|
2870
|
+
} else {
|
|
2871
|
+
cssValue = "" + value;
|
|
2872
|
+
}
|
|
2873
|
+
if (!CSS.supports(cssKey, cssValue)) unsupportedSet.add(cssKey);
|
|
2874
|
+
cssKey = kebabToCamelCaseWord(cssKey);
|
|
2875
|
+
cssKf[cssKey] = cssValue;
|
|
2876
|
+
return cssKf;
|
|
2877
|
+
}
|
|
2878
|
+
function clipKeyframesToDuration(propName, keyframes, duration) {
|
|
2879
|
+
var _a, _b, _c, _d, _e;
|
|
2880
|
+
const result = [];
|
|
2881
|
+
for (let i = 0; i < keyframes.length; i++) {
|
|
2882
|
+
const kf = keyframes[i];
|
|
2883
|
+
const t = (_a = kf.t) != null ? _a : 0;
|
|
2884
|
+
if (t < 0) {
|
|
2885
|
+
const next = keyframes[i + 1];
|
|
2886
|
+
if (next && ((_b = next.t) != null ? _b : 0) >= 0) {
|
|
2887
|
+
const nextT = (_c = next.t) != null ? _c : 0;
|
|
2888
|
+
const localFrac = (0 - t) / (nextT - t);
|
|
2889
|
+
const easedFrac = kf.e ? cubicBezier(kf.e)(localFrac) : localFrac;
|
|
2890
|
+
const { right: rightEasing } = splitEasing(kf.e, localFrac);
|
|
2891
|
+
result.push({ t: 0, v: interpolateValue(propName, kf.v, next.v, easedFrac), e: rightEasing });
|
|
2892
|
+
}
|
|
2893
|
+
continue;
|
|
2894
|
+
}
|
|
2895
|
+
if (t > duration) {
|
|
2896
|
+
const prev = keyframes[i - 1];
|
|
2897
|
+
if (prev && ((_d = prev.t) != null ? _d : 0) <= duration) {
|
|
2898
|
+
const prevT = (_e = prev.t) != null ? _e : 0;
|
|
2899
|
+
const localFrac = (duration - prevT) / (t - prevT);
|
|
2900
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
2901
|
+
const { left: leftEasing } = splitEasing(prev.e, localFrac);
|
|
2902
|
+
if (result.length > 0) result[result.length - 1] = __spreadProps(__spreadValues({}, result[result.length - 1]), { e: leftEasing });
|
|
2903
|
+
result.push({ t: duration, v: interpolateValue(propName, prev.v, kf.v, easedFrac), e: void 0 });
|
|
2904
|
+
}
|
|
2905
|
+
break;
|
|
2906
|
+
}
|
|
2907
|
+
result.push(kf);
|
|
2908
|
+
}
|
|
2909
|
+
return result;
|
|
2910
|
+
}
|
|
1312
2911
|
function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
|
|
1313
|
-
var _a
|
|
2912
|
+
var _a;
|
|
1314
2913
|
const result = /* @__PURE__ */ new Map();
|
|
1315
2914
|
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
1316
|
-
const
|
|
2915
|
+
const duration = config.duration || 1;
|
|
2916
|
+
const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.kfs || propAnim.keyframes || [], duration);
|
|
1317
2917
|
const cssKeyframes = [];
|
|
1318
|
-
for (
|
|
1319
|
-
|
|
1320
|
-
t = clamp(
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
offset: t,
|
|
1325
|
-
easing: e && Array.isArray(e) ? "cubic-bezier(" + e.join(",") + ")" : void 0
|
|
1326
|
-
};
|
|
1327
|
-
let cssValue;
|
|
1328
|
-
let cssKey = propName;
|
|
1329
|
-
if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
|
|
1330
|
-
cssValue = toRGBA(value);
|
|
1331
|
-
} else if (TRANSFORM_FN_NAMES.has(propName)) {
|
|
1332
|
-
if (Array.isArray(value)) {
|
|
1333
|
-
if (propName === "translate") value = value.map((v) => v + "px");
|
|
1334
|
-
value = value.join(",");
|
|
1335
|
-
}
|
|
1336
|
-
if (propName === "rotate") value = value + "deg";
|
|
1337
|
-
cssValue = propName + "(" + value + ")";
|
|
1338
|
-
cssKey = "transform";
|
|
1339
|
-
} else {
|
|
1340
|
-
cssValue = "" + value;
|
|
2918
|
+
for (let i = 0; i < clippedKeyframes.length; i++) {
|
|
2919
|
+
const kf = clippedKeyframes[i];
|
|
2920
|
+
const t = clamp(((_a = kf.t) != null ? _a : 0) / duration, 0, 1);
|
|
2921
|
+
const cssKf = createCssKf(kf, t, propName, unsupportedSet);
|
|
2922
|
+
if (i === 0 && (cssKf.offset || 0) > 0) {
|
|
2923
|
+
cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), { offset: 0 }));
|
|
1341
2924
|
}
|
|
1342
|
-
if (!CSS.supports(cssKey, cssValue)) unsupportedSet.add(cssKey);
|
|
1343
|
-
cssKey = kebabToCamelCaseWord(cssKey);
|
|
1344
|
-
cssKf[cssKey] = cssValue;
|
|
1345
2925
|
cssKeyframes.push(cssKf);
|
|
1346
2926
|
}
|
|
2927
|
+
if (cssKeyframes.length > 0 && (cssKeyframes[cssKeyframes.length - 1].offset || 0) < 1) {
|
|
2928
|
+
cssKeyframes.push(__spreadProps(__spreadValues({}, cssKeyframes[cssKeyframes.length - 1]), {
|
|
2929
|
+
offset: 1
|
|
2930
|
+
}));
|
|
2931
|
+
}
|
|
1347
2932
|
if (cssKeyframes.length > 0) {
|
|
1348
2933
|
result.set(propName, cssKeyframes);
|
|
1349
2934
|
}
|
|
@@ -1351,6 +2936,7 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
|
|
|
1351
2936
|
return result;
|
|
1352
2937
|
}
|
|
1353
2938
|
function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs) {
|
|
2939
|
+
var _a;
|
|
1354
2940
|
const config = getAnimatorConfig(doc) || {};
|
|
1355
2941
|
const bindings = getNormalisedBindings(doc);
|
|
1356
2942
|
if (!rootElement) {
|
|
@@ -1383,29 +2969,33 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
1383
2969
|
console.warn('createWebApiAnimator: No elements found for selector "' + selector + '"');
|
|
1384
2970
|
}
|
|
1385
2971
|
const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);
|
|
2972
|
+
const positiveDelay = config.delay && config.delay > 0 ? config.delay : void 0;
|
|
2973
|
+
const seekPosition = config.delay && config.delay < 0 && config.duration ? -config.delay % config.duration : void 0;
|
|
2974
|
+
const effectOptions = {
|
|
2975
|
+
duration: config.duration,
|
|
2976
|
+
delay: positiveDelay,
|
|
2977
|
+
// Default to 'forwards' so elements hold their final state after the
|
|
2978
|
+
// animation ends — consistent with Lottie and other animation runtimes.
|
|
2979
|
+
// Without this, seeking to the last frame reverts elements to their
|
|
2980
|
+
// pre-animation state (the Web Animations API "after" phase with fill:'none').
|
|
2981
|
+
fill: (_a = config.fill) != null ? _a : "forwards",
|
|
2982
|
+
direction: config.direction,
|
|
2983
|
+
iterations
|
|
2984
|
+
};
|
|
1386
2985
|
for (let i = 0; i < elements.length; i++) {
|
|
1387
2986
|
const element = elements[i];
|
|
1388
|
-
const positiveDelay = config.delay && config.delay > 0 ? config.delay : void 0;
|
|
1389
|
-
const seekPosition = config.delay && config.delay < 0 && config.duration ? -config.delay % config.duration : void 0;
|
|
1390
|
-
const effectOptions = {
|
|
1391
|
-
duration: config.duration,
|
|
1392
|
-
delay: positiveDelay,
|
|
1393
|
-
fill: config.fill,
|
|
1394
|
-
direction: config.direction,
|
|
1395
|
-
iterations
|
|
1396
|
-
};
|
|
1397
2987
|
for (const [, keyframes] of keyframesMap) {
|
|
1398
2988
|
if (keyframes.length > 0) {
|
|
1399
2989
|
try {
|
|
1400
2990
|
const effect = new KeyframeEffect(element, keyframes, effectOptions);
|
|
1401
2991
|
const anim = new Animation(effect, document.timeline);
|
|
1402
2992
|
if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
|
|
1403
|
-
var
|
|
1404
|
-
return (
|
|
2993
|
+
var _a2;
|
|
2994
|
+
return (_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
|
|
1405
2995
|
};
|
|
1406
2996
|
if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
|
|
1407
|
-
var
|
|
1408
|
-
return (
|
|
2997
|
+
var _a2;
|
|
2998
|
+
return (_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
|
|
1409
2999
|
};
|
|
1410
3000
|
if (seekPosition) {
|
|
1411
3001
|
anim.currentTime = seekPosition;
|
|
@@ -1426,34 +3016,47 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
1426
3016
|
"isReady": () => true,
|
|
1427
3017
|
"getRootElement": () => rootElement || null,
|
|
1428
3018
|
"isPlaying": () => {
|
|
1429
|
-
var
|
|
1430
|
-
return ((
|
|
3019
|
+
var _a2;
|
|
3020
|
+
return ((_a2 = animations[0]) == null ? void 0 : _a2.playState) === "running";
|
|
1431
3021
|
},
|
|
1432
3022
|
"play": () => {
|
|
1433
|
-
var
|
|
3023
|
+
var _a2;
|
|
1434
3024
|
animations.forEach((a) => a.play());
|
|
1435
|
-
(
|
|
3025
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
|
|
1436
3026
|
},
|
|
1437
3027
|
"pause": () => {
|
|
1438
|
-
var
|
|
3028
|
+
var _a2;
|
|
1439
3029
|
animations.forEach((a) => a.pause());
|
|
1440
|
-
(
|
|
3030
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
|
|
1441
3031
|
},
|
|
1442
3032
|
"cancel": () => {
|
|
1443
|
-
var
|
|
3033
|
+
var _a2;
|
|
1444
3034
|
animations.forEach((a) => a.cancel());
|
|
1445
|
-
(
|
|
3035
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
|
|
1446
3036
|
},
|
|
1447
3037
|
"finish": () => {
|
|
1448
|
-
|
|
3038
|
+
var _a2;
|
|
3039
|
+
for (const a of animations) {
|
|
3040
|
+
try {
|
|
3041
|
+
if (((_a2 = a.effect) == null ? void 0 : _a2.getTiming().iterations) === Infinity) {
|
|
3042
|
+
a.effect.updateTiming({ iterations: 1 });
|
|
3043
|
+
a.finish();
|
|
3044
|
+
a.effect.updateTiming({ iterations: Infinity });
|
|
3045
|
+
} else {
|
|
3046
|
+
a.finish();
|
|
3047
|
+
}
|
|
3048
|
+
} catch (e) {
|
|
3049
|
+
a.cancel();
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
1449
3052
|
},
|
|
1450
3053
|
"setPlaybackRate": (rate) => {
|
|
1451
3054
|
animations.forEach((a) => a.playbackRate = rate);
|
|
1452
3055
|
return api;
|
|
1453
3056
|
},
|
|
1454
3057
|
"getCurrentTime": () => {
|
|
1455
|
-
var
|
|
1456
|
-
const res = (_b = (
|
|
3058
|
+
var _a2, _b;
|
|
3059
|
+
const res = (_b = (_a2 = animations[0]) == null ? void 0 : _a2.currentTime) != null ? _b : null;
|
|
1457
3060
|
return res !== null ? +res : null;
|
|
1458
3061
|
},
|
|
1459
3062
|
"setCurrentTime": (time) => {
|
|
@@ -1510,6 +3113,7 @@ function deepClone(value) {
|
|
|
1510
3113
|
return cloned;
|
|
1511
3114
|
}
|
|
1512
3115
|
function generateNewIds(doc) {
|
|
3116
|
+
var _a, _b;
|
|
1513
3117
|
const cloned = deepClone(doc);
|
|
1514
3118
|
const idMap = /* @__PURE__ */ new Map();
|
|
1515
3119
|
const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
|
|
@@ -1535,6 +3139,8 @@ function generateNewIds(doc) {
|
|
|
1535
3139
|
const newId = generateUniqueId();
|
|
1536
3140
|
idMap.set(oldId, newId);
|
|
1537
3141
|
node.id = newId;
|
|
3142
|
+
} else if (node.animate) {
|
|
3143
|
+
node.id = generateUniqueId();
|
|
1538
3144
|
}
|
|
1539
3145
|
if (Array.isArray(node.children)) {
|
|
1540
3146
|
for (const child of node.children) {
|
|
@@ -1576,23 +3182,21 @@ function generateNewIds(doc) {
|
|
|
1576
3182
|
value[styleProp] = replaceUrlRefs(styleValue, idMap);
|
|
1577
3183
|
}
|
|
1578
3184
|
}
|
|
1579
|
-
} else if (typeof value === "object" && value !== null
|
|
3185
|
+
} else if (typeof value === "object" && value !== null) {
|
|
1580
3186
|
updateRefs(value);
|
|
1581
3187
|
}
|
|
1582
3188
|
}
|
|
1583
3189
|
}
|
|
1584
3190
|
collectIds(cloned);
|
|
1585
3191
|
updateRefs(cloned);
|
|
1586
|
-
const
|
|
1587
|
-
if (
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
binding.id = newId;
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
3192
|
+
const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animate;
|
|
3193
|
+
if (docAnimate && typeof docAnimate === "object") {
|
|
3194
|
+
const updatedAnimate = {};
|
|
3195
|
+
for (const [id, anim] of Object.entries(docAnimate)) {
|
|
3196
|
+
const newId = (_b = idMap.get(id)) != null ? _b : id;
|
|
3197
|
+
updatedAnimate[newId] = anim;
|
|
1595
3198
|
}
|
|
3199
|
+
cloned.animator = __spreadProps(__spreadValues({}, cloned.animator), { animate: updatedAnimate });
|
|
1596
3200
|
}
|
|
1597
3201
|
return cloned;
|
|
1598
3202
|
}
|
|
@@ -1603,6 +3207,9 @@ function replaceUrlRefs(value, idMap) {
|
|
|
1603
3207
|
});
|
|
1604
3208
|
}
|
|
1605
3209
|
function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
|
|
3210
|
+
const effectsWarnings = validateNodeEffects(doc);
|
|
3211
|
+
for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
|
|
3212
|
+
doc = applyPlayerEffects(doc).root;
|
|
1606
3213
|
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
1607
3214
|
animatorConfig.debug = true;
|
|
1608
3215
|
let rootElement = null;
|
|
@@ -1618,14 +3225,22 @@ function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
|
|
|
1618
3225
|
}
|
|
1619
3226
|
return createAnimatorFromConfig(doc, adapter, callbacks, rootElement);
|
|
1620
3227
|
}
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
3228
|
+
var PX_ANIMATOR_DATA_KEY = "data";
|
|
3229
|
+
function createAnimator(options) {
|
|
3230
|
+
const { src, data, adapter, callbacks, container } = options;
|
|
3231
|
+
if (data !== void 0 && src !== void 0) {
|
|
3232
|
+
throw new Error("createAnimator: provide either `src` or `data`, not both");
|
|
3233
|
+
}
|
|
3234
|
+
if (data === void 0 && src === void 0) {
|
|
3235
|
+
throw new Error("createAnimator: either `src` or `data` is required");
|
|
3236
|
+
}
|
|
3237
|
+
if (data !== void 0) {
|
|
3238
|
+
return createAnimatorImpl(data, adapter, callbacks, container);
|
|
1624
3239
|
}
|
|
1625
3240
|
let animator = null;
|
|
1626
|
-
fetch(
|
|
3241
|
+
fetch(src).then((res) => res.json()).then((json) => {
|
|
1627
3242
|
if (isPxElementFileFormat(json)) {
|
|
1628
|
-
animator = createAnimatorImpl(json, adapter, callbacks,
|
|
3243
|
+
animator = createAnimatorImpl(json, adapter, callbacks, container);
|
|
1629
3244
|
} else {
|
|
1630
3245
|
console.error("Invalid animation document format");
|
|
1631
3246
|
}
|
|
@@ -1665,7 +3280,7 @@ function loadTagAnimators() {
|
|
|
1665
3280
|
if (!element[PX_ANIM_ATTR_NAME]) {
|
|
1666
3281
|
const src = element.getAttribute(PX_ANIM_SRC_ATTR_NAME);
|
|
1667
3282
|
if (src) {
|
|
1668
|
-
element[PX_ANIM_ATTR_NAME] = createAnimator(src,
|
|
3283
|
+
element[PX_ANIM_ATTR_NAME] = createAnimator({ src, container: element });
|
|
1669
3284
|
}
|
|
1670
3285
|
}
|
|
1671
3286
|
}
|
|
@@ -1675,19 +3290,258 @@ if (typeof window !== "undefined") {
|
|
|
1675
3290
|
window["createAnimator"] = createAnimator;
|
|
1676
3291
|
window["setupAnimationTriggers"] = setupAnimationTriggers;
|
|
1677
3292
|
}
|
|
3293
|
+
|
|
3294
|
+
// src/effects/PlayerEffectsUtil.visualModel.ts
|
|
3295
|
+
var IDENTITY = [1, 0, 0, 1, 0, 0];
|
|
3296
|
+
function mul(m, n) {
|
|
3297
|
+
return [
|
|
3298
|
+
m[0] * n[0] + m[2] * n[1],
|
|
3299
|
+
m[1] * n[0] + m[3] * n[1],
|
|
3300
|
+
m[0] * n[2] + m[2] * n[3],
|
|
3301
|
+
m[1] * n[2] + m[3] * n[3],
|
|
3302
|
+
m[0] * n[4] + m[2] * n[5] + m[4],
|
|
3303
|
+
m[1] * n[4] + m[3] * n[5] + m[5]
|
|
3304
|
+
];
|
|
3305
|
+
}
|
|
3306
|
+
var translateM = (x, y) => [1, 0, 0, 1, x, y];
|
|
3307
|
+
var scaleM = (sx, sy) => [sx, 0, 0, sy, 0, 0];
|
|
3308
|
+
function rotateM(deg) {
|
|
3309
|
+
const r = deg * Math.PI / 180;
|
|
3310
|
+
return [Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0];
|
|
3311
|
+
}
|
|
3312
|
+
var skewXM = (deg) => [1, 0, Math.tan(deg * Math.PI / 180), 1, 0, 0];
|
|
3313
|
+
var skewYM = (deg) => [1, Math.tan(deg * Math.PI / 180), 0, 1, 0, 0];
|
|
3314
|
+
function parseTransformString(s) {
|
|
3315
|
+
let m = IDENTITY;
|
|
3316
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
3317
|
+
let hit;
|
|
3318
|
+
while (hit = re.exec(s)) {
|
|
3319
|
+
const fn = hit[1];
|
|
3320
|
+
const a = hit[2].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
3321
|
+
if (fn === "translate") m = mul(m, translateM(a[0] || 0, a[1] || 0));
|
|
3322
|
+
else if (fn === "scale") m = mul(m, scaleM(a[0], a.length > 1 ? a[1] : a[0]));
|
|
3323
|
+
else if (fn === "rotate") m = mul(m, rotateM(a[0]));
|
|
3324
|
+
else if (fn === "skewX") m = mul(m, skewXM(a[0]));
|
|
3325
|
+
else if (fn === "skewY") m = mul(m, skewYM(a[0]));
|
|
3326
|
+
else if (fn === "matrix") m = mul(m, [a[0], a[1], a[2], a[3], a[4], a[5]]);
|
|
3327
|
+
}
|
|
3328
|
+
return m;
|
|
3329
|
+
}
|
|
3330
|
+
function partsToMatrix(p) {
|
|
3331
|
+
let m = IDENTITY;
|
|
3332
|
+
if (p.translate) m = mul(m, translateM(p.translate[0], p.translate[1]));
|
|
3333
|
+
const pivot = p.origin && (p.rotate !== void 0 || p.scale);
|
|
3334
|
+
if (pivot) m = mul(m, translateM(p.origin[0], p.origin[1]));
|
|
3335
|
+
if (p.rotate !== void 0) m = mul(m, rotateM(p.rotate));
|
|
3336
|
+
if (p.scale) m = mul(m, scaleM(p.scale[0], p.scale[1]));
|
|
3337
|
+
if (pivot) m = mul(m, translateM(-p.origin[0], -p.origin[1]));
|
|
3338
|
+
return m;
|
|
3339
|
+
}
|
|
3340
|
+
function lerp(a, b, f) {
|
|
3341
|
+
return a + (b - a) * f;
|
|
3342
|
+
}
|
|
3343
|
+
function interpParts(kfs, t) {
|
|
3344
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
3345
|
+
if (!kfs.length) return {};
|
|
3346
|
+
if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value || {};
|
|
3347
|
+
if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value || {};
|
|
3348
|
+
let i = 0;
|
|
3349
|
+
while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
|
|
3350
|
+
const a = kfs[i], b = kfs[i + 1];
|
|
3351
|
+
const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
|
|
3352
|
+
const va = a.value || {}, vb = b.value || {};
|
|
3353
|
+
const out = {};
|
|
3354
|
+
if (va.translate && vb.translate) out.translate = [lerp(va.translate[0], vb.translate[0], f), lerp(va.translate[1], vb.translate[1], f)];
|
|
3355
|
+
else out.translate = va.translate || vb.translate;
|
|
3356
|
+
if (va.rotate !== void 0 && vb.rotate !== void 0) out.rotate = lerp(va.rotate, vb.rotate, f);
|
|
3357
|
+
else out.rotate = (_g = va.rotate) != null ? _g : vb.rotate;
|
|
3358
|
+
if (va.scale && vb.scale) out.scale = [lerp(va.scale[0], vb.scale[0], f), lerp(va.scale[1], vb.scale[1], f)];
|
|
3359
|
+
else out.scale = va.scale || vb.scale;
|
|
3360
|
+
out.origin = va.origin || vb.origin;
|
|
3361
|
+
return out;
|
|
3362
|
+
}
|
|
3363
|
+
function evalTransformValue(v, t) {
|
|
3364
|
+
if (v === void 0 || v === null) return IDENTITY;
|
|
3365
|
+
if (typeof v === "string") return parseTransformString(v);
|
|
3366
|
+
if (v.keyframes) return partsToMatrix(interpParts(v.keyframes, t));
|
|
3367
|
+
if (v.value) return partsToMatrix(v.value);
|
|
3368
|
+
return IDENTITY;
|
|
3369
|
+
}
|
|
3370
|
+
function nodeMatrix(node, t) {
|
|
3371
|
+
if (node.animate && node.animate.transform) return evalTransformValue(node.animate.transform, t);
|
|
3372
|
+
if (node.transform !== void 0) return evalTransformValue(node.transform, t);
|
|
3373
|
+
return IDENTITY;
|
|
3374
|
+
}
|
|
3375
|
+
function evalScalar(animated, staticVal, fallback, t) {
|
|
3376
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3377
|
+
if (animated && animated.keyframes && animated.keyframes.length) {
|
|
3378
|
+
const kfs = animated.keyframes;
|
|
3379
|
+
if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value;
|
|
3380
|
+
if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value;
|
|
3381
|
+
let i = 0;
|
|
3382
|
+
while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
|
|
3383
|
+
const a = kfs[i], b = kfs[i + 1];
|
|
3384
|
+
const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
|
|
3385
|
+
return lerp(a.value, b.value, f);
|
|
3386
|
+
}
|
|
3387
|
+
return staticVal !== void 0 ? Number(staticVal) : fallback;
|
|
3388
|
+
}
|
|
3389
|
+
var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
|
|
3390
|
+
var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
|
|
3391
|
+
function buildIdMap(node, map) {
|
|
3392
|
+
var _a;
|
|
3393
|
+
if (typeof node.id === "string") map.set(node.id, node);
|
|
3394
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => buildIdMap(c, map));
|
|
3395
|
+
}
|
|
3396
|
+
function num(v) {
|
|
3397
|
+
return v === void 0 || v === null ? 0 : Number(v);
|
|
3398
|
+
}
|
|
3399
|
+
function round(n) {
|
|
3400
|
+
return Math.round(n * 100) / 100 + 0;
|
|
3401
|
+
}
|
|
3402
|
+
function geomKey(node) {
|
|
3403
|
+
var _a;
|
|
3404
|
+
switch (node.type) {
|
|
3405
|
+
case "rect":
|
|
3406
|
+
return num(node.width) + "," + num(node.height) + "," + num(node.x) + "," + num(node.y);
|
|
3407
|
+
case "ellipse":
|
|
3408
|
+
return num(node.rx) + "," + num(node.ry) + "," + num(node.cx) + "," + num(node.cy);
|
|
3409
|
+
case "circle":
|
|
3410
|
+
return num(node.r) + "," + num(node.cx) + "," + num(node.cy);
|
|
3411
|
+
case "path":
|
|
3412
|
+
return String((_a = node.d) != null ? _a : "");
|
|
3413
|
+
default:
|
|
3414
|
+
return "";
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
function describePrimitive(node, m, t) {
|
|
3418
|
+
var _a, _b, _c, _d, _e;
|
|
3419
|
+
const fill = (_a = node.fill) != null ? _a : "";
|
|
3420
|
+
const stroke = (_b = node.stroke) != null ? _b : "";
|
|
3421
|
+
const sw = (_d = (_c = node["stroke-width"]) != null ? _c : node.strokeWidth) != null ? _d : "";
|
|
3422
|
+
const opacity = round(evalScalar((_e = node.animate) == null ? void 0 : _e.opacity, node.opacity, 1, t));
|
|
3423
|
+
const masked = node.mask ? 1 : 0;
|
|
3424
|
+
const mat = m.map(round).join(",");
|
|
3425
|
+
return node.type + "|" + geomKey(node) + "|[" + mat + "]|f:" + fill + "|s:" + stroke + "|sw:" + (num(sw) || "") + "|o:" + opacity + "|m:" + masked;
|
|
3426
|
+
}
|
|
3427
|
+
function flatten(node, parent, t, idMap, out) {
|
|
3428
|
+
var _a;
|
|
3429
|
+
const type = node.type || "";
|
|
3430
|
+
if (SKIP_TYPES.has(type)) return;
|
|
3431
|
+
const m = mul(parent, nodeMatrix(node, t));
|
|
3432
|
+
if (type === "use") {
|
|
3433
|
+
const targetId = typeof node.href === "string" ? node.href.replace(/^#/, "") : "";
|
|
3434
|
+
const target = idMap.get(targetId);
|
|
3435
|
+
const useM = mul(m, translateM(num(node.x), num(node.y)));
|
|
3436
|
+
if (target) flatten(target, useM, t, idMap, out);
|
|
3437
|
+
else out.push("UNRESOLVED_USE:#" + targetId);
|
|
3438
|
+
return;
|
|
3439
|
+
}
|
|
3440
|
+
if (CONTAINER_TYPES.has(type)) {
|
|
3441
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => flatten(c, m, t, idMap, out));
|
|
3442
|
+
return;
|
|
3443
|
+
}
|
|
3444
|
+
out.push(describePrimitive(node, m, t));
|
|
3445
|
+
}
|
|
3446
|
+
function collectSampleTimes(node, into) {
|
|
3447
|
+
var _a;
|
|
3448
|
+
into.add(0);
|
|
3449
|
+
const scanAnim = (anim) => {
|
|
3450
|
+
var _a2;
|
|
3451
|
+
if (!anim || typeof anim !== "object") return;
|
|
3452
|
+
for (const key of Object.keys(anim)) {
|
|
3453
|
+
const kfs = (_a2 = anim[key]) == null ? void 0 : _a2.keyframes;
|
|
3454
|
+
if (Array.isArray(kfs)) kfs.forEach((kf) => {
|
|
3455
|
+
var _a3;
|
|
3456
|
+
return into.add((_a3 = kf.time) != null ? _a3 : 0);
|
|
3457
|
+
});
|
|
3458
|
+
}
|
|
3459
|
+
};
|
|
3460
|
+
scanAnim(node.animate);
|
|
3461
|
+
if (node.transform && typeof node.transform === "object" && node.transform.keyframes) {
|
|
3462
|
+
node.transform.keyframes.forEach((kf) => {
|
|
3463
|
+
var _a2;
|
|
3464
|
+
return into.add((_a2 = kf.time) != null ? _a2 : 0);
|
|
3465
|
+
});
|
|
3466
|
+
}
|
|
3467
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => collectSampleTimes(c, into));
|
|
3468
|
+
}
|
|
3469
|
+
function visualModelAt(root, t) {
|
|
3470
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
3471
|
+
buildIdMap(root, idMap);
|
|
3472
|
+
const out = [];
|
|
3473
|
+
flatten(root, IDENTITY, t, idMap, out);
|
|
3474
|
+
return out.sort();
|
|
3475
|
+
}
|
|
3476
|
+
function diffInEffect(a, b) {
|
|
3477
|
+
const times = /* @__PURE__ */ new Set();
|
|
3478
|
+
collectSampleTimes(a, times);
|
|
3479
|
+
collectSampleTimes(b, times);
|
|
3480
|
+
const diffs = [];
|
|
3481
|
+
for (const t of Array.from(times).sort((x, y) => x - y)) {
|
|
3482
|
+
const ma = visualModelAt(a, t);
|
|
3483
|
+
const mb = visualModelAt(b, t);
|
|
3484
|
+
const onlyInA = subtractMultiset(ma, mb);
|
|
3485
|
+
const onlyInB = subtractMultiset(mb, ma);
|
|
3486
|
+
if (onlyInA.length || onlyInB.length) diffs.push({ time: t, onlyInA, onlyInB });
|
|
3487
|
+
}
|
|
3488
|
+
return diffs;
|
|
3489
|
+
}
|
|
3490
|
+
function subtractMultiset(a, b) {
|
|
3491
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3492
|
+
for (const x of b) counts.set(x, (counts.get(x) || 0) + 1);
|
|
3493
|
+
const extra = [];
|
|
3494
|
+
for (const x of a) {
|
|
3495
|
+
const c = counts.get(x) || 0;
|
|
3496
|
+
if (c > 0) counts.set(x, c - 1);
|
|
3497
|
+
else extra.push(x);
|
|
3498
|
+
}
|
|
3499
|
+
return extra;
|
|
3500
|
+
}
|
|
1678
3501
|
export {
|
|
1679
3502
|
COLOUR_ATTR_NAMES,
|
|
3503
|
+
PX_ANIMATOR_DATA_KEY,
|
|
1680
3504
|
PX_ANIM_ATTR_NAME,
|
|
1681
3505
|
PX_ANIM_SRC_ATTR_NAME,
|
|
3506
|
+
PX_TRANSFORM_PART_KEYS,
|
|
3507
|
+
PxAnimatedSvgDocumentSchema,
|
|
3508
|
+
PxAnimationDefinitionSchema,
|
|
3509
|
+
PxAnimatorConfigSchema,
|
|
3510
|
+
PxAttrValueSchema,
|
|
3511
|
+
PxBezierPathSchema,
|
|
3512
|
+
PxBindingSchema,
|
|
3513
|
+
PxDefsSchema,
|
|
3514
|
+
PxEasingOrRefSchema,
|
|
3515
|
+
PxEffectsSchema,
|
|
3516
|
+
PxElementAnimationSchema,
|
|
3517
|
+
PxKeyframeSchema,
|
|
3518
|
+
PxLoopSchema,
|
|
3519
|
+
PxMaskedByEffectSchema,
|
|
3520
|
+
PxNodeBase,
|
|
3521
|
+
PxNodeSchema,
|
|
3522
|
+
PxPropertyAnimationSchema,
|
|
3523
|
+
PxRefEffectSchema,
|
|
3524
|
+
PxRepeaterEffectSchema,
|
|
3525
|
+
PxRetimeEffectSchema,
|
|
3526
|
+
PxSvgNodeExtra,
|
|
3527
|
+
PxTransformPartsSchema,
|
|
3528
|
+
PxTransformValueSchema,
|
|
3529
|
+
PxTransformationEffectSchema,
|
|
3530
|
+
PxTriggerSchema,
|
|
3531
|
+
PxTrimPathEffectSchema,
|
|
1682
3532
|
STYLE_ATTR_NAMES,
|
|
1683
3533
|
TRANSFORM_FN_NAMES,
|
|
3534
|
+
applyPlayerEffects,
|
|
1684
3535
|
calcAnimationValues,
|
|
1685
3536
|
camelCaseToKebabWordIfNeeded,
|
|
3537
|
+
collectSampleTimes,
|
|
1686
3538
|
createAnimator,
|
|
1687
3539
|
createAnimatorImpl,
|
|
1688
3540
|
createBasicFrameLoopAnimator,
|
|
1689
3541
|
createFrameLoopAnimator,
|
|
1690
3542
|
createWebApiAnimator,
|
|
3543
|
+
describeSchema,
|
|
3544
|
+
diffInEffect,
|
|
1691
3545
|
generateNewIds,
|
|
1692
3546
|
getAnimatorConfig,
|
|
1693
3547
|
getBindings,
|
|
@@ -1698,8 +3552,12 @@ export {
|
|
|
1698
3552
|
isPxElementFileFormatDeep,
|
|
1699
3553
|
loadTagAnimators,
|
|
1700
3554
|
getNormalisedBindings as normalizeDocument,
|
|
3555
|
+
px,
|
|
1701
3556
|
renderNode,
|
|
3557
|
+
schemaKeys,
|
|
1702
3558
|
setupAnimationTriggers,
|
|
1703
|
-
toRGBA
|
|
3559
|
+
toRGBA,
|
|
3560
|
+
validateNodeEffects,
|
|
3561
|
+
visualModelAt
|
|
1704
3562
|
};
|
|
1705
3563
|
//# sourceMappingURL=index.js.map
|