@pixodesk/svg-animator-web 1.0.10 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +3694 -691
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4928 -198
- package/dist/index.d.ts +4928 -198
- package/dist/index.js +3638 -687
- 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 +3641 -690
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -50,17 +50,58 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
50
50
|
var index_exports = {};
|
|
51
51
|
__export(index_exports, {
|
|
52
52
|
COLOUR_ATTR_NAMES: () => COLOUR_ATTR_NAMES,
|
|
53
|
+
PX_ANIMATOR_DATA_KEY: () => PX_ANIMATOR_DATA_KEY,
|
|
53
54
|
PX_ANIM_ATTR_NAME: () => PX_ANIM_ATTR_NAME,
|
|
54
55
|
PX_ANIM_SRC_ATTR_NAME: () => PX_ANIM_SRC_ATTR_NAME,
|
|
56
|
+
PX_TRANSFORM_PART_KEYS: () => PX_TRANSFORM_PART_KEYS,
|
|
57
|
+
PxAnimatedSvgDocumentSchema: () => PxAnimatedSvgDocumentSchema,
|
|
58
|
+
PxAnimationDefinitionSchema: () => PxAnimationDefinitionSchema,
|
|
59
|
+
PxAnimatorConfigSchema: () => PxAnimatorConfigSchema,
|
|
60
|
+
PxAnimatorEngine: () => PxAnimatorEngine,
|
|
61
|
+
PxAnimatorMode: () => PxAnimatorMode,
|
|
62
|
+
PxAttrValueSchema: () => PxAttrValueSchema,
|
|
63
|
+
PxBezierPathSchema: () => PxBezierPathSchema,
|
|
64
|
+
PxBindingSchema: () => PxBindingSchema,
|
|
65
|
+
PxDefsSchema: () => PxDefsSchema,
|
|
66
|
+
PxEasingOrRefSchema: () => PxEasingOrRefSchema,
|
|
67
|
+
PxEffectsSchema: () => PxEffectsSchema,
|
|
68
|
+
PxElementAnimationSchema: () => PxElementAnimationSchema,
|
|
69
|
+
PxFillGradientEffectSchema: () => PxFillGradientEffectSchema,
|
|
70
|
+
PxGradientSpreadMethod: () => PxGradientSpreadMethod,
|
|
71
|
+
PxGradientStopSchema: () => PxGradientStopSchema,
|
|
72
|
+
PxGradientType: () => PxGradientType,
|
|
73
|
+
PxGradientUnits: () => PxGradientUnits,
|
|
74
|
+
PxKeyframeSchema: () => PxKeyframeSchema,
|
|
75
|
+
PxLoopSchema: () => PxLoopSchema,
|
|
76
|
+
PxMaskedByEffectSchema: () => PxMaskedByEffectSchema,
|
|
77
|
+
PxNodeBase: () => PxNodeBase,
|
|
78
|
+
PxNodeSchema: () => PxNodeSchema,
|
|
79
|
+
PxPropertyAnimationSchema: () => PxPropertyAnimationSchema,
|
|
80
|
+
PxRefEffectSchema: () => PxRefEffectSchema,
|
|
81
|
+
PxRepeaterEffectSchema: () => PxRepeaterEffectSchema,
|
|
82
|
+
PxRetimeEffectSchema: () => PxRetimeEffectSchema,
|
|
83
|
+
PxStrokeGradientEffectSchema: () => PxStrokeGradientEffectSchema,
|
|
84
|
+
PxSvgNodeExtra: () => PxSvgNodeExtra,
|
|
85
|
+
PxTextAlongPathEffectSchema: () => PxTextAlongPathEffectSchema,
|
|
86
|
+
PxTransformPartsSchema: () => PxTransformPartsSchema,
|
|
87
|
+
PxTransformValueSchema: () => PxTransformValueSchema,
|
|
88
|
+
PxTransformationEffectSchema: () => PxTransformationEffectSchema,
|
|
89
|
+
PxTriggerSchema: () => PxTriggerSchema,
|
|
90
|
+
PxTrimPathEffectSchema: () => PxTrimPathEffectSchema,
|
|
55
91
|
STYLE_ATTR_NAMES: () => STYLE_ATTR_NAMES,
|
|
56
92
|
TRANSFORM_FN_NAMES: () => TRANSFORM_FN_NAMES,
|
|
93
|
+
applyPlayerEffects: () => applyPlayerEffects,
|
|
57
94
|
calcAnimationValues: () => calcAnimationValues,
|
|
58
95
|
camelCaseToKebabWordIfNeeded: () => camelCaseToKebabWordIfNeeded,
|
|
96
|
+
collectSampleTimes: () => collectSampleTimes,
|
|
59
97
|
createAnimator: () => createAnimator,
|
|
60
98
|
createAnimatorImpl: () => createAnimatorImpl,
|
|
61
99
|
createBasicFrameLoopAnimator: () => createBasicFrameLoopAnimator,
|
|
62
100
|
createFrameLoopAnimator: () => createFrameLoopAnimator,
|
|
63
101
|
createWebApiAnimator: () => createWebApiAnimator,
|
|
102
|
+
describeSchema: () => describeSchema,
|
|
103
|
+
diffInEffect: () => diffInEffect,
|
|
104
|
+
evaluateMotionPathSegment: () => evaluateMotionPathSegment,
|
|
64
105
|
generateNewIds: () => generateNewIds,
|
|
65
106
|
getAnimatorConfig: () => getAnimatorConfig,
|
|
66
107
|
getBindings: () => getBindings,
|
|
@@ -70,288 +111,1088 @@ __export(index_exports, {
|
|
|
70
111
|
isPxElementFileFormat: () => isPxElementFileFormat,
|
|
71
112
|
isPxElementFileFormatDeep: () => isPxElementFileFormatDeep,
|
|
72
113
|
loadTagAnimators: () => loadTagAnimators,
|
|
114
|
+
materialiseAllInTree: () => materialiseAllInTree,
|
|
115
|
+
materialiseAnimatedUseInstances: () => materialiseAnimatedUseInstances,
|
|
116
|
+
materialiseInternalLoopsInPropAnim: () => materialiseInternalLoopsInPropAnim,
|
|
117
|
+
materialiseInternalLoopsInTree: () => materialiseInternalLoopsInTree,
|
|
118
|
+
materialiseMotionPathInPropAnim: () => materialiseMotionPathInPropAnim,
|
|
119
|
+
materialiseMotionPathsInTree: () => materialiseMotionPathsInTree,
|
|
73
120
|
normalizeDocument: () => getNormalisedBindings,
|
|
121
|
+
propAnimIsMotionPath: () => propAnimIsMotionPath,
|
|
122
|
+
px: () => px,
|
|
74
123
|
renderNode: () => renderNode,
|
|
124
|
+
schemaKeys: () => schemaKeys,
|
|
75
125
|
setupAnimationTriggers: () => setupAnimationTriggers,
|
|
76
|
-
toRGBA: () => toRGBA
|
|
126
|
+
toRGBA: () => toRGBA,
|
|
127
|
+
validateNodeEffects: () => validateNodeEffects,
|
|
128
|
+
visualModelAt: () => visualModelAt
|
|
77
129
|
});
|
|
78
130
|
module.exports = __toCommonJS(index_exports);
|
|
79
131
|
|
|
80
|
-
// src/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
|
|
99
|
-
return false;
|
|
132
|
+
// src/effects/transformParts.ts
|
|
133
|
+
function partsRecord(part, value, origin) {
|
|
134
|
+
const rec = {};
|
|
135
|
+
if (part === "translate" /* Translate */) rec.translate = value;
|
|
136
|
+
else if (part === "rotate" /* Rotate */) rec.rotate = value;
|
|
137
|
+
else rec.scale = value;
|
|
138
|
+
if (origin && part !== "translate" /* Translate */) rec.origin = origin;
|
|
139
|
+
return rec;
|
|
140
|
+
}
|
|
141
|
+
function readAnimatable(raw) {
|
|
142
|
+
if (raw === void 0) return { kind: "absent" /* Absent */ };
|
|
143
|
+
if (Array.isArray(raw)) return { kind: "static" /* Static */, value: raw };
|
|
144
|
+
if (typeof raw === "object") {
|
|
145
|
+
const obj = raw;
|
|
146
|
+
if (obj.keyframes) {
|
|
147
|
+
return { kind: "animated" /* Animated */, keyframes: obj.keyframes, autoOrient: obj.autoOrient };
|
|
148
|
+
}
|
|
149
|
+
if (obj.value !== void 0) return { kind: "static" /* Static */, value: obj.value };
|
|
100
150
|
}
|
|
101
|
-
return
|
|
151
|
+
return { kind: "static" /* Static */, value: raw };
|
|
102
152
|
}
|
|
103
|
-
function
|
|
104
|
-
|
|
153
|
+
function readStaticOrigin(raw, ctx) {
|
|
154
|
+
var _a;
|
|
155
|
+
const o = readAnimatable(raw);
|
|
156
|
+
if (o.kind === "absent" /* Absent */) return void 0;
|
|
157
|
+
if (o.kind === "static" /* Static */) return o.value;
|
|
158
|
+
ctx.warnings.push("transformation.origin: animated origin approximated by its first keyframe");
|
|
159
|
+
return (_a = o.keyframes[0]) == null ? void 0 : _a.value;
|
|
105
160
|
}
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
161
|
+
function keyframeWith(kf, value) {
|
|
162
|
+
const out = { value };
|
|
163
|
+
if (kf.time !== void 0) out.time = kf.time;
|
|
164
|
+
if (kf.easing !== void 0) out.easing = kf.easing;
|
|
165
|
+
if (kf.tangentOut !== void 0) out.tangentOut = kf.tangentOut;
|
|
166
|
+
if (kf.tangentIn !== void 0) out.tangentIn = kf.tangentIn;
|
|
167
|
+
return out;
|
|
110
168
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return
|
|
169
|
+
|
|
170
|
+
// src/effects/transformationEffect.ts
|
|
171
|
+
function applyTransformationEffect(node, fx, ctx) {
|
|
172
|
+
if (!fx) return node;
|
|
173
|
+
delete node.transform;
|
|
174
|
+
let n = node;
|
|
175
|
+
n = wrapTransformPart(n, "skew" /* Skew */, fx.skew, ctx);
|
|
176
|
+
n = wrapOrigin(
|
|
177
|
+
n,
|
|
178
|
+
fx.origin,
|
|
179
|
+
/*invert=*/
|
|
180
|
+
true
|
|
181
|
+
);
|
|
182
|
+
n = wrapTransformPart(n, "scale" /* Scale */, normalizeScale(fx.scale), ctx);
|
|
183
|
+
n = wrapTransformPart(n, "rotate" /* Rotate */, fx.rotate, ctx);
|
|
184
|
+
n = wrapOrigin(
|
|
185
|
+
n,
|
|
186
|
+
fx.origin,
|
|
187
|
+
/*invert=*/
|
|
188
|
+
false
|
|
189
|
+
);
|
|
190
|
+
if (translateHasAutoOrient(fx.translate)) {
|
|
191
|
+
n = wrapOrigin(
|
|
192
|
+
n,
|
|
193
|
+
fx.origin,
|
|
194
|
+
/*invert=*/
|
|
195
|
+
true
|
|
196
|
+
);
|
|
197
|
+
n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
|
|
198
|
+
n = wrapOrigin(
|
|
199
|
+
n,
|
|
200
|
+
fx.origin,
|
|
201
|
+
/*invert=*/
|
|
202
|
+
false
|
|
203
|
+
);
|
|
204
|
+
} else {
|
|
205
|
+
n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
|
|
206
|
+
}
|
|
207
|
+
return n;
|
|
115
208
|
}
|
|
116
|
-
function
|
|
117
|
-
if (typeof
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return
|
|
209
|
+
function translateHasAutoOrient(translate) {
|
|
210
|
+
if (!translate || typeof translate !== "object") return false;
|
|
211
|
+
const obj = translate;
|
|
212
|
+
if (obj.autoOrient) return true;
|
|
213
|
+
return Array.isArray(obj.keyframes) && obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
|
|
121
214
|
}
|
|
122
|
-
function
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
|
|
215
|
+
function normalizeScale(raw) {
|
|
216
|
+
if (raw === void 0) return void 0;
|
|
217
|
+
if (Array.isArray(raw)) return [raw[0] / 100, raw[1] / 100];
|
|
218
|
+
return raw;
|
|
219
|
+
}
|
|
220
|
+
function wrapTransformPart(inner, part, raw, ctx) {
|
|
221
|
+
if (raw === void 0) return inner;
|
|
222
|
+
if (part === "skew" /* Skew */) {
|
|
223
|
+
const skew = readAnimatable(raw);
|
|
224
|
+
if (skew.kind !== "static" /* Static */) {
|
|
225
|
+
ctx.warnings.push("transformation.skew: only static skew is supported");
|
|
226
|
+
return inner;
|
|
227
|
+
}
|
|
228
|
+
return { type: "g", transform: "skewX(" + skew.value[0] + ")skewY(" + skew.value[1] + ")", children: [inner] };
|
|
126
229
|
}
|
|
127
|
-
|
|
128
|
-
if (v.
|
|
129
|
-
|
|
130
|
-
valid = false;
|
|
230
|
+
const v = readAnimatable(raw);
|
|
231
|
+
if (v.kind === "static" /* Static */) {
|
|
232
|
+
return { type: "g", transform: { value: partsRecord(part, v.value, void 0) }, children: [inner] };
|
|
131
233
|
}
|
|
132
|
-
if (v.
|
|
133
|
-
|
|
134
|
-
|
|
234
|
+
if (v.kind === "animated" /* Animated */) {
|
|
235
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
|
|
236
|
+
if (v.autoOrient) animTr.autoOrient = true;
|
|
237
|
+
return {
|
|
238
|
+
type: "g",
|
|
239
|
+
animate: { transform: animTr },
|
|
240
|
+
children: [inner]
|
|
241
|
+
};
|
|
135
242
|
}
|
|
136
|
-
|
|
137
|
-
if (v.e !== void 0 && !validatePxEasingOrRef(v.e, path + ".e", errors)) valid = false;
|
|
138
|
-
return valid;
|
|
243
|
+
return inner;
|
|
139
244
|
}
|
|
140
|
-
function
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
|
|
245
|
+
function wrapOrigin(inner, raw, invert) {
|
|
246
|
+
if (raw === void 0) return inner;
|
|
247
|
+
const v = readAnimatable(raw);
|
|
248
|
+
const sign = (value) => invert ? [-value[0], -value[1]] : value;
|
|
249
|
+
if (v.kind === "absent" /* Absent */) return inner;
|
|
250
|
+
if (v.kind === "static" /* Static */) {
|
|
251
|
+
if (v.value[0] === 0 && v.value[1] === 0) return inner;
|
|
252
|
+
return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
|
|
144
253
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
254
|
+
if (v.kind === "animated" /* Animated */) {
|
|
255
|
+
return {
|
|
256
|
+
type: "g",
|
|
257
|
+
animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) } },
|
|
258
|
+
children: [inner]
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
return inner;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// src/effects/contentRefSplit.ts
|
|
265
|
+
function identifyContentRefTargets(node, ctx, allocator) {
|
|
266
|
+
var _a, _b, _c;
|
|
267
|
+
if (node.type === "use" && ((_b = (_a = node.effects) == null ? void 0 : _a.ref) == null ? void 0 : _b.type) === "content") {
|
|
268
|
+
const baseId = node.effects.ref.baseId;
|
|
269
|
+
if (typeof baseId === "string" && baseId && !ctx.contentRefInnerIds.has(baseId)) {
|
|
270
|
+
ctx.contentRefInnerIds.set(baseId, allocator(baseId));
|
|
154
271
|
}
|
|
155
272
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
273
|
+
(_c = node.children) == null ? void 0 : _c.forEach((c) => identifyContentRefTargets(c, ctx, allocator));
|
|
274
|
+
}
|
|
275
|
+
function splitForContentRef(node, transformation, originalId, innerId, ctx) {
|
|
276
|
+
const outerBody = liftBodyTranslate(node, transformation);
|
|
277
|
+
if (typeof node.id === "string") delete node.id;
|
|
278
|
+
const { outer: outerTr, inner: innerTr } = splitTransformationEffect(transformation);
|
|
279
|
+
let innerNode = node;
|
|
280
|
+
innerNode = applyTransformationEffect(innerNode, innerTr, ctx);
|
|
281
|
+
const innerWrapper = { type: "g", id: innerId, children: [innerNode] };
|
|
282
|
+
let outerWrapper = { type: "g", id: originalId, children: [innerWrapper] };
|
|
283
|
+
if (outerBody.transform !== void 0) outerWrapper.transform = outerBody.transform;
|
|
284
|
+
if (outerBody.animate !== void 0) outerWrapper.animate = outerBody.animate;
|
|
285
|
+
if (outerTr) {
|
|
286
|
+
delete outerWrapper.id;
|
|
287
|
+
outerWrapper = applyTransformationEffect(outerWrapper, outerTr, ctx);
|
|
288
|
+
outerWrapper.id = originalId;
|
|
289
|
+
}
|
|
290
|
+
return outerWrapper;
|
|
291
|
+
}
|
|
292
|
+
function liftBodyTranslate(node, transformation) {
|
|
293
|
+
var _a, _b, _c;
|
|
294
|
+
const out = {};
|
|
295
|
+
let didLiftAnimate = false;
|
|
296
|
+
const animTr = (_a = node.animate) == null ? void 0 : _a.transform;
|
|
297
|
+
if (animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes)) {
|
|
298
|
+
const kfs = animTr.keyframes;
|
|
299
|
+
const hasTranslate = kfs.some((kf) => kf.value && kf.value.translate);
|
|
300
|
+
if (hasTranslate) {
|
|
301
|
+
const outerHasOrigin = needsOriginOnOuter(animTr);
|
|
302
|
+
const outerKfs = kfs.map((kf) => {
|
|
303
|
+
const v = kf.value || {};
|
|
304
|
+
const newValue = {};
|
|
305
|
+
if (v.translate !== void 0) newValue.translate = v.translate;
|
|
306
|
+
if (outerHasOrigin && v.origin !== void 0) newValue.origin = v.origin;
|
|
307
|
+
const outerKf = { value: newValue };
|
|
308
|
+
if (kf.time !== void 0) outerKf.time = kf.time;
|
|
309
|
+
if (kf.easing !== void 0) outerKf.easing = kf.easing;
|
|
310
|
+
if (kf.tangentOut !== void 0) outerKf.tangentOut = kf.tangentOut;
|
|
311
|
+
if (kf.tangentIn !== void 0) outerKf.tangentIn = kf.tangentIn;
|
|
312
|
+
return outerKf;
|
|
313
|
+
});
|
|
314
|
+
const outerAnimTr = { keyframes: outerKfs };
|
|
315
|
+
if (animTr.autoOrient) outerAnimTr.autoOrient = true;
|
|
316
|
+
out.animate = { transform: outerAnimTr };
|
|
317
|
+
const innerHasPivotedPart = kfs.some((kf) => {
|
|
318
|
+
const v = kf.value || {};
|
|
319
|
+
return v.rotate !== void 0 || v.scale !== void 0;
|
|
163
320
|
});
|
|
321
|
+
const innerKfs = kfs.map((kf) => {
|
|
322
|
+
const v = kf.value || {};
|
|
323
|
+
const newValue = {};
|
|
324
|
+
if (v.rotate !== void 0) newValue.rotate = v.rotate;
|
|
325
|
+
if (v.scale !== void 0) newValue.scale = v.scale;
|
|
326
|
+
if (v.origin !== void 0 && (!outerHasOrigin || innerHasPivotedPart)) newValue.origin = v.origin;
|
|
327
|
+
const innerKf = { value: newValue };
|
|
328
|
+
if (kf.time !== void 0) innerKf.time = kf.time;
|
|
329
|
+
if (kf.easing !== void 0) innerKf.easing = kf.easing;
|
|
330
|
+
return innerKf;
|
|
331
|
+
});
|
|
332
|
+
const allInnerEmpty = innerKfs.every((kf) => Object.keys(kf.value).length === 0);
|
|
333
|
+
if (allInnerEmpty) {
|
|
334
|
+
delete node.animate.transform;
|
|
335
|
+
if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;
|
|
336
|
+
} else {
|
|
337
|
+
node.animate.transform = { keyframes: innerKfs };
|
|
338
|
+
}
|
|
339
|
+
didLiftAnimate = true;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const transformationHasTranslate = (transformation == null ? void 0 : transformation.translate) !== void 0;
|
|
343
|
+
const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
|
|
344
|
+
const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter(((_b = node.animate) == null ? void 0 : _b.transform) || void 0) || didLiftAnimate && needsOriginOnOuter(((_c = out.animate) == null ? void 0 : _c.transform) || void 0);
|
|
345
|
+
if (typeof node.transform === "string") {
|
|
346
|
+
const split = splitTransformString(node.transform);
|
|
347
|
+
if (stripBodyTranslateOnly) {
|
|
348
|
+
if (split.translate !== void 0) {
|
|
349
|
+
if (split.rest) node.transform = split.rest;
|
|
350
|
+
else delete node.transform;
|
|
351
|
+
} else if (isPureTranslateBody(node.transform)) {
|
|
352
|
+
delete node.transform;
|
|
353
|
+
} else if (liftedAnimateIsAutoOriented && isSingleMatrixBody(node.transform)) {
|
|
354
|
+
delete node.transform;
|
|
355
|
+
}
|
|
356
|
+
} else if (split.translate) {
|
|
357
|
+
out.transform = split.translate;
|
|
358
|
+
if (split.rest) node.transform = split.rest;
|
|
359
|
+
else delete node.transform;
|
|
164
360
|
}
|
|
165
361
|
}
|
|
166
|
-
return
|
|
362
|
+
return out;
|
|
167
363
|
}
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
364
|
+
function isSingleMatrixBody(s) {
|
|
365
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
366
|
+
let count = 0;
|
|
367
|
+
let isMatrix = false;
|
|
368
|
+
let m;
|
|
369
|
+
while (m = re.exec(s)) {
|
|
370
|
+
count++;
|
|
371
|
+
if (m[1] === "matrix") isMatrix = true;
|
|
372
|
+
}
|
|
373
|
+
return count === 1 && isMatrix;
|
|
374
|
+
}
|
|
375
|
+
function isPureTranslateBody(s) {
|
|
376
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
377
|
+
const ops = [];
|
|
378
|
+
let m;
|
|
379
|
+
while (m = re.exec(s)) ops.push({ name: m[1], full: m[0] });
|
|
380
|
+
if (ops.length !== 1) return false;
|
|
381
|
+
if (ops[0].name === "translate") return true;
|
|
382
|
+
if (ops[0].name !== "matrix") return false;
|
|
383
|
+
const args = /matrix\(([^)]*)\)/.exec(ops[0].full);
|
|
384
|
+
if (!args) return false;
|
|
385
|
+
const nums = args[1].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
386
|
+
return nums.length >= 4 && nums[0] === 1 && nums[1] === 0 && nums[2] === 0 && nums[3] === 1;
|
|
387
|
+
}
|
|
388
|
+
function splitTransformString(s) {
|
|
389
|
+
const ops = [];
|
|
390
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
391
|
+
let m;
|
|
392
|
+
while (m = re.exec(s)) ops.push({ name: m[1], full: m[0] });
|
|
393
|
+
if (!ops.length) return { rest: s || void 0 };
|
|
394
|
+
if (ops.every((o) => o.name === "translate")) {
|
|
395
|
+
return { translate: ops.map((o) => o.full).join("") };
|
|
172
396
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
397
|
+
const leading = ops[0];
|
|
398
|
+
const trailing = ops[ops.length - 1];
|
|
399
|
+
if (trailing.name === "translate" && leading.name === "translate") {
|
|
400
|
+
const trailingVec = parseTranslateArgs(trailing.full);
|
|
401
|
+
const leadingVec = parseTranslateArgs(leading.full);
|
|
402
|
+
const ox = -trailingVec[0];
|
|
403
|
+
const oy = -trailingVec[1];
|
|
404
|
+
const userTx = leadingVec[0] - ox;
|
|
405
|
+
const userTy = leadingVec[1] - oy;
|
|
406
|
+
if (userTx === 0 && userTy === 0) return { rest: s };
|
|
407
|
+
const middleAndTrailing = "translate(" + ox + "," + oy + ")" + ops.slice(1).map((o) => o.full).join("");
|
|
408
|
+
return { translate: "translate(" + userTx + "," + userTy + ")", rest: middleAndTrailing };
|
|
176
409
|
}
|
|
177
|
-
return
|
|
410
|
+
if (trailing.name === "translate") return { rest: s };
|
|
411
|
+
const lifted = [];
|
|
412
|
+
let i = 0;
|
|
413
|
+
while (i < ops.length && ops[i].name === "translate") {
|
|
414
|
+
lifted.push(ops[i].full);
|
|
415
|
+
i++;
|
|
416
|
+
}
|
|
417
|
+
if (!lifted.length) return { rest: s };
|
|
418
|
+
const rest = ops.slice(i).map((o) => o.full).join("");
|
|
419
|
+
return {
|
|
420
|
+
translate: lifted.join(""),
|
|
421
|
+
rest: rest || void 0
|
|
422
|
+
};
|
|
178
423
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
424
|
+
function parseTranslateArgs(translateOp) {
|
|
425
|
+
const m = /translate\(([^)]*)\)/.exec(translateOp);
|
|
426
|
+
if (!m) return [0, 0];
|
|
427
|
+
const nums = m[1].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
428
|
+
return [nums[0] || 0, nums[1] || 0];
|
|
429
|
+
}
|
|
430
|
+
function splitTransformationEffect(fx) {
|
|
431
|
+
if (!fx) return {};
|
|
432
|
+
const originOnOuter = needsOriginOnOuter(fx.translate);
|
|
433
|
+
const innerHasPivotedPart = fx.rotate !== void 0 || fx.scale !== void 0;
|
|
434
|
+
const outer = {};
|
|
435
|
+
const inner = {};
|
|
436
|
+
if (fx.translate !== void 0) outer.translate = fx.translate;
|
|
437
|
+
if (originOnOuter && fx.origin !== void 0) outer.origin = fx.origin;
|
|
438
|
+
if (fx.rotate !== void 0) inner.rotate = fx.rotate;
|
|
439
|
+
if (fx.scale !== void 0) inner.scale = fx.scale;
|
|
440
|
+
if (fx.skew !== void 0) inner.skew = fx.skew;
|
|
441
|
+
if (fx.origin !== void 0 && (!originOnOuter || innerHasPivotedPart)) inner.origin = fx.origin;
|
|
442
|
+
return {
|
|
443
|
+
outer: Object.keys(outer).length ? outer : void 0,
|
|
444
|
+
inner: Object.keys(inner).length ? inner : void 0
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
function needsOriginOnOuter(translateAnim) {
|
|
448
|
+
if (!translateAnim || typeof translateAnim !== "object") return false;
|
|
449
|
+
const obj = translateAnim;
|
|
450
|
+
if (obj.autoOrient) return true;
|
|
451
|
+
if (Array.isArray(obj.keyframes)) {
|
|
452
|
+
return obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
|
|
189
453
|
}
|
|
190
|
-
if (isObject(v)) return validatePxAnimationDefinition(v, path, errors);
|
|
191
|
-
errors.push(path + ": expected string, array, or PxAnimationDefinition object");
|
|
192
454
|
return false;
|
|
193
455
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
456
|
+
|
|
457
|
+
// src/PxSchema.ts
|
|
458
|
+
function pathStr(path) {
|
|
459
|
+
if (!path.length) return ".";
|
|
460
|
+
let result = "";
|
|
461
|
+
for (const seg of path) {
|
|
462
|
+
if (seg.startsWith("[")) result += seg;
|
|
463
|
+
else result += (result ? "." : "") + seg;
|
|
464
|
+
}
|
|
465
|
+
return result;
|
|
466
|
+
}
|
|
467
|
+
var Base = class {
|
|
468
|
+
_canSanitize(raw) {
|
|
469
|
+
return this.isValid(raw);
|
|
470
|
+
}
|
|
471
|
+
optional() {
|
|
472
|
+
return new Optional(this);
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
var Optional = class extends Base {
|
|
476
|
+
constructor(inner) {
|
|
477
|
+
super();
|
|
478
|
+
this.inner = inner;
|
|
479
|
+
this._default = void 0;
|
|
480
|
+
}
|
|
481
|
+
sanitize(raw) {
|
|
482
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
483
|
+
return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
|
|
484
|
+
}
|
|
485
|
+
isValid(raw, ctx, path) {
|
|
486
|
+
if (raw === void 0 || raw === null) return true;
|
|
487
|
+
return this.inner.isValid(raw, ctx, path);
|
|
488
|
+
}
|
|
489
|
+
_canSanitize(raw) {
|
|
490
|
+
return raw === void 0 || raw === null || this.inner._canSanitize(raw);
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
var Str = class extends Base {
|
|
494
|
+
constructor(_default = "") {
|
|
495
|
+
super();
|
|
496
|
+
this._default = _default;
|
|
497
|
+
}
|
|
498
|
+
sanitize(raw) {
|
|
499
|
+
return typeof raw === "string" ? raw : this._default;
|
|
500
|
+
}
|
|
501
|
+
isValid(raw, ctx, path) {
|
|
502
|
+
if (typeof raw === "string") return true;
|
|
503
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected string, got " + typeof raw);
|
|
197
504
|
return false;
|
|
198
505
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
506
|
+
};
|
|
507
|
+
var Num = class extends Base {
|
|
508
|
+
constructor(_default = 0) {
|
|
509
|
+
super();
|
|
510
|
+
this._default = _default;
|
|
511
|
+
}
|
|
512
|
+
sanitize(raw) {
|
|
513
|
+
return typeof raw === "number" && isFinite(raw) ? raw : this._default;
|
|
204
514
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
515
|
+
isValid(raw, ctx, path) {
|
|
516
|
+
if (typeof raw === "number" && isFinite(raw)) return true;
|
|
517
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected finite number, got " + JSON.stringify(raw));
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
var Bool = class extends Base {
|
|
522
|
+
constructor(_default = false) {
|
|
523
|
+
super();
|
|
524
|
+
this._default = _default;
|
|
211
525
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
valid = false;
|
|
526
|
+
sanitize(raw) {
|
|
527
|
+
return typeof raw === "boolean" ? raw : this._default;
|
|
215
528
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (!isObject(v)) {
|
|
220
|
-
errors.push(path + ": expected object");
|
|
529
|
+
isValid(raw, ctx, path) {
|
|
530
|
+
if (typeof raw === "boolean") return true;
|
|
531
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected boolean, got " + typeof raw);
|
|
221
532
|
return false;
|
|
222
533
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
534
|
+
};
|
|
535
|
+
var Literal = class extends Base {
|
|
536
|
+
constructor(value) {
|
|
537
|
+
super();
|
|
538
|
+
this.value = value;
|
|
539
|
+
this._default = value;
|
|
227
540
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
valid = false;
|
|
541
|
+
sanitize(raw) {
|
|
542
|
+
return raw === this.value ? this.value : this._default;
|
|
231
543
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
544
|
+
isValid(raw, ctx, path) {
|
|
545
|
+
if (raw === this.value) return true;
|
|
546
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected " + JSON.stringify(this.value) + ", got " + JSON.stringify(raw));
|
|
547
|
+
return false;
|
|
235
548
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
549
|
+
};
|
|
550
|
+
var Enum = class extends Base {
|
|
551
|
+
constructor(values, defaultVal) {
|
|
552
|
+
super();
|
|
553
|
+
this.values = values;
|
|
554
|
+
this._default = defaultVal != null ? defaultVal : values[0];
|
|
239
555
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (v.frameRate !== void 0 && typeof v.frameRate !== "number") {
|
|
243
|
-
errors.push(path + ".frameRate: expected number, got " + typeof v.frameRate);
|
|
244
|
-
valid = false;
|
|
556
|
+
sanitize(raw) {
|
|
557
|
+
return this.values.includes(raw) ? raw : this._default;
|
|
245
558
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
function validatePxDefs(v, path, errors) {
|
|
250
|
-
if (!isObject(v)) {
|
|
251
|
-
errors.push(path + ": expected object");
|
|
559
|
+
isValid(raw, ctx, path) {
|
|
560
|
+
if (this.values.includes(raw)) return true;
|
|
561
|
+
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));
|
|
252
562
|
return false;
|
|
253
563
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
564
|
+
};
|
|
565
|
+
var Union = class extends Base {
|
|
566
|
+
constructor(schemas, defaultVal) {
|
|
567
|
+
super();
|
|
568
|
+
this.schemas = schemas;
|
|
569
|
+
this._default = defaultVal != null ? defaultVal : schemas[0]._default;
|
|
570
|
+
}
|
|
571
|
+
sanitize(raw) {
|
|
572
|
+
for (const s of this.schemas) {
|
|
573
|
+
if (s.isValid(raw)) return s.sanitize(raw);
|
|
574
|
+
}
|
|
575
|
+
return this._default;
|
|
576
|
+
}
|
|
577
|
+
isValid(raw, ctx, path) {
|
|
578
|
+
var _a;
|
|
579
|
+
if (this.schemas.some((s) => s.isValid(raw))) return true;
|
|
580
|
+
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));
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
_canSanitize(raw) {
|
|
584
|
+
return this.schemas.some((s) => s._canSanitize(raw));
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
var DiscriminatedUnion = class extends Base {
|
|
588
|
+
constructor(_key, _schemas, defaultVal) {
|
|
589
|
+
super();
|
|
590
|
+
this._key = _key;
|
|
591
|
+
this._schemas = _schemas;
|
|
592
|
+
this._default = defaultVal != null ? defaultVal : _schemas[0]._default;
|
|
593
|
+
this._map = /* @__PURE__ */ new Map();
|
|
594
|
+
for (const s of _schemas) {
|
|
595
|
+
const keySchema = s._shape[_key];
|
|
596
|
+
if (keySchema) this._map.set(keySchema._default, s);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
_findSchema(raw) {
|
|
600
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
601
|
+
const val = raw[this._key];
|
|
602
|
+
if (val === void 0 || val === null) return void 0;
|
|
603
|
+
return this._map.get(val);
|
|
604
|
+
}
|
|
605
|
+
sanitize(raw) {
|
|
606
|
+
var _a;
|
|
607
|
+
return ((_a = this._findSchema(raw)) != null ? _a : this._schemas[0]).sanitize(raw);
|
|
608
|
+
}
|
|
609
|
+
isValid(raw, ctx, path) {
|
|
610
|
+
const schema = this._findSchema(raw);
|
|
611
|
+
if (!schema) {
|
|
612
|
+
const val = raw !== null && typeof raw === "object" && !Array.isArray(raw) ? raw[this._key] : void 0;
|
|
613
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no discriminated union member matched " + this._key + "=" + JSON.stringify(val));
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
return schema.isValid(raw, ctx, path);
|
|
617
|
+
}
|
|
618
|
+
_canSanitize(raw) {
|
|
619
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return false;
|
|
620
|
+
const schema = this._findSchema(raw);
|
|
621
|
+
return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
var Obj = class extends Base {
|
|
625
|
+
constructor(_shape) {
|
|
626
|
+
super();
|
|
627
|
+
this._shape = _shape;
|
|
628
|
+
const d = {};
|
|
629
|
+
for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
|
|
630
|
+
this._default = d;
|
|
631
|
+
}
|
|
632
|
+
sanitize(raw) {
|
|
633
|
+
const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
634
|
+
const out = {};
|
|
635
|
+
for (const key of Object.keys(this._shape)) {
|
|
636
|
+
out[key] = this._shape[key].sanitize(src[key]);
|
|
637
|
+
}
|
|
638
|
+
return out;
|
|
639
|
+
}
|
|
640
|
+
isValid(raw, ctx, path) {
|
|
641
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
642
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
const obj = raw;
|
|
646
|
+
const p = path != null ? path : [];
|
|
647
|
+
let ok = true;
|
|
648
|
+
for (const key of Object.keys(this._shape)) {
|
|
649
|
+
p.push(key);
|
|
650
|
+
if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;
|
|
651
|
+
p.pop();
|
|
652
|
+
}
|
|
653
|
+
if (ctx == null ? void 0 : ctx.strict) {
|
|
654
|
+
for (const key of Object.keys(obj)) {
|
|
655
|
+
if (key in this._shape) continue;
|
|
656
|
+
p.push(key);
|
|
657
|
+
ctx.errors.push(pathStr(p) + ": unexpected extra key");
|
|
658
|
+
p.pop();
|
|
659
|
+
ok = false;
|
|
262
660
|
}
|
|
263
661
|
}
|
|
662
|
+
return ok;
|
|
264
663
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
664
|
+
_canSanitize(raw) {
|
|
665
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
var OpenObj = class extends Base {
|
|
669
|
+
constructor(_shape, _openSchema) {
|
|
670
|
+
super();
|
|
671
|
+
this._shape = _shape;
|
|
672
|
+
this._openSchema = _openSchema;
|
|
673
|
+
const d = {};
|
|
674
|
+
for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
|
|
675
|
+
this._default = d;
|
|
676
|
+
}
|
|
677
|
+
sanitize(raw) {
|
|
678
|
+
const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
679
|
+
const out = __spreadValues({}, src);
|
|
680
|
+
for (const key of Object.keys(this._shape)) {
|
|
681
|
+
out[key] = this._shape[key].sanitize(src[key]);
|
|
682
|
+
}
|
|
683
|
+
if (this._openSchema) {
|
|
684
|
+
for (const key of Object.keys(src)) {
|
|
685
|
+
if (!(key in this._shape)) out[key] = this._openSchema.sanitize(src[key]);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
return out;
|
|
689
|
+
}
|
|
690
|
+
isValid(raw, ctx, path) {
|
|
691
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
692
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
693
|
+
return false;
|
|
694
|
+
}
|
|
695
|
+
const obj = raw;
|
|
696
|
+
const p = path != null ? path : [];
|
|
697
|
+
let ok = true;
|
|
698
|
+
for (const key of Object.keys(this._shape)) {
|
|
699
|
+
p.push(key);
|
|
700
|
+
if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;
|
|
701
|
+
p.pop();
|
|
702
|
+
}
|
|
703
|
+
if (this._openSchema) {
|
|
704
|
+
for (const key of Object.keys(obj)) {
|
|
705
|
+
if (key in this._shape) continue;
|
|
706
|
+
p.push(key);
|
|
707
|
+
if (!this._openSchema.isValid(obj[key], ctx, p)) ok = false;
|
|
708
|
+
p.pop();
|
|
272
709
|
}
|
|
273
710
|
}
|
|
711
|
+
return ok;
|
|
274
712
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
valid = false;
|
|
713
|
+
_canSanitize(raw) {
|
|
714
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
278
715
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
716
|
+
};
|
|
717
|
+
var Arr = class extends Base {
|
|
718
|
+
constructor(item) {
|
|
719
|
+
super();
|
|
720
|
+
this.item = item;
|
|
721
|
+
this._default = [];
|
|
285
722
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
723
|
+
sanitize(raw) {
|
|
724
|
+
if (!Array.isArray(raw)) return [];
|
|
725
|
+
const out = [];
|
|
726
|
+
for (const el of raw) {
|
|
727
|
+
if (this.item._canSanitize(el)) out.push(this.item.sanitize(el));
|
|
728
|
+
}
|
|
729
|
+
return out;
|
|
290
730
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
731
|
+
isValid(raw, ctx, path) {
|
|
732
|
+
if (!Array.isArray(raw)) {
|
|
733
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected array, got " + typeof raw);
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
const p = path != null ? path : [];
|
|
737
|
+
let ok = true;
|
|
738
|
+
for (let i = 0; i < raw.length; i++) {
|
|
739
|
+
p.push("[" + i + "]");
|
|
740
|
+
if (!this.item.isValid(raw[i], ctx, p)) ok = false;
|
|
741
|
+
p.pop();
|
|
742
|
+
}
|
|
743
|
+
return ok;
|
|
298
744
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
errors.push(path + ".type: expected string, got " + typeof v.type);
|
|
302
|
-
valid = false;
|
|
745
|
+
_canSanitize(raw) {
|
|
746
|
+
return Array.isArray(raw);
|
|
303
747
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
748
|
+
};
|
|
749
|
+
var Rec = class extends Base {
|
|
750
|
+
constructor(value) {
|
|
751
|
+
super();
|
|
752
|
+
this.value = value;
|
|
753
|
+
this._default = {};
|
|
754
|
+
}
|
|
755
|
+
sanitize(raw) {
|
|
756
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
757
|
+
const out = {};
|
|
758
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
759
|
+
if (this.value._canSanitize(v)) out[k] = this.value.sanitize(v);
|
|
312
760
|
}
|
|
761
|
+
return out;
|
|
313
762
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
763
|
+
isValid(raw, ctx, path) {
|
|
764
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
765
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object/record, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
766
|
+
return false;
|
|
767
|
+
}
|
|
768
|
+
const p = path != null ? path : [];
|
|
769
|
+
let ok = true;
|
|
770
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
771
|
+
p.push(k);
|
|
772
|
+
if (!this.value.isValid(v, ctx, p)) ok = false;
|
|
773
|
+
p.pop();
|
|
774
|
+
}
|
|
775
|
+
return ok;
|
|
323
776
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
valid = false;
|
|
777
|
+
_canSanitize(raw) {
|
|
778
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
327
779
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
780
|
+
};
|
|
781
|
+
var Any = class extends Base {
|
|
782
|
+
constructor() {
|
|
783
|
+
super(...arguments);
|
|
784
|
+
this._default = void 0;
|
|
331
785
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
valid = false;
|
|
786
|
+
sanitize(raw) {
|
|
787
|
+
return raw;
|
|
335
788
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
789
|
+
isValid(_raw, _ctx, _path) {
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
792
|
+
_canSanitize(_raw) {
|
|
793
|
+
return true;
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
var Lazy = class extends Base {
|
|
797
|
+
constructor(fn, _default) {
|
|
798
|
+
super();
|
|
799
|
+
this.fn = fn;
|
|
800
|
+
this._default = _default;
|
|
801
|
+
this.resolved = null;
|
|
802
|
+
}
|
|
803
|
+
get schema() {
|
|
804
|
+
var _a;
|
|
805
|
+
return (_a = this.resolved) != null ? _a : this.resolved = this.fn();
|
|
806
|
+
}
|
|
807
|
+
sanitize(raw) {
|
|
808
|
+
return this.schema.sanitize(raw);
|
|
809
|
+
}
|
|
810
|
+
isValid(raw, ctx, path) {
|
|
811
|
+
return this.schema.isValid(raw, ctx, path);
|
|
812
|
+
}
|
|
813
|
+
_canSanitize(raw) {
|
|
814
|
+
return this.schema._canSanitize(raw);
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
var Tuple = class extends Base {
|
|
818
|
+
constructor(schemas) {
|
|
819
|
+
super();
|
|
820
|
+
this.schemas = schemas;
|
|
821
|
+
this._default = schemas.map((s) => s._default);
|
|
822
|
+
}
|
|
823
|
+
sanitize(raw) {
|
|
824
|
+
if (!Array.isArray(raw) || raw.length !== this.schemas.length) return this._default;
|
|
825
|
+
return this.schemas.map((s, i) => s.sanitize(raw[i]));
|
|
826
|
+
}
|
|
827
|
+
isValid(raw, ctx, path) {
|
|
828
|
+
if (!Array.isArray(raw) || raw.length !== this.schemas.length) {
|
|
829
|
+
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));
|
|
830
|
+
return false;
|
|
831
|
+
}
|
|
832
|
+
const p = path != null ? path : [];
|
|
833
|
+
let ok = true;
|
|
834
|
+
for (let i = 0; i < this.schemas.length; i++) {
|
|
835
|
+
p.push("[" + i + "]");
|
|
836
|
+
if (!this.schemas[i].isValid(raw[i], ctx, p)) ok = false;
|
|
837
|
+
p.pop();
|
|
838
|
+
}
|
|
839
|
+
return ok;
|
|
840
|
+
}
|
|
841
|
+
// Require exact length so wrong-length arrays are dropped rather than repaired to default.
|
|
842
|
+
_canSanitize(raw) {
|
|
843
|
+
return Array.isArray(raw) && raw.length === this.schemas.length;
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
function implementsInterface() {
|
|
847
|
+
return (schema) => schema;
|
|
848
|
+
}
|
|
849
|
+
function schemaKeys(schema) {
|
|
850
|
+
return Object.fromEntries(
|
|
851
|
+
Object.keys(schema["_shape"]).map((k) => [k, k])
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
function describeSchema(schema) {
|
|
855
|
+
var _a;
|
|
856
|
+
const s = schema;
|
|
857
|
+
if ("_shape" in s) return { kind: "shape", shape: s._shape };
|
|
858
|
+
if ("item" in s) return { kind: "array", item: s.item };
|
|
859
|
+
if ("inner" in s) return { kind: "optional", inner: s.inner };
|
|
860
|
+
if ("fn" in s) return { kind: "lazy", resolved: (_a = s.resolved) != null ? _a : s.fn() };
|
|
861
|
+
return { kind: "leaf" };
|
|
862
|
+
}
|
|
863
|
+
var px = {
|
|
864
|
+
/** Matches a string. Default: '' or provided value. */
|
|
865
|
+
string: (defaultVal = "") => new Str(defaultVal),
|
|
866
|
+
/** Matches a finite number. Default: 0 or provided value. */
|
|
867
|
+
number: (defaultVal = 0) => new Num(defaultVal),
|
|
868
|
+
/** Matches a boolean. Default: false or provided value. */
|
|
869
|
+
boolean: (defaultVal = false) => new Bool(defaultVal),
|
|
870
|
+
/** Matches one exact primitive value; its default is the value itself. */
|
|
871
|
+
literal: (value) => new Literal(value),
|
|
872
|
+
/** Matches one of a fixed set of string/number values. Default: first value. */
|
|
873
|
+
enum: (values, defaultVal) => new Enum(values, defaultVal),
|
|
874
|
+
/**
|
|
875
|
+
* Returns the first schema whose isValid passes.
|
|
876
|
+
* TypeScript infers the union of all member types automatically.
|
|
877
|
+
*/
|
|
878
|
+
union: (schemas, defaultVal) => new Union(schemas, defaultVal),
|
|
879
|
+
/**
|
|
880
|
+
* Discriminated union — reads `raw[key]`, finds the member schema whose
|
|
881
|
+
* literal at `key` matches, then delegates sanitize/isValid to that member.
|
|
882
|
+
* Each member must be an object schema with a `px.literal(...)` at `key`.
|
|
883
|
+
* TypeScript infers the union of all member types automatically.
|
|
884
|
+
*/
|
|
885
|
+
discriminatedUnion: (key, schemas) => new DiscriminatedUnion(key, schemas),
|
|
886
|
+
/** Typed object — unknown keys are stripped. Required fields fall back to their default. */
|
|
887
|
+
object: (shape) => new Obj(shape),
|
|
888
|
+
/**
|
|
889
|
+
* Open object — validates known keys; passes unknown keys through as-is,
|
|
890
|
+
* or validates/sanitizes them against `openSchema` when provided.
|
|
891
|
+
*/
|
|
892
|
+
openObject: (shape, openSchema) => new OpenObj(shape, openSchema),
|
|
893
|
+
/**
|
|
894
|
+
* Creates a new closed object schema by merging a base schema's shape with additional fields.
|
|
895
|
+
* The base can be the result of px.object() or px.openObject() — anything with a _shape property.
|
|
896
|
+
*
|
|
897
|
+
* @example
|
|
898
|
+
* const PxSvgNodeSchema = px.extendedObject(PxNodeBase, { width: px.number().optional() });
|
|
899
|
+
*/
|
|
900
|
+
extendedObject: (base, extra) => new Obj(__spreadValues(__spreadValues({}, base._shape), extra)),
|
|
901
|
+
/** Array whose unrecoverable items are filtered out. Default: []. */
|
|
902
|
+
array: (item) => new Arr(item),
|
|
903
|
+
/** String-keyed record whose unrecoverable values are dropped. Default: {}. */
|
|
904
|
+
record: (value) => new Rec(value),
|
|
905
|
+
/** Passes anything through unchanged — always valid. */
|
|
906
|
+
any: () => new Any(),
|
|
907
|
+
/** Fixed-length tuple — validates element count and each position individually. */
|
|
908
|
+
tuple: (schemas) => new Tuple(schemas),
|
|
909
|
+
/** Defers schema creation — required for recursive types. Must supply a default value. */
|
|
910
|
+
lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
|
|
911
|
+
};
|
|
912
|
+
|
|
913
|
+
// src/PxAnimatorTypes.ts
|
|
914
|
+
var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
|
|
915
|
+
var PX_ANIM_ATTR_NAME = "_px_animator";
|
|
916
|
+
var PxAnimatorMode = {
|
|
917
|
+
auto: "auto",
|
|
918
|
+
webapi: "webapi",
|
|
919
|
+
frames: "frames"
|
|
920
|
+
};
|
|
921
|
+
var PxAnimatorEngine = {
|
|
922
|
+
webapi: PxAnimatorMode.webapi,
|
|
923
|
+
frames: PxAnimatorMode.frames
|
|
924
|
+
};
|
|
925
|
+
var TEXT_ATTR = "text";
|
|
926
|
+
var TEXT_CONTENT_ATTR = "textContent";
|
|
927
|
+
var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
|
|
928
|
+
"type",
|
|
929
|
+
"children",
|
|
930
|
+
"animator",
|
|
931
|
+
"meta",
|
|
932
|
+
"animate",
|
|
933
|
+
TEXT_ATTR,
|
|
934
|
+
TEXT_CONTENT_ATTR
|
|
935
|
+
]);
|
|
936
|
+
var PxEasingOrRefSchema = px.union([
|
|
937
|
+
px.string(),
|
|
938
|
+
px.tuple([px.number(), px.number(), px.number(), px.number()])
|
|
939
|
+
]);
|
|
940
|
+
var PxKeyframeValueSchema = implementsInterface()(px.union([
|
|
941
|
+
px.string(),
|
|
942
|
+
// e.g. for colors
|
|
943
|
+
px.number(),
|
|
944
|
+
px.array(px.number()),
|
|
945
|
+
px.lazy(() => PxTransformPartsSchema, {}),
|
|
946
|
+
px.object({ path: px.string() }),
|
|
947
|
+
px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] })
|
|
948
|
+
]));
|
|
949
|
+
var PxKeyframeSchema = implementsInterface()(px.object({
|
|
950
|
+
time: px.number().optional(),
|
|
951
|
+
t: px.number().optional(),
|
|
952
|
+
value: px.any().optional(),
|
|
953
|
+
v: px.any().optional(),
|
|
954
|
+
easing: PxEasingOrRefSchema.optional(),
|
|
955
|
+
e: PxEasingOrRefSchema.optional(),
|
|
956
|
+
tangentOut: px.tuple([px.number(), px.number()]).optional(),
|
|
957
|
+
to: px.tuple([px.number(), px.number()]).optional(),
|
|
958
|
+
// short alias
|
|
959
|
+
tangentIn: px.tuple([px.number(), px.number()]).optional(),
|
|
960
|
+
ti: px.tuple([px.number(), px.number()]).optional(),
|
|
961
|
+
// short alias
|
|
962
|
+
selected: px.boolean().optional()
|
|
963
|
+
// editor-side UI state (Player ignores it)
|
|
964
|
+
}));
|
|
965
|
+
var PxLoopSchema = implementsInterface()(px.object({
|
|
966
|
+
segmentCount: px.number().optional(),
|
|
967
|
+
before: px.boolean().optional(),
|
|
968
|
+
alternate: px.boolean().optional()
|
|
969
|
+
}));
|
|
970
|
+
var PxPropertyAnimationSchema = implementsInterface()(px.object({
|
|
971
|
+
keyframes: px.array(PxKeyframeSchema).optional(),
|
|
972
|
+
kfs: px.array(PxKeyframeSchema).optional(),
|
|
973
|
+
loop: px.union([PxLoopSchema, px.boolean()]).optional(),
|
|
974
|
+
autoOrient: px.boolean().optional()
|
|
975
|
+
}));
|
|
976
|
+
var PX_TRANSFORM_PART_KEYS = ["translate", "rotate", "scale", "origin"];
|
|
977
|
+
var PxTransformPartsSchema = implementsInterface()(px.object({
|
|
978
|
+
translate: px.tuple([px.number(), px.number()]).optional(),
|
|
979
|
+
rotate: px.number().optional(),
|
|
980
|
+
scale: px.tuple([px.number(), px.number()]).optional(),
|
|
981
|
+
origin: px.tuple([px.number(), px.number()]).optional()
|
|
982
|
+
}));
|
|
983
|
+
var PxTransformValueSchema = px.union([
|
|
984
|
+
px.string(),
|
|
985
|
+
px.object({ value: PxTransformPartsSchema }),
|
|
986
|
+
PxPropertyAnimationSchema
|
|
987
|
+
]);
|
|
988
|
+
var PxAnimationDefinitionSchema = implementsInterface()(
|
|
989
|
+
px.record(PxPropertyAnimationSchema)
|
|
990
|
+
);
|
|
991
|
+
var PxElementAnimationSchema = implementsInterface()(px.union([
|
|
992
|
+
px.string(),
|
|
993
|
+
px.array(px.union([px.string(), PxAnimationDefinitionSchema])),
|
|
994
|
+
PxAnimationDefinitionSchema
|
|
995
|
+
]));
|
|
996
|
+
var PxTriggerSchema = implementsInterface()(px.object({
|
|
997
|
+
startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
|
|
998
|
+
outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
|
|
999
|
+
scrollIntoViewThreshold: px.number().optional()
|
|
1000
|
+
}));
|
|
1001
|
+
var PxDefsSchema = implementsInterface()(px.object({
|
|
1002
|
+
easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
|
|
1003
|
+
animations: px.record(PxAnimationDefinitionSchema).optional(),
|
|
1004
|
+
styles: px.record(px.any()).optional()
|
|
1005
|
+
}));
|
|
1006
|
+
var PxAnimatorConfigSchema = implementsInterface()(px.object({
|
|
1007
|
+
mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
|
|
1008
|
+
duration: px.number().optional(),
|
|
1009
|
+
delay: px.number().optional(),
|
|
1010
|
+
iterations: px.union([px.number(), px.literal("infinite")]).optional(),
|
|
1011
|
+
fill: px.enum(["forwards", "backwards", "both", "none"]).optional(),
|
|
1012
|
+
direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional(),
|
|
1013
|
+
frameRate: px.number().optional(),
|
|
1014
|
+
trigger: PxTriggerSchema.optional(),
|
|
1015
|
+
definitions: PxDefsSchema.optional(),
|
|
1016
|
+
animate: px.record(PxElementAnimationSchema).optional(),
|
|
1017
|
+
debug: px.boolean().optional(),
|
|
1018
|
+
debugInstName: px.string().optional()
|
|
1019
|
+
}));
|
|
1020
|
+
var PxBindingSchema = implementsInterface()(px.object({
|
|
1021
|
+
id: px.string(),
|
|
1022
|
+
animate: PxElementAnimationSchema
|
|
1023
|
+
}));
|
|
1024
|
+
var PxAttrValueSchema = px.union([
|
|
1025
|
+
px.string(),
|
|
1026
|
+
px.number(),
|
|
1027
|
+
px.object({ value: px.any() }),
|
|
1028
|
+
PxPropertyAnimationSchema
|
|
1029
|
+
]);
|
|
1030
|
+
var PxAnimatableNumberSchema = px.union([
|
|
1031
|
+
px.number(),
|
|
1032
|
+
px.object({ value: px.number() }),
|
|
1033
|
+
px.object({
|
|
1034
|
+
keyframes: px.array(PxKeyframeSchema),
|
|
1035
|
+
autoOrient: px.boolean().optional()
|
|
1036
|
+
})
|
|
1037
|
+
]);
|
|
1038
|
+
var PxAnimatableVec2Schema = px.union([
|
|
1039
|
+
px.tuple([px.number(), px.number()]),
|
|
1040
|
+
px.object({ value: px.tuple([px.number(), px.number()]) }),
|
|
1041
|
+
px.object({
|
|
1042
|
+
keyframes: px.array(PxKeyframeSchema),
|
|
1043
|
+
autoOrient: px.boolean().optional()
|
|
1044
|
+
})
|
|
1045
|
+
]);
|
|
1046
|
+
var PxTransformationEffectSchema = implementsInterface()(px.object({
|
|
1047
|
+
translate: PxAnimatableVec2Schema.optional(),
|
|
1048
|
+
rotate: PxAnimatableNumberSchema.optional(),
|
|
1049
|
+
scale: PxAnimatableVec2Schema.optional(),
|
|
1050
|
+
skew: PxAnimatableVec2Schema.optional(),
|
|
1051
|
+
origin: PxAnimatableVec2Schema.optional()
|
|
1052
|
+
}));
|
|
1053
|
+
var PxRepeaterEffectSchema = implementsInterface()(px.object({
|
|
1054
|
+
copies: px.number().optional(),
|
|
1055
|
+
translate: PxAnimatableVec2Schema.optional(),
|
|
1056
|
+
rotate: PxAnimatableNumberSchema.optional(),
|
|
1057
|
+
scale: PxAnimatableVec2Schema.optional(),
|
|
1058
|
+
origin: PxAnimatableVec2Schema.optional()
|
|
1059
|
+
}));
|
|
1060
|
+
var PxMaskedByEffectSchema = implementsInterface()(px.object({
|
|
1061
|
+
href: px.string().optional(),
|
|
1062
|
+
maskType: px.string().optional(),
|
|
1063
|
+
maskUnits: px.string().optional(),
|
|
1064
|
+
maskContentUnits: px.string().optional()
|
|
1065
|
+
}));
|
|
1066
|
+
var PxTrimPathEffectSchema = implementsInterface()(px.object({
|
|
1067
|
+
offset: PxAnimatableNumberSchema.optional(),
|
|
1068
|
+
range: PxAnimatableVec2Schema.optional(),
|
|
1069
|
+
trimAllAsOne: px.boolean().optional()
|
|
1070
|
+
}));
|
|
1071
|
+
var PxRetimeEffectSchema = implementsInterface()(px.object({
|
|
1072
|
+
baseId: px.string().optional(),
|
|
1073
|
+
start: px.number().optional(),
|
|
1074
|
+
stretch: px.number().optional(),
|
|
1075
|
+
timeCrop: px.tuple([px.number(), px.number()]).optional()
|
|
1076
|
+
}));
|
|
1077
|
+
var PxRefEffectSchema = implementsInterface()(px.object({
|
|
1078
|
+
baseId: px.string().optional(),
|
|
1079
|
+
type: px.string().optional()
|
|
1080
|
+
}));
|
|
1081
|
+
var PxGradientUnits = {
|
|
1082
|
+
userSpaceOnUse: "userSpaceOnUse",
|
|
1083
|
+
objectBoundingBox: "objectBoundingBox"
|
|
1084
|
+
};
|
|
1085
|
+
var PxGradientSpreadMethod = {
|
|
1086
|
+
pad: "pad",
|
|
1087
|
+
reflect: "reflect",
|
|
1088
|
+
repeat: "repeat"
|
|
1089
|
+
};
|
|
1090
|
+
var PxGradientType = {
|
|
1091
|
+
linear: "linear",
|
|
1092
|
+
radial: "radial"
|
|
1093
|
+
};
|
|
1094
|
+
var PxGradientStopSchema = implementsInterface()(px.object({
|
|
1095
|
+
offset: px.number(),
|
|
1096
|
+
color: px.string()
|
|
1097
|
+
}));
|
|
1098
|
+
var PxAnimatableGradientStopsSchema = px.union([
|
|
1099
|
+
px.array(PxGradientStopSchema),
|
|
1100
|
+
px.object({ value: px.array(PxGradientStopSchema) }),
|
|
1101
|
+
px.object({ keyframes: px.array(PxKeyframeSchema) })
|
|
1102
|
+
]);
|
|
1103
|
+
var PxFillGradientEffectSchema = implementsInterface()(px.object({
|
|
1104
|
+
type: px.enum([PxGradientType.linear, PxGradientType.radial]),
|
|
1105
|
+
p1: px.tuple([px.number(), px.number()]).optional(),
|
|
1106
|
+
p2: px.tuple([px.number(), px.number()]).optional(),
|
|
1107
|
+
c: px.tuple([px.number(), px.number()]).optional(),
|
|
1108
|
+
r: px.number().optional(),
|
|
1109
|
+
fp: px.tuple([px.number(), px.number()]).optional(),
|
|
1110
|
+
stops: PxAnimatableGradientStopsSchema.optional(),
|
|
1111
|
+
gradientUnits: px.string().optional(),
|
|
1112
|
+
spreadMethod: px.string().optional(),
|
|
1113
|
+
gradientTransform: px.string().optional()
|
|
1114
|
+
}));
|
|
1115
|
+
var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
|
|
1116
|
+
var PxTextAlongPathEffectSchema = implementsInterface()(px.object({
|
|
1117
|
+
href: px.string(),
|
|
1118
|
+
lengthAdjust: px.string().optional(),
|
|
1119
|
+
method: px.string().optional(),
|
|
1120
|
+
spacing: px.string().optional(),
|
|
1121
|
+
startOffset: PxAnimatableNumberSchema.optional(),
|
|
1122
|
+
textLength: PxAnimatableNumberSchema.optional()
|
|
1123
|
+
}));
|
|
1124
|
+
var PxEffectsSchema = implementsInterface()(px.object({
|
|
1125
|
+
transformation: PxTransformationEffectSchema.optional(),
|
|
1126
|
+
repeater: PxRepeaterEffectSchema.optional(),
|
|
1127
|
+
maskedBy: PxMaskedByEffectSchema.optional(),
|
|
1128
|
+
trimPath: PxTrimPathEffectSchema.optional(),
|
|
1129
|
+
retime: PxRetimeEffectSchema.optional(),
|
|
1130
|
+
isCombinedShape: px.boolean().optional(),
|
|
1131
|
+
ref: PxRefEffectSchema.optional(),
|
|
1132
|
+
fillGradient: PxFillGradientEffectSchema.optional(),
|
|
1133
|
+
strokeGradient: PxStrokeGradientEffectSchema.optional(),
|
|
1134
|
+
textAlongPath: PxTextAlongPathEffectSchema.optional()
|
|
1135
|
+
}));
|
|
1136
|
+
function validateNodeEffects(root, opts) {
|
|
1137
|
+
const warnings = [];
|
|
1138
|
+
const walk = (node, path) => {
|
|
1139
|
+
if (node && node.effects) {
|
|
1140
|
+
const ctx = { errors: [], warnings: [], strict: !!(opts == null ? void 0 : opts.strict) };
|
|
1141
|
+
const ok = PxEffectsSchema.isValid(node.effects, ctx, [path + ".effects"]);
|
|
1142
|
+
if (!ok) {
|
|
1143
|
+
for (const err of ctx.errors) warnings.push(err);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
if (node && Array.isArray(node.children)) {
|
|
1147
|
+
node.children.forEach((c, i) => walk(c, path + ".children[" + i + "]"));
|
|
346
1148
|
}
|
|
1149
|
+
};
|
|
1150
|
+
walk(root, "root");
|
|
1151
|
+
return warnings;
|
|
1152
|
+
}
|
|
1153
|
+
var PxNodeBase = px.openObject({
|
|
1154
|
+
type: px.string(),
|
|
1155
|
+
id: px.string().optional(),
|
|
1156
|
+
meta: px.any().optional(),
|
|
1157
|
+
// Player-effects bucket emitted by the Editor's lightweight design format.
|
|
1158
|
+
// Consumed and removed by `applyPlayerEffects` before any other normalisation
|
|
1159
|
+
// (see `createAnimatorImpl`), so downstream code never sees it.
|
|
1160
|
+
effects: PxEffectsSchema.optional(),
|
|
1161
|
+
// `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
|
|
1162
|
+
// string ref / array of refs / inline definition / mixed array; mirrors
|
|
1163
|
+
// `animator.animate` map values and what `processNode` resolves at runtime.
|
|
1164
|
+
animate: PxElementAnimationSchema.optional(),
|
|
1165
|
+
style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
|
|
1166
|
+
}, PxAttrValueSchema);
|
|
1167
|
+
var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBase._shape), {
|
|
1168
|
+
children: px.lazy(() => px.array(PxNodeSchema), []).optional()
|
|
1169
|
+
}), PxAttrValueSchema);
|
|
1170
|
+
var PxSvgNodeExtra = px.object({
|
|
1171
|
+
width: px.number().optional(),
|
|
1172
|
+
height: px.number().optional(),
|
|
1173
|
+
viewBox: px.string().optional(),
|
|
1174
|
+
animator: PxAnimatorConfigSchema.optional()
|
|
1175
|
+
});
|
|
1176
|
+
var PxAnimatedSvgDocumentSchema = px.openObject(__spreadProps(__spreadValues(__spreadValues({}, PxNodeBase._shape), PxSvgNodeExtra._shape), {
|
|
1177
|
+
type: px.literal("svg"),
|
|
1178
|
+
// override string → literal to require 'svg'
|
|
1179
|
+
children: px.array(PxNodeSchema).optional()
|
|
1180
|
+
}), PxAttrValueSchema);
|
|
1181
|
+
var PxBezierPathSchema = implementsInterface()(px.object({
|
|
1182
|
+
v: px.array(px.array(px.number())),
|
|
1183
|
+
i: px.array(px.array(px.number())).optional(),
|
|
1184
|
+
o: px.array(px.array(px.number())).optional(),
|
|
1185
|
+
c: px.boolean().optional()
|
|
1186
|
+
}));
|
|
1187
|
+
function isPxElementFileFormat(fileJson) {
|
|
1188
|
+
if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
|
|
1189
|
+
return false;
|
|
347
1190
|
}
|
|
348
|
-
|
|
349
|
-
return valid;
|
|
1191
|
+
return fileJson["type"] === "svg" || fileJson["tagName"] === "svg";
|
|
350
1192
|
}
|
|
351
1193
|
function isPxElementFileFormatDeep(fileJson) {
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
return { valid, errors };
|
|
1194
|
+
const valid = PxAnimatedSvgDocumentSchema.isValid(fileJson);
|
|
1195
|
+
return { valid, errors: valid ? [] : ["Document failed schema validation"] };
|
|
355
1196
|
}
|
|
356
1197
|
function getAnimatorConfig(doc) {
|
|
357
1198
|
var _a, _b;
|
|
@@ -360,59 +1201,846 @@ function getAnimatorConfig(doc) {
|
|
|
360
1201
|
function getDefs(doc) {
|
|
361
1202
|
var _a;
|
|
362
1203
|
if (!doc) return void 0;
|
|
363
|
-
return
|
|
1204
|
+
return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
|
|
364
1205
|
}
|
|
365
1206
|
function getBindings(doc) {
|
|
366
1207
|
var _a;
|
|
367
1208
|
if (!doc) return void 0;
|
|
368
|
-
|
|
1209
|
+
const animate = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animate;
|
|
1210
|
+
if (!animate) return void 0;
|
|
1211
|
+
return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));
|
|
369
1212
|
}
|
|
370
1213
|
function getChildren(doc) {
|
|
371
1214
|
return doc == null ? void 0 : doc.children;
|
|
372
1215
|
}
|
|
373
1216
|
|
|
374
|
-
// src/
|
|
375
|
-
function
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const isLine = prevO[0] === prevV[0] && prevO[1] === prevV[1] && (currI[0] === currV[0] && currI[1] === currV[1]);
|
|
391
|
-
if (isLine) {
|
|
392
|
-
d.push("L" + currV[0] + "," + currV[1]);
|
|
393
|
-
} else {
|
|
394
|
-
d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
|
|
1217
|
+
// src/PxNodeCloneUtil.ts
|
|
1218
|
+
function deepClonePxNode(value) {
|
|
1219
|
+
if (value === null || typeof value !== "object") return value;
|
|
1220
|
+
if (Array.isArray(value)) return value.map(deepClonePxNode);
|
|
1221
|
+
const out = {};
|
|
1222
|
+
for (const k of Object.keys(value)) out[k] = deepClonePxNode(value[k]);
|
|
1223
|
+
return out;
|
|
1224
|
+
}
|
|
1225
|
+
function regenerateIdsAndRewriteRefs(root, genId3) {
|
|
1226
|
+
const oldToNew = /* @__PURE__ */ new Map();
|
|
1227
|
+
const walkAssign = (n) => {
|
|
1228
|
+
var _a;
|
|
1229
|
+
if (typeof n.id === "string") {
|
|
1230
|
+
const newId = genId3();
|
|
1231
|
+
oldToNew.set(n.id, newId);
|
|
1232
|
+
n.id = newId;
|
|
395
1233
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
1234
|
+
(_a = n.children) == null ? void 0 : _a.forEach(walkAssign);
|
|
1235
|
+
};
|
|
1236
|
+
walkAssign(root);
|
|
1237
|
+
const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
|
|
1238
|
+
const newId = oldToNew.get(oldId);
|
|
1239
|
+
return newId ? "url(#" + newId + ")" : m;
|
|
1240
|
+
});
|
|
1241
|
+
const walkRewrite = (n) => {
|
|
1242
|
+
var _a;
|
|
1243
|
+
if (typeof n.href === "string" && n.href.startsWith("#")) {
|
|
1244
|
+
const newId = oldToNew.get(n.href.slice(1));
|
|
1245
|
+
if (newId) n.href = "#" + newId;
|
|
405
1246
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
1247
|
+
for (const k of Object.keys(n)) {
|
|
1248
|
+
if (k === "children" || k === "effects" || k === "meta" || k === "animate" || k === "href" || k === "id") continue;
|
|
1249
|
+
const v = n[k];
|
|
1250
|
+
if (typeof v === "string" && v.indexOf("url(#") !== -1) {
|
|
1251
|
+
n[k] = rewriteUrl(v);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
(_a = n.children) == null ? void 0 : _a.forEach(walkRewrite);
|
|
1255
|
+
};
|
|
1256
|
+
walkRewrite(root);
|
|
1257
|
+
return oldToNew;
|
|
409
1258
|
}
|
|
410
|
-
function
|
|
411
|
-
|
|
1259
|
+
function toFiniteNum(v) {
|
|
1260
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? parseFloat(v) : NaN;
|
|
1261
|
+
return Number.isFinite(n) ? n : 0;
|
|
412
1262
|
}
|
|
413
|
-
function
|
|
414
|
-
|
|
415
|
-
const
|
|
1263
|
+
function applyUseOffsetToG(gNode) {
|
|
1264
|
+
var _a;
|
|
1265
|
+
const x = toFiniteNum(gNode.x);
|
|
1266
|
+
const y = toFiniteNum(gNode.y);
|
|
1267
|
+
delete gNode.x;
|
|
1268
|
+
delete gNode.y;
|
|
1269
|
+
if (!x && !y) return gNode;
|
|
1270
|
+
const offset = "translate(" + x + "," + y + ")";
|
|
1271
|
+
const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
|
|
1272
|
+
if (carriesTransform) {
|
|
1273
|
+
const inner = { type: "g", transform: offset, children: (_a = gNode.children) != null ? _a : [] };
|
|
1274
|
+
gNode.children = [inner];
|
|
1275
|
+
} else {
|
|
1276
|
+
gNode.transform = offset;
|
|
1277
|
+
}
|
|
1278
|
+
return gNode;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
// src/effects/util.ts
|
|
1282
|
+
function genId(ctx, prefix) {
|
|
1283
|
+
return "_lw_" + prefix + "_" + ctx.nextId++;
|
|
1284
|
+
}
|
|
1285
|
+
function stripHash(href) {
|
|
1286
|
+
return typeof href === "string" ? href.replace(/^#/, "") : void 0;
|
|
1287
|
+
}
|
|
1288
|
+
function indexById(node, map) {
|
|
1289
|
+
var _a;
|
|
1290
|
+
if (typeof node.id === "string") map.set(node.id, node);
|
|
1291
|
+
(_a = node.children) == null ? void 0 : _a.forEach((child) => indexById(child, map));
|
|
1292
|
+
}
|
|
1293
|
+
function spliceDefs(root, defs) {
|
|
1294
|
+
if (!defs.length) return;
|
|
1295
|
+
const existing = root.children || (root.children = []);
|
|
1296
|
+
existing.unshift({ type: "defs", children: defs });
|
|
1297
|
+
}
|
|
1298
|
+
var clone = deepClonePxNode;
|
|
1299
|
+
function regenerateIdsInClone(root, ctx) {
|
|
1300
|
+
return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
// src/effects/gradientEffect.ts
|
|
1304
|
+
function applyFillGradientEffect(node, fx, ctx) {
|
|
1305
|
+
return applyGradient(node, fx, ctx, "fill");
|
|
1306
|
+
}
|
|
1307
|
+
function applyStrokeGradientEffect(node, fx, ctx) {
|
|
1308
|
+
return applyGradient(node, fx, ctx, "stroke");
|
|
1309
|
+
}
|
|
1310
|
+
function applyGradient(node, fx, ctx, attr) {
|
|
1311
|
+
if (!fx) return node;
|
|
1312
|
+
const id = genId(ctx, "grad");
|
|
1313
|
+
const def = synthesiseGradientDef(fx, id, ctx);
|
|
1314
|
+
ctx.defs.push(def);
|
|
1315
|
+
node[attr] = "url(#" + id + ")";
|
|
1316
|
+
return node;
|
|
1317
|
+
}
|
|
1318
|
+
function synthesiseGradientDef(fx, id, ctx) {
|
|
1319
|
+
const out = {
|
|
1320
|
+
type: fx.type === PxGradientType.radial ? "radialGradient" : "linearGradient",
|
|
1321
|
+
id
|
|
1322
|
+
};
|
|
1323
|
+
if (fx.type === PxGradientType.linear) {
|
|
1324
|
+
if (fx.p1) {
|
|
1325
|
+
out.x1 = String(fx.p1[0]);
|
|
1326
|
+
out.y1 = String(fx.p1[1]);
|
|
1327
|
+
}
|
|
1328
|
+
if (fx.p2) {
|
|
1329
|
+
out.x2 = String(fx.p2[0]);
|
|
1330
|
+
out.y2 = String(fx.p2[1]);
|
|
1331
|
+
}
|
|
1332
|
+
} else {
|
|
1333
|
+
if (fx.c) {
|
|
1334
|
+
out.cx = String(fx.c[0]);
|
|
1335
|
+
out.cy = String(fx.c[1]);
|
|
1336
|
+
}
|
|
1337
|
+
if (fx.r !== void 0) out.r = String(fx.r);
|
|
1338
|
+
if (fx.fp) {
|
|
1339
|
+
out.fx = String(fx.fp[0]);
|
|
1340
|
+
out.fy = String(fx.fp[1]);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
|
|
1344
|
+
if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
|
|
1345
|
+
if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
|
|
1346
|
+
out.children = buildStopChildren(fx.stops, ctx);
|
|
1347
|
+
return out;
|
|
1348
|
+
}
|
|
1349
|
+
function buildStopChildren(stops, ctx) {
|
|
1350
|
+
var _a, _b, _c, _d;
|
|
1351
|
+
if (!stops) return [];
|
|
1352
|
+
if (Array.isArray(stops)) return stops.map(staticStopNode);
|
|
1353
|
+
if (typeof stops === "object" && Array.isArray(stops.value)) {
|
|
1354
|
+
return stops.value.map(staticStopNode);
|
|
1355
|
+
}
|
|
1356
|
+
const animBlock = stops;
|
|
1357
|
+
const kfs = animBlock.keyframes;
|
|
1358
|
+
if (!Array.isArray(kfs) || !kfs.length) return [];
|
|
1359
|
+
let stopCount = 0;
|
|
1360
|
+
for (const kf of kfs) {
|
|
1361
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
1362
|
+
if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
|
|
1363
|
+
}
|
|
1364
|
+
if (!stopCount) return [];
|
|
1365
|
+
const firstKfValue = (_b = kfs[0].value) != null ? _b : kfs[0].v;
|
|
1366
|
+
const baselineStops = [];
|
|
1367
|
+
for (let i = 0; i < stopCount; i++) {
|
|
1368
|
+
const s = (_d = (_c = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _c : prevDefinedStop(kfs, 0, i)) != null ? _d : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
|
|
1369
|
+
baselineStops.push({ offset: s.offset, color: s.color });
|
|
1370
|
+
}
|
|
1371
|
+
return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx));
|
|
1372
|
+
}
|
|
1373
|
+
function staticStopNode(s) {
|
|
1374
|
+
return {
|
|
1375
|
+
type: "stop",
|
|
1376
|
+
offset: formatOffset(s.offset),
|
|
1377
|
+
stopColor: s.color
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
function animatedStopNode(baseline, kfs, stopIdx, _ctx) {
|
|
1381
|
+
var _a, _b, _c, _d, _e;
|
|
1382
|
+
const colorKfs = [];
|
|
1383
|
+
const offsetKfs = [];
|
|
1384
|
+
let offsetVaries = false;
|
|
1385
|
+
for (const kf of kfs) {
|
|
1386
|
+
const t = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
|
|
1387
|
+
const arr = (_c = kf.value) != null ? _c : kf.v;
|
|
1388
|
+
const sliced = (_d = arr == null ? void 0 : arr[stopIdx]) != null ? _d : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
|
|
1389
|
+
if (!sliced) continue;
|
|
1390
|
+
const easing = (_e = kf.easing) != null ? _e : kf.e;
|
|
1391
|
+
const colorOut = { time: t, value: sliced.color };
|
|
1392
|
+
if (easing !== void 0) colorOut.easing = easing;
|
|
1393
|
+
colorKfs.push(colorOut);
|
|
1394
|
+
const offsetOut = { time: t, value: sliced.offset };
|
|
1395
|
+
if (easing !== void 0) offsetOut.easing = easing;
|
|
1396
|
+
offsetKfs.push(offsetOut);
|
|
1397
|
+
if (sliced.offset !== baseline.offset) offsetVaries = true;
|
|
1398
|
+
}
|
|
1399
|
+
const stop = {
|
|
1400
|
+
type: "stop",
|
|
1401
|
+
offset: formatOffset(baseline.offset),
|
|
1402
|
+
stopColor: baseline.color
|
|
1403
|
+
};
|
|
1404
|
+
const animate = {};
|
|
1405
|
+
if (colorKfs.length) animate.stopColor = { keyframes: colorKfs };
|
|
1406
|
+
if (offsetVaries && offsetKfs.length) animate.offset = { keyframes: offsetKfs };
|
|
1407
|
+
if (Object.keys(animate).length) stop.animate = animate;
|
|
1408
|
+
return stop;
|
|
1409
|
+
}
|
|
1410
|
+
function prevDefinedStop(kfs, fromIdx, stopIdx) {
|
|
1411
|
+
var _a, _b;
|
|
1412
|
+
for (let i = fromIdx; i >= 0; i--) {
|
|
1413
|
+
const arr = (_a = kfs[i].value) != null ? _a : kfs[i].v;
|
|
1414
|
+
if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
|
|
1415
|
+
}
|
|
1416
|
+
for (let i = fromIdx + 1; i < kfs.length; i++) {
|
|
1417
|
+
const arr = (_b = kfs[i].value) != null ? _b : kfs[i].v;
|
|
1418
|
+
if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
|
|
1419
|
+
}
|
|
1420
|
+
return void 0;
|
|
1421
|
+
}
|
|
1422
|
+
function formatOffset(o) {
|
|
1423
|
+
const pct = Math.round(o * 1e3) / 10;
|
|
1424
|
+
return pct + "%";
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
// src/effects/maskedByEffect.ts
|
|
1428
|
+
function applyMaskedByEffect(node, fx, transformation, ctx) {
|
|
1429
|
+
if (!fx) return node;
|
|
1430
|
+
if (!fx.href) {
|
|
1431
|
+
ctx.errors.push("maskedBy.href missing \u2014 cannot build mask");
|
|
1432
|
+
return node;
|
|
1433
|
+
}
|
|
1434
|
+
const maskId = genId(ctx, "mask");
|
|
1435
|
+
let content = { type: "use", href: "#" + fx.href };
|
|
1436
|
+
if (transformation) {
|
|
1437
|
+
content = wrapInverseTransform(content, transformation, ctx);
|
|
1438
|
+
} else if (hasAnimateTransform(node)) {
|
|
1439
|
+
content = wrapInverseAnimatedBodyTransform(content, node, ctx);
|
|
1440
|
+
} else {
|
|
1441
|
+
const bodyStatic = readTransformationFromBody(node);
|
|
1442
|
+
if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
|
|
1443
|
+
}
|
|
1444
|
+
const includeTargetOwn = transformation === void 0 && !nodeHasBodyTransform(node);
|
|
1445
|
+
content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);
|
|
1446
|
+
const mask = { type: "mask", id: maskId, children: [content] };
|
|
1447
|
+
if (fx.maskType) mask.maskType = fx.maskType;
|
|
1448
|
+
if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
|
|
1449
|
+
if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
|
|
1450
|
+
ctx.defs.push(mask);
|
|
1451
|
+
node.mask = "url(#" + maskId + ")";
|
|
1452
|
+
return node;
|
|
1453
|
+
}
|
|
1454
|
+
function wrapInverseTransform(inner, fx, ctx) {
|
|
1455
|
+
if (!fx) return inner;
|
|
1456
|
+
const origin = readStaticOrigin(fx.origin, ctx);
|
|
1457
|
+
let n = inner;
|
|
1458
|
+
n = wrapInversePart(n, "translate" /* Translate */, fx.translate, void 0, ctx);
|
|
1459
|
+
n = wrapInversePart(n, "rotate" /* Rotate */, fx.rotate, origin, ctx);
|
|
1460
|
+
n = wrapInversePart(n, "scale" /* Scale */, fx.scale, origin, ctx);
|
|
1461
|
+
return n;
|
|
1462
|
+
}
|
|
1463
|
+
function wrapInversePart(inner, part, raw, origin, ctx) {
|
|
1464
|
+
if (raw === void 0) return inner;
|
|
1465
|
+
const normalisedRaw = part === "scale" /* Scale */ && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
|
|
1466
|
+
const v = readAnimatable(normalisedRaw);
|
|
1467
|
+
if (v.kind === "static" /* Static */) {
|
|
1468
|
+
return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
|
|
1469
|
+
}
|
|
1470
|
+
if (v.kind === "animated" /* Animated */) {
|
|
1471
|
+
return {
|
|
1472
|
+
type: "g",
|
|
1473
|
+
animate: { transform: { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin))) } },
|
|
1474
|
+
children: [inner]
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
return inner;
|
|
1478
|
+
}
|
|
1479
|
+
function invertPartValue(part, value) {
|
|
1480
|
+
if (part === "translate" /* Translate */) return [-value[0], -value[1]];
|
|
1481
|
+
if (part === "rotate" /* Rotate */) return -value;
|
|
1482
|
+
return [1 / value[0], 1 / value[1]];
|
|
1483
|
+
}
|
|
1484
|
+
function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
|
|
1485
|
+
var _a;
|
|
1486
|
+
const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
1487
|
+
const animTr = animate == null ? void 0 : animate.transform;
|
|
1488
|
+
const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
|
|
1489
|
+
if (!kfs || !kfs.length) return inner;
|
|
1490
|
+
const translateKfs = [];
|
|
1491
|
+
const rotateKfs = [];
|
|
1492
|
+
const scaleKfs = [];
|
|
1493
|
+
for (const kf of kfs) {
|
|
1494
|
+
const v = ((_a = kf.value) != null ? _a : kf.v) || {};
|
|
1495
|
+
const baseKf = keyframeWith(kf, void 0);
|
|
1496
|
+
if (Array.isArray(v.translate)) {
|
|
1497
|
+
translateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
|
|
1498
|
+
}
|
|
1499
|
+
if (typeof v.rotate === "number") {
|
|
1500
|
+
const rec = { rotate: -v.rotate };
|
|
1501
|
+
if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
|
|
1502
|
+
rotateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
1503
|
+
}
|
|
1504
|
+
if (Array.isArray(v.scale)) {
|
|
1505
|
+
const rec = { scale: [1 / v.scale[0], 1 / v.scale[1]] };
|
|
1506
|
+
if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
|
|
1507
|
+
scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
let n = inner;
|
|
1511
|
+
if (translateKfs.length) n = { type: "g", animate: { transform: { keyframes: translateKfs } }, children: [n] };
|
|
1512
|
+
if (rotateKfs.length) n = { type: "g", animate: { transform: { keyframes: rotateKfs } }, children: [n] };
|
|
1513
|
+
if (scaleKfs.length) n = { type: "g", animate: { transform: { keyframes: scaleKfs } }, children: [n] };
|
|
1514
|
+
return n;
|
|
1515
|
+
}
|
|
1516
|
+
function nodeHasBodyTransform(node) {
|
|
1517
|
+
if (typeof node.transform === "string") return true;
|
|
1518
|
+
if (node.transform && typeof node.transform === "object") return true;
|
|
1519
|
+
return hasAnimateTransform(node);
|
|
1520
|
+
}
|
|
1521
|
+
function hasAnimateTransform(node) {
|
|
1522
|
+
const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
1523
|
+
return !!(animate && animate.transform);
|
|
1524
|
+
}
|
|
1525
|
+
function readTransformationFromBody(node) {
|
|
1526
|
+
if (typeof node.transform === "string") {
|
|
1527
|
+
const parts = parseTransformStringToParts(node.transform);
|
|
1528
|
+
if (!parts) return void 0;
|
|
1529
|
+
const out = {};
|
|
1530
|
+
if (parts.translate) out.translate = parts.translate;
|
|
1531
|
+
if (parts.rotate !== void 0) out.rotate = parts.rotate;
|
|
1532
|
+
if (parts.scale) out.scale = { value: parts.scale };
|
|
1533
|
+
if (parts.origin) out.origin = parts.origin;
|
|
1534
|
+
return Object.keys(out).length ? out : void 0;
|
|
1535
|
+
}
|
|
1536
|
+
return void 0;
|
|
1537
|
+
}
|
|
1538
|
+
function parseTransformStringToParts(s) {
|
|
1539
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
1540
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
1541
|
+
let m;
|
|
1542
|
+
const ops = [];
|
|
1543
|
+
while ((m = re.exec(s)) !== null) {
|
|
1544
|
+
const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
|
|
1545
|
+
ops.push({ name: m[1], args });
|
|
1546
|
+
}
|
|
1547
|
+
if (!ops.length) return void 0;
|
|
1548
|
+
const last = ops[ops.length - 1];
|
|
1549
|
+
if (last.name === "translate") {
|
|
1550
|
+
for (let j = ops.length - 2; j >= 0; j--) {
|
|
1551
|
+
const cand = ops[j];
|
|
1552
|
+
if (cand.name !== "translate") continue;
|
|
1553
|
+
const ox = (_a = cand.args[0]) != null ? _a : 0;
|
|
1554
|
+
const oy = (_b = cand.args[1]) != null ? _b : 0;
|
|
1555
|
+
const lx = (_c = last.args[0]) != null ? _c : 0;
|
|
1556
|
+
const ly = (_d = last.args[1]) != null ? _d : 0;
|
|
1557
|
+
if (lx !== -ox || ly !== -oy) continue;
|
|
1558
|
+
const out2 = {};
|
|
1559
|
+
out2.origin = [ox, oy];
|
|
1560
|
+
for (let k = 0; k < j; k++) {
|
|
1561
|
+
if (ops[k].name === "translate") {
|
|
1562
|
+
const tx = (_e = ops[k].args[0]) != null ? _e : 0;
|
|
1563
|
+
const ty = (_f = ops[k].args[1]) != null ? _f : 0;
|
|
1564
|
+
out2.translate = out2.translate ? [out2.translate[0] + tx, out2.translate[1] + ty] : [tx, ty];
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
for (let k = j + 1; k < ops.length - 1; k++) {
|
|
1568
|
+
const op = ops[k];
|
|
1569
|
+
if (op.name === "rotate") out2.rotate = ((_g = out2.rotate) != null ? _g : 0) + ((_h = op.args[0]) != null ? _h : 0);
|
|
1570
|
+
else if (op.name === "scale") {
|
|
1571
|
+
const sx = (_i = op.args[0]) != null ? _i : 1;
|
|
1572
|
+
const sy = op.args.length > 1 ? op.args[1] : sx;
|
|
1573
|
+
out2.scale = out2.scale ? [out2.scale[0] * sx, out2.scale[1] * sy] : [sx, sy];
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
return out2;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
let translate;
|
|
1580
|
+
let rotate;
|
|
1581
|
+
let scale;
|
|
1582
|
+
for (const op of ops) {
|
|
1583
|
+
if (op.name === "translate") {
|
|
1584
|
+
const dx = (_j = op.args[0]) != null ? _j : 0;
|
|
1585
|
+
const dy = (_k = op.args[1]) != null ? _k : 0;
|
|
1586
|
+
translate = translate ? [translate[0] + dx, translate[1] + dy] : [dx, dy];
|
|
1587
|
+
} else if (op.name === "rotate") {
|
|
1588
|
+
rotate = (rotate != null ? rotate : 0) + ((_l = op.args[0]) != null ? _l : 0);
|
|
1589
|
+
} else if (op.name === "scale") {
|
|
1590
|
+
const sx = (_m = op.args[0]) != null ? _m : 1;
|
|
1591
|
+
const sy = op.args.length > 1 ? op.args[1] : sx;
|
|
1592
|
+
scale = scale ? [scale[0] * sx, scale[1] * sy] : [sx, sy];
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
const out = {};
|
|
1596
|
+
if (translate) out.translate = translate;
|
|
1597
|
+
if (rotate !== void 0) out.rotate = rotate;
|
|
1598
|
+
if (scale) out.scale = scale;
|
|
1599
|
+
return Object.keys(out).length ? out : void 0;
|
|
1600
|
+
}
|
|
1601
|
+
function wrapAncestorChainCompensation(inner, maskedNode, sourceId, ctx, includeTargetOwn) {
|
|
1602
|
+
const sourceNode = ctx.idMap.get(sourceId);
|
|
1603
|
+
const targetAncestors = ctx.maskAncestorChains.get(maskedNode) || [];
|
|
1604
|
+
const targetOwn = includeTargetOwn ? extractTranslateOnly(maskedNode, ctx) : void 0;
|
|
1605
|
+
const targetChain = targetOwn ? [...targetAncestors, targetOwn] : targetAncestors;
|
|
1606
|
+
const sourceChain = sourceNode && ctx.maskAncestorChains.get(sourceNode) || [];
|
|
1607
|
+
if (!targetChain.length && !sourceChain.length) return inner;
|
|
1608
|
+
const times = /* @__PURE__ */ new Set();
|
|
1609
|
+
for (const a of targetChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
|
|
1610
|
+
for (const a of sourceChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
|
|
1611
|
+
const animated = times.size > 0;
|
|
1612
|
+
if (!animated) {
|
|
1613
|
+
const tgt = sumStaticTranslate(targetChain);
|
|
1614
|
+
const src = sumStaticTranslate(sourceChain);
|
|
1615
|
+
const dx = src[0] - tgt[0];
|
|
1616
|
+
const dy = src[1] - tgt[1];
|
|
1617
|
+
if (dx === 0 && dy === 0) return inner;
|
|
1618
|
+
return { type: "g", transform: "translate(" + dx + "," + dy + ")", children: [inner] };
|
|
1619
|
+
}
|
|
1620
|
+
const sortedTimes = Array.from(times).sort((a, b) => a - b);
|
|
1621
|
+
const keyframes = sortedTimes.map((t) => {
|
|
1622
|
+
const tgt = sumTranslateAt(targetChain, t);
|
|
1623
|
+
const src = sumTranslateAt(sourceChain, t);
|
|
1624
|
+
return { time: t, value: { translate: [src[0] - tgt[0], src[1] - tgt[1]] } };
|
|
1625
|
+
});
|
|
1626
|
+
return { type: "g", animate: { transform: { keyframes } }, children: [inner] };
|
|
1627
|
+
}
|
|
1628
|
+
function sumStaticTranslate(chain) {
|
|
1629
|
+
let x = 0, y = 0;
|
|
1630
|
+
for (const a of chain) {
|
|
1631
|
+
if (a.translate) {
|
|
1632
|
+
x += a.translate[0];
|
|
1633
|
+
y += a.translate[1];
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
return [x, y];
|
|
1637
|
+
}
|
|
1638
|
+
function sumTranslateAt(chain, t) {
|
|
1639
|
+
let x = 0, y = 0;
|
|
1640
|
+
for (const a of chain) {
|
|
1641
|
+
if (a.translateKeyframes && a.translateKeyframes.length) {
|
|
1642
|
+
const v = interpKfs(a.translateKeyframes, t);
|
|
1643
|
+
x += v[0];
|
|
1644
|
+
y += v[1];
|
|
1645
|
+
} else if (a.translate) {
|
|
1646
|
+
x += a.translate[0];
|
|
1647
|
+
y += a.translate[1];
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
return [x, y];
|
|
1651
|
+
}
|
|
1652
|
+
function interpKfs(kfs, t) {
|
|
1653
|
+
if (t <= kfs[0].time) return kfs[0].value;
|
|
1654
|
+
if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
|
|
1655
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
1656
|
+
if (t <= kfs[i].time) {
|
|
1657
|
+
const prev = kfs[i - 1];
|
|
1658
|
+
const cur = kfs[i];
|
|
1659
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
1660
|
+
return [prev.value[0] + (cur.value[0] - prev.value[0]) * a, prev.value[1] + (cur.value[1] - prev.value[1]) * a];
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
return kfs[kfs.length - 1].value;
|
|
1664
|
+
}
|
|
1665
|
+
function collectMaskAncestorChains(root, ctx) {
|
|
1666
|
+
const interestingNodes = /* @__PURE__ */ new Set();
|
|
1667
|
+
const collectInterestingNodes = (n) => {
|
|
1668
|
+
var _a, _b;
|
|
1669
|
+
const href = (_b = (_a = n.effects) == null ? void 0 : _a.maskedBy) == null ? void 0 : _b.href;
|
|
1670
|
+
if (typeof href === "string") {
|
|
1671
|
+
interestingNodes.add(n);
|
|
1672
|
+
const sourceNode = ctx.idMap.get(href);
|
|
1673
|
+
if (sourceNode) interestingNodes.add(sourceNode);
|
|
1674
|
+
}
|
|
1675
|
+
if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
|
|
1676
|
+
};
|
|
1677
|
+
collectInterestingNodes(root);
|
|
1678
|
+
if (interestingNodes.size === 0) return;
|
|
1679
|
+
const walk = (node, chain) => {
|
|
1680
|
+
if (interestingNodes.has(node)) ctx.maskAncestorChains.set(node, chain);
|
|
1681
|
+
if (Array.isArray(node.children)) {
|
|
1682
|
+
const own = extractTranslateOnly(node, ctx);
|
|
1683
|
+
const next = own ? [...chain, own] : chain;
|
|
1684
|
+
for (const ch of node.children) walk(ch, next);
|
|
1685
|
+
}
|
|
1686
|
+
};
|
|
1687
|
+
walk(root, []);
|
|
1688
|
+
}
|
|
1689
|
+
function extractTranslateOnly(node, ctx) {
|
|
1690
|
+
var _a, _b, _c;
|
|
1691
|
+
const tr = node.transform;
|
|
1692
|
+
const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
|
|
1693
|
+
if (tr === void 0 && !animateBlock) return void 0;
|
|
1694
|
+
const out = {};
|
|
1695
|
+
if (typeof tr === "string") {
|
|
1696
|
+
const parts = parseTranslateOnlyFromString(tr, ctx);
|
|
1697
|
+
if (parts) out.translate = parts;
|
|
1698
|
+
} else if (tr && typeof tr === "object") {
|
|
1699
|
+
const value = tr.value;
|
|
1700
|
+
if (value && typeof value === "object" && Array.isArray(value.translate)) {
|
|
1701
|
+
out.translate = [value.translate[0] || 0, value.translate[1] || 0];
|
|
1702
|
+
}
|
|
1703
|
+
if (value && (value.rotate !== void 0 || value.scale !== void 0 || value.skew !== void 0)) {
|
|
1704
|
+
ctx.warnings.push("maskedBy ancestor: non-translate transform parts ignored (rotate/scale not yet supported)");
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
if (animateBlock && Array.isArray(animateBlock.keyframes)) {
|
|
1708
|
+
const kfs = animateBlock.keyframes;
|
|
1709
|
+
const translateKfs = [];
|
|
1710
|
+
for (const kf of kfs) {
|
|
1711
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
1712
|
+
const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
|
|
1713
|
+
if (v && typeof v === "object" && Array.isArray(v.translate)) {
|
|
1714
|
+
translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
|
|
1715
|
+
if (v.rotate !== void 0 || v.scale !== void 0 || v.skew !== void 0) {
|
|
1716
|
+
ctx.warnings.push("maskedBy ancestor: animated non-translate parts ignored");
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
if (translateKfs.length) out.translateKeyframes = translateKfs;
|
|
1721
|
+
}
|
|
1722
|
+
return out.translate || out.translateKeyframes ? out : void 0;
|
|
1723
|
+
}
|
|
1724
|
+
function parseTranslateOnlyFromString(s, ctx) {
|
|
1725
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
1726
|
+
let m;
|
|
1727
|
+
let x = 0, y = 0;
|
|
1728
|
+
let seen = false;
|
|
1729
|
+
let droppedNonTranslate = false;
|
|
1730
|
+
while ((m = re.exec(s)) !== null) {
|
|
1731
|
+
const name = m[1];
|
|
1732
|
+
const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
|
|
1733
|
+
if (name === "translate") {
|
|
1734
|
+
x += args[0] || 0;
|
|
1735
|
+
y += args[1] || 0;
|
|
1736
|
+
seen = true;
|
|
1737
|
+
} else {
|
|
1738
|
+
droppedNonTranslate = true;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
|
|
1742
|
+
return seen ? [x, y] : void 0;
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
// src/effects/refEffect.ts
|
|
1746
|
+
var CONTENT_SUBREF = "content";
|
|
1747
|
+
function applyRefAndTransformationEffect(node, ref, transformation, ctx) {
|
|
1748
|
+
if (ref) {
|
|
1749
|
+
const baseId = ref.baseId;
|
|
1750
|
+
if (!baseId) {
|
|
1751
|
+
ctx.errors.push("ref: missing baseId");
|
|
1752
|
+
} else {
|
|
1753
|
+
const targetId = ref.type === CONTENT_SUBREF ? ctx.contentRefInnerIds.get(baseId) || baseId : baseId;
|
|
1754
|
+
node.href = "#" + targetId;
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
return applyTransformationEffect(node, transformation, ctx);
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
// src/effects/repeaterEffect.ts
|
|
1761
|
+
function applyRepeaterEffect(node, fx, ctx) {
|
|
1762
|
+
var _a, _b;
|
|
1763
|
+
if (!fx) return node;
|
|
1764
|
+
const copies = (_a = fx.copies) != null ? _a : 1;
|
|
1765
|
+
if (copies < 1) {
|
|
1766
|
+
ctx.errors.push("repeater.copies invalid: " + fx.copies);
|
|
1767
|
+
return node;
|
|
1768
|
+
}
|
|
1769
|
+
const sharedTransform = node.transform;
|
|
1770
|
+
const sharedAnimTransform = (_b = node.animate) == null ? void 0 : _b.transform;
|
|
1771
|
+
const base = clone(node);
|
|
1772
|
+
delete base.transform;
|
|
1773
|
+
if (base.animate) {
|
|
1774
|
+
delete base.animate.transform;
|
|
1775
|
+
if (Object.keys(base.animate).length === 0) delete base.animate;
|
|
1776
|
+
}
|
|
1777
|
+
const children = [base];
|
|
1778
|
+
for (let i = 1; i < copies; i++) {
|
|
1779
|
+
const baseClone = clone(base);
|
|
1780
|
+
const synthFx = synthesisePerCopyFx(fx, i);
|
|
1781
|
+
const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;
|
|
1782
|
+
children.push(wrapped);
|
|
1783
|
+
}
|
|
1784
|
+
const wrapper = { type: "g", children };
|
|
1785
|
+
if (sharedTransform !== void 0) wrapper.transform = sharedTransform;
|
|
1786
|
+
if (sharedAnimTransform !== void 0) wrapper.animate = { transform: sharedAnimTransform };
|
|
1787
|
+
return wrapper;
|
|
1788
|
+
}
|
|
1789
|
+
function synthesisePerCopyFx(fx, i) {
|
|
1790
|
+
const out = {};
|
|
1791
|
+
if (fx.translate !== void 0) {
|
|
1792
|
+
out.translate = mapAnimatableVec2(fx.translate, (v) => [v[0] * i, v[1] * i]);
|
|
1793
|
+
}
|
|
1794
|
+
if (fx.rotate !== void 0) {
|
|
1795
|
+
out.rotate = mapAnimatableNumber(fx.rotate, (v) => v * i);
|
|
1796
|
+
}
|
|
1797
|
+
if (fx.scale !== void 0) {
|
|
1798
|
+
out.scale = synthesiseScale(fx.scale, i);
|
|
1799
|
+
}
|
|
1800
|
+
if (fx.origin !== void 0) {
|
|
1801
|
+
out.origin = fx.origin;
|
|
1802
|
+
}
|
|
1803
|
+
return Object.keys(out).length ? out : void 0;
|
|
1804
|
+
}
|
|
1805
|
+
function mapAnimatableVec2(raw, fn) {
|
|
1806
|
+
if (Array.isArray(raw)) return fn(raw);
|
|
1807
|
+
if (raw && typeof raw === "object") {
|
|
1808
|
+
const obj = raw;
|
|
1809
|
+
if (Array.isArray(obj.keyframes)) {
|
|
1810
|
+
return __spreadProps(__spreadValues({}, obj), {
|
|
1811
|
+
keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1814
|
+
if (obj.value !== void 0) {
|
|
1815
|
+
return __spreadProps(__spreadValues({}, obj), { value: fn(obj.value) });
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
return raw;
|
|
1819
|
+
}
|
|
1820
|
+
function mapAnimatableNumber(raw, fn) {
|
|
1821
|
+
if (typeof raw === "number") return fn(raw);
|
|
1822
|
+
if (raw && typeof raw === "object") {
|
|
1823
|
+
const obj = raw;
|
|
1824
|
+
if (Array.isArray(obj.keyframes)) {
|
|
1825
|
+
return __spreadProps(__spreadValues({}, obj), {
|
|
1826
|
+
keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
if (obj.value !== void 0) {
|
|
1830
|
+
return __spreadProps(__spreadValues({}, obj), { value: fn(obj.value) });
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
return raw;
|
|
1834
|
+
}
|
|
1835
|
+
function synthesiseScale(raw, i) {
|
|
1836
|
+
const scalePowerFromPercent = (v) => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];
|
|
1837
|
+
const scalePowerFromUnits = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
|
|
1838
|
+
if (Array.isArray(raw)) {
|
|
1839
|
+
return { value: scalePowerFromPercent(raw) };
|
|
1840
|
+
}
|
|
1841
|
+
if (raw && typeof raw === "object") {
|
|
1842
|
+
const obj = raw;
|
|
1843
|
+
if (Array.isArray(obj.keyframes)) {
|
|
1844
|
+
return __spreadProps(__spreadValues({}, obj), {
|
|
1845
|
+
keyframes: obj.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: scalePowerFromUnits(kf.value) }) : kf)
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
if (obj.value !== void 0) {
|
|
1849
|
+
return __spreadProps(__spreadValues({}, obj), { value: scalePowerFromPercent(obj.value) });
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
return raw;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
// src/effects/retimeEffect.ts
|
|
1856
|
+
var RETIME_MATERIALISATION_MODE_INLINE_G = false;
|
|
1857
|
+
function asRetime(r) {
|
|
1858
|
+
var _a, _b;
|
|
1859
|
+
return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
|
|
1860
|
+
}
|
|
1861
|
+
function concatRetime(child, parent) {
|
|
1862
|
+
return {
|
|
1863
|
+
start: parent.start + parent.stretch * child.start,
|
|
1864
|
+
stretch: parent.stretch * child.stretch
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1867
|
+
function applyAllRetimeEffects(root, ctx) {
|
|
1868
|
+
var _a;
|
|
1869
|
+
ctx.idMap.clear();
|
|
1870
|
+
indexById(root, ctx.idMap);
|
|
1871
|
+
const sites = [];
|
|
1872
|
+
const collect = (n) => {
|
|
1873
|
+
var _a2, _b;
|
|
1874
|
+
if ((_a2 = n.effects) == null ? void 0 : _a2.retime) sites.push(n);
|
|
1875
|
+
(_b = n.children) == null ? void 0 : _b.forEach(collect);
|
|
1876
|
+
};
|
|
1877
|
+
collect(root);
|
|
1878
|
+
for (const useNode of sites) {
|
|
1879
|
+
const retime = (_a = useNode.effects) == null ? void 0 : _a.retime;
|
|
1880
|
+
if (!retime) continue;
|
|
1881
|
+
delete useNode.effects.retime;
|
|
1882
|
+
if (Object.keys(useNode.effects).length === 0) delete useNode.effects;
|
|
1883
|
+
materialiseRetime(useNode, asRetime(retime), ctx);
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
function materialiseRetime(useNode, retime, ctx) {
|
|
1887
|
+
const targetId = stripHash(useNode.href);
|
|
1888
|
+
if (!targetId) {
|
|
1889
|
+
ctx.errors.push("retime: <use> has no href to follow");
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
const chainRootId = buildChainClone(targetId, retime, ctx, /* @__PURE__ */ new Set());
|
|
1893
|
+
if (!chainRootId) return;
|
|
1894
|
+
if (RETIME_MATERIALISATION_MODE_INLINE_G) {
|
|
1895
|
+
const cloneNode = ctx.idMap.get(chainRootId);
|
|
1896
|
+
useNode.type = "g";
|
|
1897
|
+
delete useNode.href;
|
|
1898
|
+
useNode.children = [cloneNode];
|
|
1899
|
+
applyUseOffsetToG(useNode);
|
|
1900
|
+
ctx.defs = ctx.defs.filter((d) => d !== cloneNode);
|
|
1901
|
+
} else {
|
|
1902
|
+
useNode.href = "#" + chainRootId;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
function buildChainClone(targetId, accum, ctx, chain) {
|
|
1906
|
+
var _a, _b;
|
|
1907
|
+
if (chain.has(targetId)) {
|
|
1908
|
+
ctx.errors.push('retime: loop via "' + targetId + '"');
|
|
1909
|
+
return void 0;
|
|
1910
|
+
}
|
|
1911
|
+
const target = ctx.idMap.get(targetId);
|
|
1912
|
+
if (!target) {
|
|
1913
|
+
ctx.warnings.push('retime: target "' + targetId + '" not found');
|
|
1914
|
+
return void 0;
|
|
1915
|
+
}
|
|
1916
|
+
const cloneNode = clone(target);
|
|
1917
|
+
regenerateIdsInClone(cloneNode, ctx);
|
|
1918
|
+
if (target.type === "use") {
|
|
1919
|
+
remapKeyframeTimesOnly(cloneNode, accum.start, accum.stretch);
|
|
1920
|
+
} else {
|
|
1921
|
+
remapKeyframeTimes(cloneNode, accum.start, accum.stretch);
|
|
1922
|
+
}
|
|
1923
|
+
if ((_a = cloneNode.effects) == null ? void 0 : _a.retime) {
|
|
1924
|
+
delete cloneNode.effects.retime;
|
|
1925
|
+
if (Object.keys(cloneNode.effects).length === 0) delete cloneNode.effects;
|
|
1926
|
+
}
|
|
1927
|
+
if (target.type === "use" && target.href) {
|
|
1928
|
+
const subId = stripHash(target.href);
|
|
1929
|
+
if (subId) {
|
|
1930
|
+
const innerRetime = (_b = target.effects) == null ? void 0 : _b.retime;
|
|
1931
|
+
const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
|
|
1932
|
+
const subChain = new Set(chain);
|
|
1933
|
+
subChain.add(targetId);
|
|
1934
|
+
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
1935
|
+
if (subId2) cloneNode.href = "#" + subId2;
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
ctx.defs.push(cloneNode);
|
|
1939
|
+
if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
|
|
1940
|
+
return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
|
|
1941
|
+
}
|
|
1942
|
+
function remapKeyframeTimes(node, start, stretch) {
|
|
1943
|
+
var _a;
|
|
1944
|
+
remapKeyframeTimesOnly(node, start, stretch);
|
|
1945
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => remapKeyframeTimes(c, start, stretch));
|
|
1946
|
+
}
|
|
1947
|
+
function remapKeyframeTimesOnly(node, start, stretch) {
|
|
1948
|
+
const remap2 = (kfs) => {
|
|
1949
|
+
for (const kf of kfs) if (typeof kf.time === "number") kf.time = start + kf.time * stretch;
|
|
1950
|
+
};
|
|
1951
|
+
if (node.transform && typeof node.transform === "object" && Array.isArray(node.transform.keyframes)) {
|
|
1952
|
+
remap2(node.transform.keyframes);
|
|
1953
|
+
}
|
|
1954
|
+
if (node.animate && typeof node.animate === "object") {
|
|
1955
|
+
for (const prop of Object.keys(node.animate)) {
|
|
1956
|
+
const anim = node.animate[prop];
|
|
1957
|
+
if (anim && Array.isArray(anim.keyframes)) remap2(anim.keyframes);
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
// src/effects/textAlongPathEffect.ts
|
|
1963
|
+
function applyTextAlongPathEffect(node, fx, _ctx) {
|
|
1964
|
+
var _a;
|
|
1965
|
+
if (!fx) return node;
|
|
1966
|
+
const href = typeof fx.href === "string" && !fx.href.startsWith("#") ? "#" + fx.href : fx.href;
|
|
1967
|
+
const textPath = {
|
|
1968
|
+
type: "textPath",
|
|
1969
|
+
href,
|
|
1970
|
+
children: (_a = node.children) != null ? _a : []
|
|
1971
|
+
};
|
|
1972
|
+
if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
|
|
1973
|
+
if (fx.method !== void 0) textPath.method = fx.method;
|
|
1974
|
+
if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
|
|
1975
|
+
applyAnimatableNumber(textPath, "startOffset", fx.startOffset);
|
|
1976
|
+
applyAnimatableNumber(textPath, "textLength", fx.textLength);
|
|
1977
|
+
node.children = [textPath];
|
|
1978
|
+
return node;
|
|
1979
|
+
}
|
|
1980
|
+
function applyAnimatableNumber(node, attrName, raw) {
|
|
1981
|
+
if (raw === void 0 || raw === null) return;
|
|
1982
|
+
if (typeof raw === "number") {
|
|
1983
|
+
node[attrName] = String(raw);
|
|
1984
|
+
return;
|
|
1985
|
+
}
|
|
1986
|
+
if (typeof raw === "object") {
|
|
1987
|
+
const obj = raw;
|
|
1988
|
+
if (Array.isArray(obj.keyframes)) {
|
|
1989
|
+
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
1990
|
+
const animate = __spreadValues({}, prevAnimate || {});
|
|
1991
|
+
animate[attrName] = { keyframes: obj.keyframes };
|
|
1992
|
+
node.animate = animate;
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1995
|
+
if (typeof obj.value === "number") {
|
|
1996
|
+
node[attrName] = String(obj.value);
|
|
1997
|
+
return;
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
// src/PxAnimatorUtil.ts
|
|
2003
|
+
function bezierToSvgPath(path) {
|
|
2004
|
+
var _a, _b, _c, _d;
|
|
2005
|
+
const v = path.v;
|
|
2006
|
+
const i = path.i;
|
|
2007
|
+
const o = path.o;
|
|
2008
|
+
const c = path.c;
|
|
2009
|
+
if (!v.length) return "";
|
|
2010
|
+
const d = [];
|
|
2011
|
+
const len = v.length;
|
|
2012
|
+
d.push("M" + v[0][0] + "," + v[0][1]);
|
|
2013
|
+
for (let idx = 1; idx < len; idx++) {
|
|
2014
|
+
const prevV = v[idx - 1];
|
|
2015
|
+
const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
|
|
2016
|
+
const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
|
|
2017
|
+
const currV = v[idx];
|
|
2018
|
+
const isLine = prevO[0] === prevV[0] && prevO[1] === prevV[1] && (currI[0] === currV[0] && currI[1] === currV[1]);
|
|
2019
|
+
if (isLine) {
|
|
2020
|
+
d.push("L" + currV[0] + "," + currV[1]);
|
|
2021
|
+
} else {
|
|
2022
|
+
d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
if (c && len > 0) {
|
|
2026
|
+
const lastV = v[len - 1];
|
|
2027
|
+
const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
|
|
2028
|
+
const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
|
|
2029
|
+
const firstV = v[0];
|
|
2030
|
+
const isLine = lastO[0] === lastV[0] && lastO[1] === lastV[1] && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
|
|
2031
|
+
if (!isLine) {
|
|
2032
|
+
d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
|
|
2033
|
+
}
|
|
2034
|
+
d.push("z");
|
|
2035
|
+
}
|
|
2036
|
+
return d.join("");
|
|
2037
|
+
}
|
|
2038
|
+
function interpolateNum(a, b, t) {
|
|
2039
|
+
return a + (b - a) * t;
|
|
2040
|
+
}
|
|
2041
|
+
function interpolateVec(a, b, t) {
|
|
2042
|
+
const res = [];
|
|
2043
|
+
const count = Math.max(a.length, b.length);
|
|
416
2044
|
for (let i = 0; i < count; i++) {
|
|
417
2045
|
res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
|
|
418
2046
|
}
|
|
@@ -604,6 +2232,24 @@ function parseColor(s) {
|
|
|
604
2232
|
var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
|
|
605
2233
|
var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
|
|
606
2234
|
var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
2235
|
+
function composeTransformParts(parts, opts) {
|
|
2236
|
+
var _a;
|
|
2237
|
+
if (!parts) return "";
|
|
2238
|
+
const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
|
|
2239
|
+
const segs = [];
|
|
2240
|
+
const t = parts.translate;
|
|
2241
|
+
const o = parts.origin;
|
|
2242
|
+
const r = parts.rotate;
|
|
2243
|
+
const s = parts.scale;
|
|
2244
|
+
const tu = withUnits ? "px" : "";
|
|
2245
|
+
const ru = withUnits ? "deg" : "";
|
|
2246
|
+
if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
|
|
2247
|
+
if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
|
|
2248
|
+
if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
|
|
2249
|
+
if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
|
|
2250
|
+
if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
|
|
2251
|
+
return segs.join("");
|
|
2252
|
+
}
|
|
607
2253
|
var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
608
2254
|
var DEFAULT_DURATION_MS = 1e3;
|
|
609
2255
|
function kebabToCamelCaseWord(kebab) {
|
|
@@ -628,6 +2274,12 @@ var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
|
|
|
628
2274
|
"clipPathUnits",
|
|
629
2275
|
"maskUnits",
|
|
630
2276
|
"maskContentUnits",
|
|
2277
|
+
// Marker (SVG spec keeps these camelCase, like viewBox)
|
|
2278
|
+
"markerUnits",
|
|
2279
|
+
"markerWidth",
|
|
2280
|
+
"markerHeight",
|
|
2281
|
+
"refX",
|
|
2282
|
+
"refY",
|
|
631
2283
|
// Text
|
|
632
2284
|
"textLength",
|
|
633
2285
|
"lengthAdjust",
|
|
@@ -663,288 +2315,456 @@ function camelCaseToKebabWordIfNeeded(camel) {
|
|
|
663
2315
|
function clamp(value, min, max) {
|
|
664
2316
|
return Math.max(min, Math.min(value, max));
|
|
665
2317
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
"symbol",
|
|
690
|
-
"marker",
|
|
691
|
-
"filter",
|
|
692
|
-
"feGaussianBlur",
|
|
693
|
-
"feOffset",
|
|
694
|
-
"feBlend",
|
|
695
|
-
"feColorMatrix",
|
|
696
|
-
"feMerge",
|
|
697
|
-
"feMergeNode"
|
|
698
|
-
].map((tagName) => tagName.toLowerCase()));
|
|
699
|
-
var ALLOWED_RESOURCE_ATTRIBUTES = [
|
|
700
|
-
"href",
|
|
701
|
-
// <use>
|
|
702
|
-
"src",
|
|
703
|
-
// <image>
|
|
704
|
-
"filter",
|
|
705
|
-
// url(#filterId)
|
|
706
|
-
"clipPath",
|
|
707
|
-
// clip-path="url(#clipPathId)"
|
|
708
|
-
"mask",
|
|
709
|
-
// url(#maskId)
|
|
710
|
-
"markerStart",
|
|
711
|
-
// marker-start="url(#markerId)"
|
|
712
|
-
"markerMid",
|
|
713
|
-
// marker-mid="url(#markerId)"
|
|
714
|
-
"markerEnd"
|
|
715
|
-
// marker-end="url(#markerId)"
|
|
716
|
-
// 'fill', // url(#gradientId) or url(#patternId)
|
|
717
|
-
// 'stroke', // url(#gradientId) or url(#patternId)
|
|
718
|
-
// Don't allow 'cursor', can use external SVG, // url(cursor.svg)
|
|
719
|
-
];
|
|
720
|
-
var ALLOWED_RESOURCE_ATTRIBUTES_SET = new Set(ALLOWED_RESOURCE_ATTRIBUTES);
|
|
721
|
-
var ALLOWED_ATTRIBUTES_SET = /* @__PURE__ */ new Set([
|
|
722
|
-
"href",
|
|
723
|
-
"src",
|
|
724
|
-
// Presentation
|
|
725
|
-
"fill",
|
|
726
|
-
"stroke",
|
|
727
|
-
"strokeWidth",
|
|
728
|
-
"opacity",
|
|
729
|
-
"transform",
|
|
730
|
-
// Geometry
|
|
731
|
-
"x",
|
|
732
|
-
"y",
|
|
733
|
-
"cx",
|
|
734
|
-
"cy",
|
|
735
|
-
"r",
|
|
736
|
-
"rx",
|
|
737
|
-
"ry",
|
|
738
|
-
"width",
|
|
739
|
-
"height",
|
|
740
|
-
"d",
|
|
741
|
-
"x1",
|
|
742
|
-
"y1",
|
|
743
|
-
"x2",
|
|
744
|
-
"y2",
|
|
745
|
-
"points",
|
|
746
|
-
// Text
|
|
747
|
-
"fontSize",
|
|
748
|
-
"fontFamily",
|
|
749
|
-
"textAnchor",
|
|
750
|
-
// Structure
|
|
751
|
-
"id",
|
|
752
|
-
"class",
|
|
753
|
-
"viewBox",
|
|
754
|
-
"preserveAspectRatio",
|
|
755
|
-
// Gradient/Pattern
|
|
756
|
-
"offset",
|
|
757
|
-
"stopColor",
|
|
758
|
-
"stopOpacity",
|
|
759
|
-
"gradientTransform",
|
|
760
|
-
// Clippath/Mask
|
|
761
|
-
"clipPath",
|
|
762
|
-
"mask",
|
|
763
|
-
// Filter
|
|
764
|
-
"filter",
|
|
765
|
-
"stdDeviation",
|
|
766
|
-
"in",
|
|
767
|
-
"in2",
|
|
768
|
-
"result",
|
|
769
|
-
"mode",
|
|
770
|
-
...ALLOWED_RESOURCE_ATTRIBUTES
|
|
771
|
-
]);
|
|
772
|
-
function sanitiseAttributeValue(name, value) {
|
|
773
|
-
const nameLower = name.toLowerCase();
|
|
774
|
-
if (!ALLOWED_ATTRIBUTES_SET.has(nameLower)) {
|
|
775
|
-
console.warn("Attribute not in whitelist: ", nameLower);
|
|
776
|
-
return void 0;
|
|
2318
|
+
function bezier2D_pointAt(P0, P1, P2, P3, t) {
|
|
2319
|
+
if (t <= 0) return [P0[0], P0[1]];
|
|
2320
|
+
if (t >= 1) return [P3[0], P3[1]];
|
|
2321
|
+
const u = 1 - t;
|
|
2322
|
+
const u2 = u * u;
|
|
2323
|
+
const u3 = u2 * u;
|
|
2324
|
+
const t2 = t * t;
|
|
2325
|
+
const t3 = t2 * t;
|
|
2326
|
+
const w0 = u3;
|
|
2327
|
+
const w1 = 3 * t * u2;
|
|
2328
|
+
const w2 = 3 * t2 * u;
|
|
2329
|
+
const w3 = t3;
|
|
2330
|
+
return [
|
|
2331
|
+
w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
|
|
2332
|
+
w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
|
|
2333
|
+
];
|
|
2334
|
+
}
|
|
2335
|
+
var BEZIER_T_NUDGE = 1e-4;
|
|
2336
|
+
function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
|
|
2337
|
+
const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
|
|
2338
|
+
if (result[0] === 0 && result[1] === 0) {
|
|
2339
|
+
const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
|
|
2340
|
+
return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
|
|
777
2341
|
}
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
2342
|
+
return result;
|
|
2343
|
+
}
|
|
2344
|
+
function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
|
|
2345
|
+
const u = 1 - t;
|
|
2346
|
+
const a = 3 * u * u;
|
|
2347
|
+
const b = 6 * t * u;
|
|
2348
|
+
const c = 3 * t * t;
|
|
2349
|
+
return [
|
|
2350
|
+
a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
|
|
2351
|
+
a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
|
|
2352
|
+
];
|
|
2353
|
+
}
|
|
2354
|
+
function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
|
|
2355
|
+
const n = steps + 1;
|
|
2356
|
+
const ts = new Float64Array(n);
|
|
2357
|
+
const ds = new Float64Array(n);
|
|
2358
|
+
let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
|
|
2359
|
+
ts[0] = 0;
|
|
2360
|
+
ds[0] = 0;
|
|
2361
|
+
let cum = 0;
|
|
2362
|
+
for (let i = 1; i < n; i++) {
|
|
2363
|
+
const t = i / steps;
|
|
2364
|
+
const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
|
|
2365
|
+
const dx = cur[0] - prev[0];
|
|
2366
|
+
const dy = cur[1] - prev[1];
|
|
2367
|
+
cum += Math.sqrt(dx * dx + dy * dy);
|
|
2368
|
+
ts[i] = t;
|
|
2369
|
+
ds[i] = cum;
|
|
2370
|
+
prev = cur;
|
|
785
2371
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
2372
|
+
return { ts, ds };
|
|
2373
|
+
}
|
|
2374
|
+
function bezier2D_arcAtT(lut, t) {
|
|
2375
|
+
const { ts, ds } = lut;
|
|
2376
|
+
const last = ts.length - 1;
|
|
2377
|
+
if (t <= ts[0]) return ds[0];
|
|
2378
|
+
if (t >= ts[last]) return ds[last];
|
|
2379
|
+
let lo = 1, hi = last;
|
|
2380
|
+
while (lo < hi) {
|
|
2381
|
+
const mid = lo + hi >>> 1;
|
|
2382
|
+
if (ts[mid] < t) lo = mid + 1;
|
|
2383
|
+
else hi = mid;
|
|
2384
|
+
}
|
|
2385
|
+
const tPrev = ts[hi - 1];
|
|
2386
|
+
const span = ts[hi] - tPrev;
|
|
2387
|
+
const frac = span > 0 ? (t - tPrev) / span : 0;
|
|
2388
|
+
return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);
|
|
2389
|
+
}
|
|
2390
|
+
function invertEasing(easing) {
|
|
2391
|
+
if (!easing) return (y) => y;
|
|
2392
|
+
const flipped = [easing[1], easing[0], easing[3], easing[2]];
|
|
2393
|
+
return cubicBezier(flipped);
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
// src/PxMotionPath.ts
|
|
2397
|
+
function getKfTranslate(kf) {
|
|
2398
|
+
var _a;
|
|
2399
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
2400
|
+
if (!v) return void 0;
|
|
2401
|
+
if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
|
|
2402
|
+
return [v[0], v[1]];
|
|
2403
|
+
}
|
|
2404
|
+
const tr = v.translate;
|
|
2405
|
+
if (Array.isArray(tr) && tr.length >= 2) return [tr[0], tr[1]];
|
|
2406
|
+
return void 0;
|
|
2407
|
+
}
|
|
2408
|
+
function getKfTime(kf) {
|
|
2409
|
+
var _a, _b;
|
|
2410
|
+
return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
|
|
2411
|
+
}
|
|
2412
|
+
function getKfEasing(kf) {
|
|
2413
|
+
var _a;
|
|
2414
|
+
return (_a = kf.easing) != null ? _a : kf.e;
|
|
2415
|
+
}
|
|
2416
|
+
function propAnimIsMotionPath(anim) {
|
|
2417
|
+
var _a, _b, _c;
|
|
2418
|
+
const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
|
|
2419
|
+
if (!Array.isArray(kfs)) return false;
|
|
2420
|
+
if (anim.autoOrient) return true;
|
|
2421
|
+
for (const kf of kfs) {
|
|
2422
|
+
if (((_b = kf.tangentIn) != null ? _b : kf.ti) || ((_c = kf.tangentOut) != null ? _c : kf.to)) return true;
|
|
2423
|
+
}
|
|
2424
|
+
return false;
|
|
2425
|
+
}
|
|
2426
|
+
var _segmentCache = /* @__PURE__ */ new WeakMap();
|
|
2427
|
+
function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
|
|
2428
|
+
var _a, _b;
|
|
2429
|
+
const existing = _segmentCache.get(prevKf);
|
|
2430
|
+
if (existing) return existing;
|
|
2431
|
+
const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
|
|
2432
|
+
const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
|
|
2433
|
+
const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
|
|
2434
|
+
const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
|
|
2435
|
+
const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
|
|
2436
|
+
const entry = {
|
|
2437
|
+
P0: prevPos,
|
|
2438
|
+
P1,
|
|
2439
|
+
P2,
|
|
2440
|
+
P3: nextPos,
|
|
2441
|
+
lut,
|
|
2442
|
+
totalArc: lut.ds[lut.ds.length - 1]
|
|
2443
|
+
};
|
|
2444
|
+
_segmentCache.set(prevKf, entry);
|
|
2445
|
+
return entry;
|
|
2446
|
+
}
|
|
2447
|
+
function evaluateMotionPathSegment(prevKf, nextKf, prevPos, nextPos, localProgress, autoOrient) {
|
|
2448
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
2449
|
+
const t = seg.totalArc === 0 ? localProgress : tFromArcFraction(seg.lut, localProgress);
|
|
2450
|
+
const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2451
|
+
if (!autoOrient) return { translate: point };
|
|
2452
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2453
|
+
const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
2454
|
+
return { translate: point, rotateDeg };
|
|
2455
|
+
}
|
|
2456
|
+
function tFromArcFraction(lut, arcFrac) {
|
|
2457
|
+
const total = lut.ds[lut.ds.length - 1];
|
|
2458
|
+
const target = arcFrac * total;
|
|
2459
|
+
const { ts, ds } = lut;
|
|
2460
|
+
const last = ds.length - 1;
|
|
2461
|
+
if (target <= 0) return ts[0];
|
|
2462
|
+
if (target >= ds[last]) return ts[last];
|
|
2463
|
+
let lo = 1, hi = last;
|
|
2464
|
+
while (lo < hi) {
|
|
2465
|
+
const mid = lo + hi >>> 1;
|
|
2466
|
+
if (ds[mid] < target) lo = mid + 1;
|
|
2467
|
+
else hi = mid;
|
|
2468
|
+
}
|
|
2469
|
+
const dPrev = ds[hi - 1];
|
|
2470
|
+
const span = ds[hi] - dPrev;
|
|
2471
|
+
const frac = span > 0 ? (target - dPrev) / span : 0;
|
|
2472
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
2473
|
+
}
|
|
2474
|
+
var DEFAULT_FLATNESS_TOL = 0.5;
|
|
2475
|
+
var DEFAULT_ROTATION_TOL = 5;
|
|
2476
|
+
var DEFAULT_MAX_SAMPLES = 32;
|
|
2477
|
+
function materialiseMotionPathInPropAnim(anim, opts) {
|
|
2478
|
+
var _a, _b, _c, _d;
|
|
2479
|
+
if (!propAnimIsMotionPath(anim)) return anim;
|
|
2480
|
+
const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
|
|
2481
|
+
if (!Array.isArray(kfs) || kfs.length < 2) return anim;
|
|
2482
|
+
const autoOrient = !!anim.autoOrient;
|
|
2483
|
+
const flatnessTol = (_b = opts == null ? void 0 : opts.flatnessTolerance) != null ? _b : DEFAULT_FLATNESS_TOL;
|
|
2484
|
+
const rotationTol = (_c = opts == null ? void 0 : opts.rotationTolerance) != null ? _c : DEFAULT_ROTATION_TOL;
|
|
2485
|
+
const maxSamples = (_d = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _d : DEFAULT_MAX_SAMPLES;
|
|
2486
|
+
const out = [];
|
|
2487
|
+
const firstPos = getKfTranslate(kfs[0]);
|
|
2488
|
+
if (!firstPos) return anim;
|
|
2489
|
+
const firstRotate = autoOrient ? derivAngleForFirstKf(kfs[0], kfs[1]) : void 0;
|
|
2490
|
+
out.push(makeOutKf(
|
|
2491
|
+
getKfTime(kfs[0]),
|
|
2492
|
+
buildOutKfValue(getKfValueParts(kfs[0]), getKfValueParts(kfs[0]), 0, firstPos, firstRotate, autoOrient)
|
|
2493
|
+
));
|
|
2494
|
+
for (let i = 0; i < kfs.length - 1; i++) {
|
|
2495
|
+
const prevKf = kfs[i];
|
|
2496
|
+
const nextKf = kfs[i + 1];
|
|
2497
|
+
const prevPos = getKfTranslate(prevKf);
|
|
2498
|
+
const nextPos = getKfTranslate(nextKf);
|
|
2499
|
+
if (!prevPos || !nextPos) {
|
|
2500
|
+
out.push(makeOutKf(
|
|
2501
|
+
getKfTime(nextKf),
|
|
2502
|
+
buildOutKfValue(getKfValueParts(nextKf), getKfValueParts(nextKf), 1, nextPos != null ? nextPos : [0, 0], void 0, autoOrient)
|
|
2503
|
+
));
|
|
2504
|
+
continue;
|
|
790
2505
|
}
|
|
791
|
-
if (
|
|
792
|
-
|
|
2506
|
+
if (autoOrient && i > 0) {
|
|
2507
|
+
insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
|
|
793
2508
|
}
|
|
794
|
-
|
|
2509
|
+
materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
|
|
795
2510
|
}
|
|
796
|
-
|
|
2511
|
+
const lastInE = getKfEasing(kfs[kfs.length - 1]);
|
|
2512
|
+
if (lastInE) out[out.length - 1].e = lastInE;
|
|
2513
|
+
if (autoOrient) unwrapAutoOrientRotations(out);
|
|
2514
|
+
const result = { kfs: out };
|
|
2515
|
+
if (anim.loop !== void 0) result.loop = anim.loop;
|
|
2516
|
+
return result;
|
|
797
2517
|
}
|
|
798
|
-
function
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
for (const
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
if (style) {
|
|
808
|
-
for (const styleProp in style) {
|
|
809
|
-
element.style[styleProp] = String(style[styleProp]);
|
|
2518
|
+
function unwrapAutoOrientRotations(kfs) {
|
|
2519
|
+
var _a;
|
|
2520
|
+
let prev;
|
|
2521
|
+
for (const kf of kfs) {
|
|
2522
|
+
const v = (_a = kf.v) != null ? _a : kf.value;
|
|
2523
|
+
if (!v || typeof v.rotate !== "number") continue;
|
|
2524
|
+
if (prev === void 0) {
|
|
2525
|
+
prev = v.rotate;
|
|
2526
|
+
continue;
|
|
810
2527
|
}
|
|
2528
|
+
let r = v.rotate;
|
|
2529
|
+
while (r - prev > 180) r -= 360;
|
|
2530
|
+
while (r - prev < -180) r += 360;
|
|
2531
|
+
v.rotate = r;
|
|
2532
|
+
prev = r;
|
|
811
2533
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
2534
|
+
}
|
|
2535
|
+
function makeOutKf(time, value) {
|
|
2536
|
+
return { t: time, v: value };
|
|
2537
|
+
}
|
|
2538
|
+
function getKfValueParts(kf) {
|
|
2539
|
+
var _a;
|
|
2540
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
2541
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
|
|
2542
|
+
return v;
|
|
2543
|
+
}
|
|
2544
|
+
function interpolatePart(prev, next, p) {
|
|
2545
|
+
if (prev === void 0) return next;
|
|
2546
|
+
if (next === void 0) return prev;
|
|
2547
|
+
if (typeof prev === "number" && typeof next === "number") {
|
|
2548
|
+
return prev + (next - prev) * p;
|
|
2549
|
+
}
|
|
2550
|
+
if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {
|
|
2551
|
+
const out = new Array(prev.length);
|
|
2552
|
+
for (let i = 0; i < prev.length; i++) {
|
|
2553
|
+
const a = typeof prev[i] === "number" ? prev[i] : 0;
|
|
2554
|
+
const b = typeof next[i] === "number" ? next[i] : 0;
|
|
2555
|
+
out[i] = a + (b - a) * p;
|
|
815
2556
|
}
|
|
2557
|
+
return out;
|
|
816
2558
|
}
|
|
817
|
-
|
|
818
|
-
return element;
|
|
2559
|
+
return p < 0.5 ? prev : next;
|
|
819
2560
|
}
|
|
820
|
-
function
|
|
2561
|
+
function buildOutKfValue(prevV, nextV, p, translate, rotateDegFromAutoOrient, autoOrient) {
|
|
2562
|
+
const value = { translate };
|
|
2563
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2564
|
+
if (prevV) for (const k of Object.keys(prevV)) keys.add(k);
|
|
2565
|
+
if (nextV) for (const k of Object.keys(nextV)) keys.add(k);
|
|
2566
|
+
for (const k of keys) {
|
|
2567
|
+
if (k === "translate") continue;
|
|
2568
|
+
if (k === "rotate" && autoOrient) continue;
|
|
2569
|
+
const pv = prevV == null ? void 0 : prevV[k];
|
|
2570
|
+
const nv = nextV == null ? void 0 : nextV[k];
|
|
2571
|
+
if (pv === void 0 && nv === void 0) continue;
|
|
2572
|
+
value[k] = interpolatePart(pv, nv, p);
|
|
2573
|
+
}
|
|
2574
|
+
if (rotateDegFromAutoOrient !== void 0) value.rotate = rotateDegFromAutoOrient;
|
|
2575
|
+
return value;
|
|
2576
|
+
}
|
|
2577
|
+
function derivAngleForFirstKf(kf0, kf1) {
|
|
2578
|
+
const p0 = getKfTranslate(kf0);
|
|
2579
|
+
const p1 = getKfTranslate(kf1);
|
|
2580
|
+
if (!p0 || !p1) return 0;
|
|
2581
|
+
const seg = getSegmentCache(kf0, kf1, p0, p1);
|
|
2582
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
2583
|
+
return Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
2584
|
+
}
|
|
2585
|
+
function wrappedAngleDelta(a, b) {
|
|
2586
|
+
let d = a - b;
|
|
2587
|
+
while (d > 180) d -= 360;
|
|
2588
|
+
while (d < -180) d += 360;
|
|
2589
|
+
return d;
|
|
2590
|
+
}
|
|
2591
|
+
function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
|
|
821
2592
|
var _a;
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
2593
|
+
const lastKf = out[out.length - 1];
|
|
2594
|
+
const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
|
|
2595
|
+
const prevExit = lastV == null ? void 0 : lastV.rotate;
|
|
2596
|
+
if (typeof prevExit !== "number") return;
|
|
2597
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
2598
|
+
const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
2599
|
+
const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;
|
|
2600
|
+
const delta = wrappedAngleDelta(nextEntry, prevExit);
|
|
2601
|
+
if (Math.abs(delta) <= rotationTol) return;
|
|
2602
|
+
const dupValue = buildOutKfValue(
|
|
2603
|
+
getKfValueParts(prevKf),
|
|
2604
|
+
getKfValueParts(prevKf),
|
|
2605
|
+
0,
|
|
2606
|
+
prevPos,
|
|
2607
|
+
nextEntry,
|
|
2608
|
+
true
|
|
2609
|
+
);
|
|
2610
|
+
out.push(makeOutKf(getKfTime(prevKf), dupValue));
|
|
2611
|
+
}
|
|
2612
|
+
function materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
|
|
2613
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
2614
|
+
const prevTime = getKfTime(prevKf);
|
|
2615
|
+
const nextTime = getKfTime(nextKf);
|
|
2616
|
+
const prevEasing = getKfEasing(prevKf);
|
|
2617
|
+
const invertFn = invertEasing(prevEasing);
|
|
2618
|
+
const prevV = getKfValueParts(prevKf);
|
|
2619
|
+
const nextV = getKfValueParts(nextKf);
|
|
2620
|
+
const interiorTs = computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples);
|
|
2621
|
+
const samples = [];
|
|
2622
|
+
for (const t of interiorTs) {
|
|
2623
|
+
const arc = bezier2D_arcAtT(seg.lut, t);
|
|
2624
|
+
const p = clamp(seg.totalArc > 0 ? arc / seg.totalArc : t, 0, 1);
|
|
2625
|
+
const u = clamp(invertFn(p), 0, 1);
|
|
2626
|
+
const pos = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2627
|
+
const sample = { u, p, pos };
|
|
2628
|
+
if (autoOrient) {
|
|
2629
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2630
|
+
sample.rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
2631
|
+
}
|
|
2632
|
+
samples.push(sample);
|
|
2633
|
+
}
|
|
2634
|
+
let remaining = prevEasing;
|
|
2635
|
+
let prevU = 0;
|
|
2636
|
+
const startIdx = out.length - 1;
|
|
2637
|
+
for (let i = 0; i < samples.length; i++) {
|
|
2638
|
+
const s = samples[i];
|
|
2639
|
+
const xFrac = prevU < 1 ? clamp((s.u - prevU) / (1 - prevU), 0, 1) : 1;
|
|
2640
|
+
const { left, right } = splitEasing(remaining, xFrac);
|
|
2641
|
+
const ownerIdx = i === 0 ? startIdx : out.length - 1;
|
|
2642
|
+
if (left) out[ownerIdx].e = left;
|
|
2643
|
+
else delete out[ownerIdx].e;
|
|
2644
|
+
const tGlobal = prevTime + s.u * (nextTime - prevTime);
|
|
2645
|
+
const value = buildOutKfValue(prevV, nextV, s.p, s.pos, s.rotateDeg, autoOrient);
|
|
2646
|
+
out.push(makeOutKf(tGlobal, value));
|
|
2647
|
+
remaining = right;
|
|
2648
|
+
prevU = s.u;
|
|
825
2649
|
}
|
|
826
|
-
return style;
|
|
827
2650
|
}
|
|
828
|
-
function
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
if (Array.isArray(value)) {
|
|
838
|
-
if (key === "translate") value = value.map((v) => v + "px");
|
|
839
|
-
value = value.join(",");
|
|
840
|
-
}
|
|
841
|
-
if (key === "rotate") value = value + "deg";
|
|
842
|
-
propsCopy["transform"] = key + "(" + value + ")";
|
|
843
|
-
} else if (value !== void 0 && value !== null) {
|
|
844
|
-
propsCopy[key] = String(value);
|
|
2651
|
+
function computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples) {
|
|
2652
|
+
const extremes = [];
|
|
2653
|
+
addAxisExtremes(seg.P0[0], seg.P1[0], seg.P2[0], seg.P3[0], extremes);
|
|
2654
|
+
addAxisExtremes(seg.P0[1], seg.P1[1], seg.P2[1], seg.P3[1], extremes);
|
|
2655
|
+
extremes.sort((a, b) => a - b);
|
|
2656
|
+
const critical = [0];
|
|
2657
|
+
for (const t of extremes) {
|
|
2658
|
+
if (t > critical[critical.length - 1] + 1e-6 && t < 1 - 1e-6) {
|
|
2659
|
+
critical.push(t);
|
|
845
2660
|
}
|
|
846
2661
|
}
|
|
847
|
-
|
|
2662
|
+
critical.push(1);
|
|
2663
|
+
const out = [];
|
|
2664
|
+
const budget = { remaining: maxSamples - critical.length };
|
|
2665
|
+
for (let i = 0; i < critical.length - 1; i++) {
|
|
2666
|
+
bisect(critical[i], critical[i + 1], out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
2667
|
+
}
|
|
2668
|
+
return out;
|
|
848
2669
|
}
|
|
849
|
-
function
|
|
850
|
-
|
|
851
|
-
const
|
|
852
|
-
const
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
childElements.push(child);
|
|
861
|
-
}
|
|
2670
|
+
function addAxisExtremes(p0, p1, p2, p3, out) {
|
|
2671
|
+
const a = p1 - p0;
|
|
2672
|
+
const b = p2 - p1;
|
|
2673
|
+
const c = p3 - p2;
|
|
2674
|
+
const A = a - 2 * b + c;
|
|
2675
|
+
const B = 2 * (b - a);
|
|
2676
|
+
const C = a;
|
|
2677
|
+
if (Math.abs(A) < 1e-10) {
|
|
2678
|
+
if (Math.abs(B) > 1e-10) {
|
|
2679
|
+
const t = -C / B;
|
|
2680
|
+
if (t > 1e-6 && t < 1 - 1e-6) out.push(t);
|
|
862
2681
|
}
|
|
2682
|
+
return;
|
|
863
2683
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
2684
|
+
const disc = B * B - 4 * A * C;
|
|
2685
|
+
if (disc < 0) return;
|
|
2686
|
+
const sq = Math.sqrt(disc);
|
|
2687
|
+
const t1 = (-B - sq) / (2 * A);
|
|
2688
|
+
const t2 = (-B + sq) / (2 * A);
|
|
2689
|
+
if (t1 > 1e-6 && t1 < 1 - 1e-6) out.push(t1);
|
|
2690
|
+
if (t2 > 1e-6 && t2 < 1 - 1e-6) out.push(t2);
|
|
2691
|
+
}
|
|
2692
|
+
function bisect(tA, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget) {
|
|
2693
|
+
const tMid = (tA + tB) / 2;
|
|
2694
|
+
const pA = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
|
|
2695
|
+
const pB = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
|
|
2696
|
+
const span = tB - tA;
|
|
2697
|
+
const p25 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.25);
|
|
2698
|
+
const p50 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tMid);
|
|
2699
|
+
const p75 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.75);
|
|
2700
|
+
const dev = Math.max(
|
|
2701
|
+
perpDist(p25, pA, pB),
|
|
2702
|
+
perpDist(p50, pA, pB),
|
|
2703
|
+
perpDist(p75, pA, pB)
|
|
870
2704
|
);
|
|
2705
|
+
let rotOk = true;
|
|
2706
|
+
if (autoOrient) {
|
|
2707
|
+
const tanA = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
|
|
2708
|
+
const tanB = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
|
|
2709
|
+
const angA = Math.atan2(tanA[1], tanA[0]) * 180 / Math.PI;
|
|
2710
|
+
const angB = Math.atan2(tanB[1], tanB[0]) * 180 / Math.PI;
|
|
2711
|
+
let delta = Math.abs(angA - angB);
|
|
2712
|
+
if (delta > 180) delta = 360 - delta;
|
|
2713
|
+
if (delta > rotationTol) rotOk = false;
|
|
2714
|
+
}
|
|
2715
|
+
if (dev <= flatnessTol && rotOk || budget.remaining <= 0 || span < 1e-6) {
|
|
2716
|
+
out.push(tB);
|
|
2717
|
+
return;
|
|
2718
|
+
}
|
|
2719
|
+
budget.remaining -= 1;
|
|
2720
|
+
bisect(tA, tMid, out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
2721
|
+
bisect(tMid, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
871
2722
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
const
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
return
|
|
2723
|
+
function perpDist(q, pA, pB) {
|
|
2724
|
+
const dx = pB[0] - pA[0];
|
|
2725
|
+
const dy = pB[1] - pA[1];
|
|
2726
|
+
const len2 = dx * dx + dy * dy;
|
|
2727
|
+
if (len2 < 1e-20) {
|
|
2728
|
+
const qdx = q[0] - pA[0];
|
|
2729
|
+
const qdy = q[1] - pA[1];
|
|
2730
|
+
return Math.sqrt(qdx * qdx + qdy * qdy);
|
|
880
2731
|
}
|
|
881
|
-
const
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
break;
|
|
898
|
-
}
|
|
899
|
-
};
|
|
900
|
-
switch (startOn) {
|
|
901
|
-
case "load": {
|
|
902
|
-
const startHandler = () => start();
|
|
903
|
-
if (document.readyState === "complete") {
|
|
904
|
-
startHandler();
|
|
905
|
-
} else {
|
|
906
|
-
window.addEventListener("load", startHandler, { once: true });
|
|
2732
|
+
const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
|
|
2733
|
+
return Math.abs(cross) / Math.sqrt(len2);
|
|
2734
|
+
}
|
|
2735
|
+
function materialiseMotionPathsInTree(root, opts) {
|
|
2736
|
+
const out = walkAndMaterialise(root, opts);
|
|
2737
|
+
return out != null ? out : root;
|
|
2738
|
+
}
|
|
2739
|
+
function walkAndMaterialise(node, opts) {
|
|
2740
|
+
let newChildren;
|
|
2741
|
+
if (node.children) {
|
|
2742
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2743
|
+
const ch = node.children[i];
|
|
2744
|
+
const ret = walkAndMaterialise(ch, opts);
|
|
2745
|
+
if (ret !== null) {
|
|
2746
|
+
if (!newChildren) newChildren = node.children.slice();
|
|
2747
|
+
newChildren[i] = ret;
|
|
907
2748
|
}
|
|
908
|
-
break;
|
|
909
|
-
}
|
|
910
|
-
case "mouseOver": {
|
|
911
|
-
const mouseOverHandler = () => start();
|
|
912
|
-
const mouseOutHandler = () => handleEndAction();
|
|
913
|
-
root.addEventListener("mouseenter", mouseOverHandler);
|
|
914
|
-
root.addEventListener("mouseleave", mouseOutHandler);
|
|
915
|
-
break;
|
|
916
|
-
}
|
|
917
|
-
case "click": {
|
|
918
|
-
const clickHandler = () => {
|
|
919
|
-
if (api.isPlaying()) {
|
|
920
|
-
handleEndAction();
|
|
921
|
-
} else {
|
|
922
|
-
start();
|
|
923
|
-
}
|
|
924
|
-
};
|
|
925
|
-
root.addEventListener("click", clickHandler);
|
|
926
|
-
break;
|
|
927
2749
|
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
{ threshold: scrollIntoViewThreshold }
|
|
940
|
-
);
|
|
941
|
-
observer.observe(root);
|
|
942
|
-
break;
|
|
2750
|
+
}
|
|
2751
|
+
let newAnimate;
|
|
2752
|
+
const animBucket = node.animate;
|
|
2753
|
+
if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
|
|
2754
|
+
const animDef = animBucket;
|
|
2755
|
+
const transformAnim = animDef.transform;
|
|
2756
|
+
if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
|
|
2757
|
+
const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);
|
|
2758
|
+
if (materialised !== transformAnim) {
|
|
2759
|
+
newAnimate = __spreadProps(__spreadValues({}, animDef), { transform: materialised });
|
|
2760
|
+
}
|
|
943
2761
|
}
|
|
944
|
-
case "programmatic":
|
|
945
|
-
break;
|
|
946
2762
|
}
|
|
947
|
-
return
|
|
2763
|
+
if (!newChildren && !newAnimate) return null;
|
|
2764
|
+
const cloned = __spreadValues({}, node);
|
|
2765
|
+
if (newChildren) cloned.children = newChildren;
|
|
2766
|
+
if (newAnimate) cloned.animate = newAnimate;
|
|
2767
|
+
return cloned;
|
|
948
2768
|
}
|
|
949
2769
|
|
|
950
2770
|
// src/PxDefinitions.ts
|
|
@@ -1010,6 +2830,8 @@ function parseSvgPathToBezier(d) {
|
|
|
1010
2830
|
currentPath.o.push([x2, y2]);
|
|
1011
2831
|
} else if (type === "Z" || type === "z") {
|
|
1012
2832
|
currentPath.c = true;
|
|
2833
|
+
} else {
|
|
2834
|
+
console.warn('Unsupported path command "' + type + '"');
|
|
1013
2835
|
}
|
|
1014
2836
|
}
|
|
1015
2837
|
return res;
|
|
@@ -1027,13 +2849,17 @@ function isPathString(value) {
|
|
|
1027
2849
|
return typeof value === "string" && extractPathData(value) !== void 0;
|
|
1028
2850
|
}
|
|
1029
2851
|
function normalizePathValue(value) {
|
|
2852
|
+
if (value && typeof value === "object" && typeof value.path === "string") {
|
|
2853
|
+
const d = extractPathData(value.path);
|
|
2854
|
+
return d ? { paths: parseSvgPathToBezier(d) } : value;
|
|
2855
|
+
}
|
|
1030
2856
|
if (value && typeof value === "object" && "paths" in value) {
|
|
1031
2857
|
const pathsArray = value.paths;
|
|
1032
2858
|
if (Array.isArray(pathsArray) && pathsArray.length > 0) {
|
|
1033
2859
|
if (isPathString(pathsArray[0])) {
|
|
1034
2860
|
const paths = [];
|
|
1035
|
-
for (const
|
|
1036
|
-
const d = extractPathData(
|
|
2861
|
+
for (const pathStr2 of pathsArray) {
|
|
2862
|
+
const d = extractPathData(pathStr2);
|
|
1037
2863
|
if (d) {
|
|
1038
2864
|
paths.push(...parseSvgPathToBezier(d));
|
|
1039
2865
|
}
|
|
@@ -1046,8 +2872,8 @@ function normalizePathValue(value) {
|
|
|
1046
2872
|
if (Array.isArray(value)) {
|
|
1047
2873
|
if (value.length > 0 && isPathString(value[0])) {
|
|
1048
2874
|
const paths = [];
|
|
1049
|
-
for (const
|
|
1050
|
-
const d = extractPathData(
|
|
2875
|
+
for (const pathStr2 of value) {
|
|
2876
|
+
const d = extractPathData(pathStr2);
|
|
1051
2877
|
if (d) {
|
|
1052
2878
|
paths.push(...parseSvgPathToBezier(d));
|
|
1053
2879
|
}
|
|
@@ -1111,11 +2937,34 @@ function interpolateValue(propName, a, b, t) {
|
|
|
1111
2937
|
if (COLOUR_ATTR_NAMES.has(propName)) {
|
|
1112
2938
|
return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
|
|
1113
2939
|
}
|
|
2940
|
+
if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
|
|
2941
|
+
return interpolateTransformParts(a, b, t);
|
|
2942
|
+
}
|
|
2943
|
+
if (propName === "rotate" && typeof a === "number" && typeof b === "number") {
|
|
2944
|
+
return interpolateNum(a, b, t);
|
|
2945
|
+
}
|
|
1114
2946
|
if (TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
|
|
1115
2947
|
return interpolateVec(a || [], b || [], t);
|
|
1116
2948
|
}
|
|
1117
2949
|
return interpolateNum(+(a || 0), +(b || 0), t);
|
|
1118
2950
|
}
|
|
2951
|
+
function interpolateTransformParts(a, b, t) {
|
|
2952
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(a != null ? a : {}), ...Object.keys(b != null ? b : {})]);
|
|
2953
|
+
const out = {};
|
|
2954
|
+
for (const k of keys) {
|
|
2955
|
+
const av = a == null ? void 0 : a[k];
|
|
2956
|
+
const bv = b == null ? void 0 : b[k];
|
|
2957
|
+
if (k === "rotate") {
|
|
2958
|
+
out[k] = interpolateNum(+(av != null ? av : 0), +(bv != null ? bv : 0), t);
|
|
2959
|
+
} else if (k === "translate" || k === "scale" || k === "origin") {
|
|
2960
|
+
const fallback = k === "scale" ? [1, 1] : [0, 0];
|
|
2961
|
+
out[k] = interpolateVec(av || fallback, bv || fallback, t);
|
|
2962
|
+
} else {
|
|
2963
|
+
out[k] = bv != null ? bv : av;
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
return out;
|
|
2967
|
+
}
|
|
1119
2968
|
function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
1120
2969
|
var _a, _b, _c, _d, _e;
|
|
1121
2970
|
const totalIntervals = keyframes.length - 1;
|
|
@@ -1142,11 +2991,16 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
|
1142
2991
|
const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
|
|
1143
2992
|
const segDuration = segEndT - segStartT;
|
|
1144
2993
|
if (segDuration <= 0) return keyframes;
|
|
1145
|
-
const template = segKfs.map((kf) =>
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
2994
|
+
const template = segKfs.map((kf) => {
|
|
2995
|
+
var _a2, _b2;
|
|
2996
|
+
return {
|
|
2997
|
+
relT: (kf.t - segStartT) / segDuration,
|
|
2998
|
+
v: kf.v,
|
|
2999
|
+
e: kf.e,
|
|
3000
|
+
tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
|
|
3001
|
+
tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
|
|
3002
|
+
};
|
|
3003
|
+
});
|
|
1150
3004
|
const fullReps = Math.floor(fillDuration / segDuration);
|
|
1151
3005
|
const remainder = fillDuration - fullReps * segDuration;
|
|
1152
3006
|
const partialFraction = remainder / segDuration;
|
|
@@ -1160,7 +3014,12 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
|
1160
3014
|
relT: 1 - template[i].relT,
|
|
1161
3015
|
v: template[i].v,
|
|
1162
3016
|
// Easing for reversed transition: use reversed easing from the forward "from" keyframe
|
|
1163
|
-
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0
|
|
3017
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
3018
|
+
// Reversed traversal swaps each vertex's in/out spatial tangents
|
|
3019
|
+
// (geometry is identical, walked backwards), so curvature and
|
|
3020
|
+
// auto-orientation survive the reversed rep.
|
|
3021
|
+
tangentIn: template[i].tangentOut,
|
|
3022
|
+
tangentOut: template[i].tangentIn
|
|
1164
3023
|
});
|
|
1165
3024
|
}
|
|
1166
3025
|
} else {
|
|
@@ -1182,11 +3041,14 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
|
1182
3041
|
looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
|
|
1183
3042
|
return;
|
|
1184
3043
|
}
|
|
1185
|
-
|
|
3044
|
+
const pushed = {
|
|
1186
3045
|
t: repStart + entry.relT * segDuration,
|
|
1187
3046
|
v: entry.v,
|
|
1188
3047
|
e: i < entries.length - 1 ? entry.e : void 0
|
|
1189
|
-
}
|
|
3048
|
+
};
|
|
3049
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
3050
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
3051
|
+
looped.push(pushed);
|
|
1190
3052
|
}
|
|
1191
3053
|
}
|
|
1192
3054
|
for (let rep = 0; rep < fullReps; rep++) {
|
|
@@ -1207,7 +3069,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
|
1207
3069
|
}
|
|
1208
3070
|
}
|
|
1209
3071
|
function normalizeKeyframes(propName, propAnim, duration, defs) {
|
|
1210
|
-
var _a, _b, _c, _d, _e;
|
|
3072
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1211
3073
|
const keyframes = propAnim.keyframes || propAnim.kfs || [];
|
|
1212
3074
|
const normalized = [];
|
|
1213
3075
|
for (const kf of keyframes) {
|
|
@@ -1217,14 +3079,20 @@ function normalizeKeyframes(propName, propAnim, duration, defs) {
|
|
|
1217
3079
|
if (propName === "d") {
|
|
1218
3080
|
value = normalizePathValue(value);
|
|
1219
3081
|
}
|
|
1220
|
-
|
|
3082
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
3083
|
+
if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
|
|
1221
3084
|
value = (_e = parseColor(value)) != null ? _e : value;
|
|
1222
3085
|
}
|
|
1223
|
-
|
|
3086
|
+
const normKf = {
|
|
1224
3087
|
t: timePct,
|
|
1225
3088
|
v: value,
|
|
1226
3089
|
e: resolveEasing(easing, defs)
|
|
1227
|
-
}
|
|
3090
|
+
};
|
|
3091
|
+
const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
|
|
3092
|
+
const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
|
|
3093
|
+
if (tIn) normKf.tangentIn = tIn;
|
|
3094
|
+
if (tOut) normKf.tangentOut = tOut;
|
|
3095
|
+
normalized.push(normKf);
|
|
1228
3096
|
}
|
|
1229
3097
|
normalized.sort((a, b) => {
|
|
1230
3098
|
var _a2, _b2;
|
|
@@ -1246,21 +3114,84 @@ function mergeAnimationDefinitions(animations) {
|
|
|
1246
3114
|
}
|
|
1247
3115
|
return merged;
|
|
1248
3116
|
}
|
|
3117
|
+
function materialiseInternalLoopsInPropAnim(propName, propAnim, duration) {
|
|
3118
|
+
var _a;
|
|
3119
|
+
const loopRaw = propAnim.loop;
|
|
3120
|
+
if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
|
|
3121
|
+
const loop = loopRaw === true ? {} : loopRaw;
|
|
3122
|
+
const rawKfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
|
|
3123
|
+
if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
|
|
3124
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
3125
|
+
const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);
|
|
3126
|
+
const kfs = rawKfs.map((kf) => {
|
|
3127
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
3128
|
+
const t = (_a2 = kf.t) != null ? _a2 : kf.time;
|
|
3129
|
+
let v = (_b = kf.v) != null ? _b : kf.value;
|
|
3130
|
+
if (propName === "d") v = normalizePathValue(v);
|
|
3131
|
+
if (isColour) v = (_c = parseColor(v)) != null ? _c : v;
|
|
3132
|
+
const e = (_d = kf.e) != null ? _d : kf.easing;
|
|
3133
|
+
const out2 = { t, v, e };
|
|
3134
|
+
if ((_e = kf.tangentIn) != null ? _e : kf.ti) out2.tangentIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
|
|
3135
|
+
if ((_g = kf.tangentOut) != null ? _g : kf.to) out2.tangentOut = (_h = kf.tangentOut) != null ? _h : kf.to;
|
|
3136
|
+
return out2;
|
|
3137
|
+
});
|
|
3138
|
+
const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
|
|
3139
|
+
const out = { kfs: expanded };
|
|
3140
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
3141
|
+
return out;
|
|
3142
|
+
}
|
|
3143
|
+
function materialiseInternalLoopsInTree(root, duration) {
|
|
3144
|
+
const ret = walkAndMaterialiseLoops(root, duration);
|
|
3145
|
+
return ret != null ? ret : root;
|
|
3146
|
+
}
|
|
3147
|
+
function walkAndMaterialiseLoops(node, duration) {
|
|
3148
|
+
let newChildren;
|
|
3149
|
+
if (node.children) {
|
|
3150
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
3151
|
+
const ret = walkAndMaterialiseLoops(node.children[i], duration);
|
|
3152
|
+
if (ret !== null) {
|
|
3153
|
+
if (!newChildren) newChildren = node.children.slice();
|
|
3154
|
+
newChildren[i] = ret;
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
let newAnimate;
|
|
3159
|
+
const animBucket = node.animate;
|
|
3160
|
+
if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
|
|
3161
|
+
const animDef = animBucket;
|
|
3162
|
+
for (const propName of Object.keys(animDef)) {
|
|
3163
|
+
const propAnim = animDef[propName];
|
|
3164
|
+
const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);
|
|
3165
|
+
if (materialised !== propAnim) {
|
|
3166
|
+
if (!newAnimate) newAnimate = __spreadValues({}, animDef);
|
|
3167
|
+
newAnimate[propName] = materialised;
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
if (!newChildren && !newAnimate) return null;
|
|
3172
|
+
const cloned = __spreadValues({}, node);
|
|
3173
|
+
if (newChildren) cloned.children = newChildren;
|
|
3174
|
+
if (newAnimate) cloned.animate = newAnimate;
|
|
3175
|
+
return cloned;
|
|
3176
|
+
}
|
|
1249
3177
|
var _elementIdCounter = 0;
|
|
1250
3178
|
function generateElementId() {
|
|
1251
3179
|
return "_px_el_" + ++_elementIdCounter;
|
|
1252
3180
|
}
|
|
1253
|
-
function normalizeAnimationDefinition(animDef, duration, defs) {
|
|
3181
|
+
function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.webapi) {
|
|
1254
3182
|
const normalized = {};
|
|
1255
3183
|
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
1256
3184
|
const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
|
|
1257
3185
|
if (normalizedKfs.length > 0) {
|
|
1258
|
-
|
|
3186
|
+
const out = { kfs: normalizedKfs };
|
|
3187
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
3188
|
+
if (propAnim.loop !== void 0) out.loop = propAnim.loop;
|
|
3189
|
+
normalized[propName] = engine === PxAnimatorEngine.webapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
|
|
1259
3190
|
}
|
|
1260
3191
|
}
|
|
1261
3192
|
return normalized;
|
|
1262
3193
|
}
|
|
1263
|
-
function getNormalisedBindings(doc) {
|
|
3194
|
+
function getNormalisedBindings(doc, engine = PxAnimatorEngine.webapi) {
|
|
1264
3195
|
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
1265
3196
|
const defs = getDefs(doc);
|
|
1266
3197
|
const duration = animatorConfig.duration || 1e3;
|
|
@@ -1270,7 +3201,7 @@ function getNormalisedBindings(doc) {
|
|
|
1270
3201
|
const animDefs = resolveElementAnimation(animate, defs);
|
|
1271
3202
|
if (animDefs.length === 0) return null;
|
|
1272
3203
|
const merged = mergeAnimationDefinitions(animDefs);
|
|
1273
|
-
const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs);
|
|
3204
|
+
const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
|
|
1274
3205
|
if (Object.keys(normalizedAnim).length === 0) return null;
|
|
1275
3206
|
return {
|
|
1276
3207
|
id,
|
|
@@ -1285,10 +3216,11 @@ function getNormalisedBindings(doc) {
|
|
|
1285
3216
|
}
|
|
1286
3217
|
}
|
|
1287
3218
|
const processNode = (node) => {
|
|
1288
|
-
|
|
3219
|
+
const inlineAnim = node.animate;
|
|
3220
|
+
if (inlineAnim && Object.keys(inlineAnim).length > 0) {
|
|
1289
3221
|
const nodeId = node.id || generateElementId();
|
|
1290
3222
|
node.id = nodeId;
|
|
1291
|
-
const normalized = processAnimation(nodeId,
|
|
3223
|
+
const normalized = processAnimation(nodeId, inlineAnim);
|
|
1292
3224
|
if (normalized) bindings.push(normalized);
|
|
1293
3225
|
}
|
|
1294
3226
|
if (node.children) {
|
|
@@ -1296,115 +3228,870 @@ function getNormalisedBindings(doc) {
|
|
|
1296
3228
|
processNode(node.children[i]);
|
|
1297
3229
|
}
|
|
1298
3230
|
}
|
|
1299
|
-
};
|
|
1300
|
-
if (doc.children) {
|
|
1301
|
-
for (let i = 0; i < doc.children.length; i++) {
|
|
1302
|
-
processNode(doc.children[i]);
|
|
1303
|
-
}
|
|
3231
|
+
};
|
|
3232
|
+
if (doc.children) {
|
|
3233
|
+
for (let i = 0; i < doc.children.length; i++) {
|
|
3234
|
+
processNode(doc.children[i]);
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
return bindings;
|
|
3238
|
+
}
|
|
3239
|
+
function getKeyframesPair(keyframes, progress) {
|
|
3240
|
+
var _a, _b;
|
|
3241
|
+
let prevKf = keyframes[0];
|
|
3242
|
+
let nextKf = keyframes[keyframes.length - 1];
|
|
3243
|
+
for (let j = 0; j < keyframes.length - 1; j++) {
|
|
3244
|
+
const aOff = (_a = keyframes[j].t) != null ? _a : 0;
|
|
3245
|
+
const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
|
|
3246
|
+
if (aOff <= progress && progress <= bOff) {
|
|
3247
|
+
prevKf = keyframes[j];
|
|
3248
|
+
nextKf = keyframes[j + 1];
|
|
3249
|
+
break;
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
return { prevKf, nextKf };
|
|
3253
|
+
}
|
|
3254
|
+
function calcPropertyValue(propName, propAnim, progress) {
|
|
3255
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
3256
|
+
const keyframes = propAnim.kfs || propAnim.keyframes || [];
|
|
3257
|
+
if (keyframes.length === 0) return null;
|
|
3258
|
+
const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
|
|
3259
|
+
let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
|
|
3260
|
+
localProgress = clamp(localProgress, 0, 1);
|
|
3261
|
+
const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
|
|
3262
|
+
if (easing && Array.isArray(easing)) {
|
|
3263
|
+
try {
|
|
3264
|
+
localProgress = cubicBezier(easing)(localProgress);
|
|
3265
|
+
} catch (e) {
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
3269
|
+
let cssValue = null;
|
|
3270
|
+
const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
|
|
3271
|
+
const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
|
|
3272
|
+
if (cssAttrName === "d") {
|
|
3273
|
+
const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
|
|
3274
|
+
const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
|
|
3275
|
+
cssValue = interpolateBeziers(
|
|
3276
|
+
prevPaths,
|
|
3277
|
+
nextPaths,
|
|
3278
|
+
localProgress
|
|
3279
|
+
).map((bz) => bezierToSvgPath(bz)).join("");
|
|
3280
|
+
} else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {
|
|
3281
|
+
cssValue = toRGBA(interpolateColor(
|
|
3282
|
+
prevV || [0, 0, 0, 1],
|
|
3283
|
+
nextV || [0, 0, 0, 1],
|
|
3284
|
+
localProgress
|
|
3285
|
+
));
|
|
3286
|
+
cssAttrName = propName;
|
|
3287
|
+
} else if (cssAttrName === "stroke-dasharray") {
|
|
3288
|
+
cssValue = interpolateVec(
|
|
3289
|
+
prevV || [],
|
|
3290
|
+
nextV || [],
|
|
3291
|
+
localProgress
|
|
3292
|
+
).join(" ");
|
|
3293
|
+
cssAttrName = propName;
|
|
3294
|
+
} else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
|
|
3295
|
+
const partKeys = /* @__PURE__ */ new Set([
|
|
3296
|
+
...prevV ? Object.keys(prevV) : [],
|
|
3297
|
+
...nextV ? Object.keys(nextV) : []
|
|
3298
|
+
]);
|
|
3299
|
+
const partsResult = {};
|
|
3300
|
+
for (const partKey of partKeys) {
|
|
3301
|
+
const prevPart = prevV == null ? void 0 : prevV[partKey];
|
|
3302
|
+
const nextPart = nextV == null ? void 0 : nextV[partKey];
|
|
3303
|
+
if (partKey === "rotate") {
|
|
3304
|
+
partsResult.rotate = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
|
|
3305
|
+
} else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
|
|
3306
|
+
const fallback = partKey === "scale" ? [1, 1] : [0, 0];
|
|
3307
|
+
const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
|
|
3308
|
+
partsResult[partKey] = interp;
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
if (propAnimIsMotionPath(propAnim)) {
|
|
3312
|
+
const prevTr = prevV.translate;
|
|
3313
|
+
const nextTr = nextV.translate;
|
|
3314
|
+
if (Array.isArray(prevTr) && Array.isArray(nextTr)) {
|
|
3315
|
+
const sample = evaluateMotionPathSegment(
|
|
3316
|
+
prevKf,
|
|
3317
|
+
nextKf,
|
|
3318
|
+
[+prevTr[0], +prevTr[1]],
|
|
3319
|
+
[+nextTr[0], +nextTr[1]],
|
|
3320
|
+
localProgress,
|
|
3321
|
+
!!propAnim.autoOrient
|
|
3322
|
+
);
|
|
3323
|
+
partsResult.translate = [sample.translate[0], sample.translate[1]];
|
|
3324
|
+
if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
cssValue = composeTransformParts(partsResult, { withUnits: false });
|
|
3328
|
+
cssAttrName = "transform";
|
|
3329
|
+
} else if (cssAttrName === "translate") {
|
|
3330
|
+
const v = interpolateVec(
|
|
3331
|
+
prevV || [0, 0],
|
|
3332
|
+
nextV || [0, 0],
|
|
3333
|
+
localProgress
|
|
3334
|
+
);
|
|
3335
|
+
cssValue = "translate(" + v.join(",") + ")";
|
|
3336
|
+
cssAttrName = "transform";
|
|
3337
|
+
} else if (cssAttrName === "rotate") {
|
|
3338
|
+
const v = interpolateNum(
|
|
3339
|
+
+(prevV || 0),
|
|
3340
|
+
+(nextV || 0),
|
|
3341
|
+
localProgress
|
|
3342
|
+
);
|
|
3343
|
+
cssValue = "rotate(" + v + ")";
|
|
3344
|
+
cssAttrName = "transform";
|
|
3345
|
+
} else if (cssAttrName === "scale") {
|
|
3346
|
+
const v = interpolateVec(
|
|
3347
|
+
prevV || [1, 1],
|
|
3348
|
+
nextV || [1, 1],
|
|
3349
|
+
localProgress
|
|
3350
|
+
);
|
|
3351
|
+
cssValue = "scale(" + v.join(",") + ")";
|
|
3352
|
+
cssAttrName = "transform";
|
|
3353
|
+
} else {
|
|
3354
|
+
const num2 = interpolateNum(
|
|
3355
|
+
+(prevV || 0),
|
|
3356
|
+
+(nextV || 0),
|
|
3357
|
+
localProgress
|
|
3358
|
+
);
|
|
3359
|
+
cssValue = num2;
|
|
3360
|
+
}
|
|
3361
|
+
if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
|
|
3362
|
+
cssValue = cssValue * 100 + "%";
|
|
3363
|
+
}
|
|
3364
|
+
return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
|
|
3365
|
+
}
|
|
3366
|
+
function calcAnimationValues(animDef, progress) {
|
|
3367
|
+
const result = {};
|
|
3368
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
3369
|
+
const computed = calcPropertyValue(propName, propAnim, progress);
|
|
3370
|
+
if (computed) {
|
|
3371
|
+
result[computed.k] = computed.v;
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
return result;
|
|
3375
|
+
}
|
|
3376
|
+
|
|
3377
|
+
// src/effects/trimPathEffect.ts
|
|
3378
|
+
function applyTrimPathEffect(node, trimPath, isCombinedShape, ctx) {
|
|
3379
|
+
if (!trimPath) return node;
|
|
3380
|
+
const trimAllAsOne = !!trimPath.trimAllAsOne;
|
|
3381
|
+
const leafEntries = [];
|
|
3382
|
+
let acc = 0;
|
|
3383
|
+
const measure = (n) => {
|
|
3384
|
+
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
3385
|
+
for (const ch of n.children) measure(ch);
|
|
3386
|
+
return;
|
|
3387
|
+
}
|
|
3388
|
+
const d = typeof n.d === "string" ? n.d : rectToPathD(n);
|
|
3389
|
+
if (d === void 0) return;
|
|
3390
|
+
const subpaths = parseSvgPathToBezier(d);
|
|
3391
|
+
if (!subpaths.length) return;
|
|
3392
|
+
const entry = { leaf: n, subpaths: [] };
|
|
3393
|
+
for (const sp of subpaths) {
|
|
3394
|
+
if (!trimAllAsOne) acc = 0;
|
|
3395
|
+
const lengthPx = pxBezierPathLength(sp);
|
|
3396
|
+
entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: acc });
|
|
3397
|
+
acc += lengthPx;
|
|
3398
|
+
}
|
|
3399
|
+
leafEntries.push(entry);
|
|
3400
|
+
};
|
|
3401
|
+
measure(node);
|
|
3402
|
+
if (!leafEntries.length) return node;
|
|
3403
|
+
const chainLengthPx = acc;
|
|
3404
|
+
if (trimAllAsOne && chainLengthPx < 1e-3) return node;
|
|
3405
|
+
const offsetReadRaw = readAnimatable(trimPath.offset);
|
|
3406
|
+
const offsetRead = offsetReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: 0 } : offsetReadRaw;
|
|
3407
|
+
const rangeReadRaw = readRangeWithCrossings(trimPath.range);
|
|
3408
|
+
const rangeRead = rangeReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: [0, 1] } : rangeReadRaw;
|
|
3409
|
+
const offsetValues = readScalarValues(offsetRead);
|
|
3410
|
+
const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;
|
|
3411
|
+
const maxOffset = offsetValues.length ? Math.max(...offsetValues) : 0;
|
|
3412
|
+
const minMaxOffset = [minOffset, maxOffset];
|
|
3413
|
+
if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
|
|
3414
|
+
const entry = leafEntries[0];
|
|
3415
|
+
const sp = entry.subpaths[0];
|
|
3416
|
+
const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
|
|
3417
|
+
if (pathLengthPx < 1e-3) return node;
|
|
3418
|
+
const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
|
|
3419
|
+
return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
|
|
3420
|
+
}
|
|
3421
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
3422
|
+
for (const entry of leafEntries) {
|
|
3423
|
+
const newChildren = [];
|
|
3424
|
+
for (const sp of entry.subpaths) {
|
|
3425
|
+
const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;
|
|
3426
|
+
if (pathLengthPx < 1e-3) continue;
|
|
3427
|
+
const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;
|
|
3428
|
+
newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
|
|
3429
|
+
}
|
|
3430
|
+
replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
|
|
3431
|
+
}
|
|
3432
|
+
const swap = (n) => {
|
|
3433
|
+
const r = replacements.get(n);
|
|
3434
|
+
if (r) return r;
|
|
3435
|
+
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
3436
|
+
return __spreadProps(__spreadValues({}, n), { children: n.children.map(swap) });
|
|
3437
|
+
}
|
|
3438
|
+
return n;
|
|
3439
|
+
};
|
|
3440
|
+
return swap(node);
|
|
3441
|
+
}
|
|
3442
|
+
function wrapLeafAsGroup(leaf, children) {
|
|
3443
|
+
const wrapper = __spreadProps(__spreadValues({}, leaf), { type: "g", children });
|
|
3444
|
+
delete wrapper.d;
|
|
3445
|
+
delete wrapper.strokeDasharray;
|
|
3446
|
+
delete wrapper.strokeDashoffset;
|
|
3447
|
+
delete wrapper.effects;
|
|
3448
|
+
return wrapper;
|
|
3449
|
+
}
|
|
3450
|
+
function buildSubpathNodes(leaf, subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx) {
|
|
3451
|
+
const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
|
|
3452
|
+
const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
|
|
3453
|
+
const dashOffsetAttr = computeAnimAttr(offsetRead, offsetToDashOffset);
|
|
3454
|
+
const dashArrayAttr = computeAnimAttr(rangeRead, rangeToDasharray);
|
|
3455
|
+
const strokeOpacityAttr = computeOpacityFromRange(rangeRead);
|
|
3456
|
+
const dStr = bezierToSvgPath(subpath);
|
|
3457
|
+
const base = makeBareSubpath(dStr);
|
|
3458
|
+
applyAttr(base, "strokeDasharray", dashArrayAttr);
|
|
3459
|
+
applyAttr(base, "strokeDashoffset", dashOffsetAttr);
|
|
3460
|
+
applyAttr(base, "strokeOpacity", strokeOpacityAttr);
|
|
3461
|
+
return [base];
|
|
3462
|
+
}
|
|
3463
|
+
function collapseLeafWithTrim(leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead) {
|
|
3464
|
+
const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
|
|
3465
|
+
const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
|
|
3466
|
+
const node = __spreadValues({}, leaf);
|
|
3467
|
+
delete node.effects;
|
|
3468
|
+
applyAttr(node, "strokeDasharray", computeAnimAttr(rangeRead, rangeToDasharray));
|
|
3469
|
+
applyAttr(node, "strokeDashoffset", computeAnimAttr(offsetRead, offsetToDashOffset));
|
|
3470
|
+
applyAttr(node, "strokeOpacity", computeOpacityFromRange(rangeRead));
|
|
3471
|
+
return node;
|
|
3472
|
+
}
|
|
3473
|
+
function makeBareSubpath(dStr) {
|
|
3474
|
+
return { type: "path", d: dStr };
|
|
3475
|
+
}
|
|
3476
|
+
var SMALL_PADDING_PX = 1;
|
|
3477
|
+
function makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset) {
|
|
3478
|
+
const [minIdx] = getOffsetIndexRange(minMaxOffset);
|
|
3479
|
+
return (offsetVal) => pathLengthPx * (-offsetVal - minIdx + startOffsetPct) + SMALL_PADDING_PX;
|
|
3480
|
+
}
|
|
3481
|
+
function makeRangeToDasharray(pathLengthPx, minMaxOffset) {
|
|
3482
|
+
const [minIdx, maxIdx] = getOffsetIndexRange(minMaxOffset);
|
|
3483
|
+
const repeats = maxIdx - minIdx + 1;
|
|
3484
|
+
return (rangeVal) => {
|
|
3485
|
+
const a = clamp(rangeVal[0], 0, 1);
|
|
3486
|
+
const b = clamp(rangeVal[1], 0, 1);
|
|
3487
|
+
const minR = Math.min(a, b);
|
|
3488
|
+
const maxR = Math.max(a, b);
|
|
3489
|
+
const out = [0];
|
|
3490
|
+
let gap = SMALL_PADDING_PX;
|
|
3491
|
+
for (let i = 0; i < repeats; i++) {
|
|
3492
|
+
out.push(gap + minR * pathLengthPx);
|
|
3493
|
+
out.push((maxR - minR) * pathLengthPx);
|
|
3494
|
+
gap = (1 - maxR) * pathLengthPx;
|
|
3495
|
+
}
|
|
3496
|
+
out.push(gap + SMALL_PADDING_PX);
|
|
3497
|
+
return out;
|
|
3498
|
+
};
|
|
3499
|
+
}
|
|
3500
|
+
function getOffsetIndexRange(minMaxOffset) {
|
|
3501
|
+
return [
|
|
3502
|
+
Math.floor(Math.min(-minMaxOffset[0], -minMaxOffset[1])),
|
|
3503
|
+
Math.ceil(Math.max(-minMaxOffset[0], -minMaxOffset[1]))
|
|
3504
|
+
];
|
|
3505
|
+
}
|
|
3506
|
+
function readScalarValues(r) {
|
|
3507
|
+
var _a;
|
|
3508
|
+
if (r.kind === "absent" /* Absent */) return [];
|
|
3509
|
+
if (r.kind === "static" /* Static */) return [r.value];
|
|
3510
|
+
const out = [];
|
|
3511
|
+
for (const kf of r.keyframes) {
|
|
3512
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
3513
|
+
if (typeof v === "number") out.push(v);
|
|
3514
|
+
}
|
|
3515
|
+
return out;
|
|
3516
|
+
}
|
|
3517
|
+
function computeAnimAttr(read, map) {
|
|
3518
|
+
if (read.kind === "absent" /* Absent */) return void 0;
|
|
3519
|
+
if (read.kind === "static" /* Static */) return { kind: "static" /* Static */, value: map(read.value) };
|
|
3520
|
+
return {
|
|
3521
|
+
kind: "animated" /* Animated */,
|
|
3522
|
+
keyframes: read.keyframes.map((kf) => {
|
|
3523
|
+
var _a, _b, _c, _d;
|
|
3524
|
+
return {
|
|
3525
|
+
time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
|
|
3526
|
+
value: map((_c = kf.value) != null ? _c : kf.v),
|
|
3527
|
+
easing: (_d = kf.easing) != null ? _d : kf.e
|
|
3528
|
+
};
|
|
3529
|
+
})
|
|
3530
|
+
};
|
|
3531
|
+
}
|
|
3532
|
+
function applyAttr(node, attrName, attr) {
|
|
3533
|
+
if (!attr) return;
|
|
3534
|
+
if (attr.kind === "static" /* Static */) {
|
|
3535
|
+
node[attrName] = attr.value;
|
|
3536
|
+
return;
|
|
3537
|
+
}
|
|
3538
|
+
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
3539
|
+
const animate = __spreadValues({}, prevAnimate || {});
|
|
3540
|
+
animate[attrName] = { keyframes: attr.keyframes };
|
|
3541
|
+
node.animate = animate;
|
|
3542
|
+
}
|
|
3543
|
+
function computeOpacityFromRange(rangeRead) {
|
|
3544
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3545
|
+
const hide = (v) => v[0] === v[1];
|
|
3546
|
+
if (rangeRead.kind === "absent" /* Absent */) return void 0;
|
|
3547
|
+
if (rangeRead.kind === "static" /* Static */) return hide(rangeRead.value) ? { kind: "static" /* Static */, value: 0 } : void 0;
|
|
3548
|
+
const kfs = rangeRead.keyframes;
|
|
3549
|
+
let anyHide = false;
|
|
3550
|
+
let allHide = true;
|
|
3551
|
+
for (const kf of kfs) {
|
|
3552
|
+
if (hide((_a = kf.value) != null ? _a : kf.v)) anyHide = true;
|
|
3553
|
+
else allHide = false;
|
|
3554
|
+
}
|
|
3555
|
+
if (!anyHide) return void 0;
|
|
3556
|
+
if (allHide) return { kind: "static" /* Static */, value: 0 };
|
|
3557
|
+
const out = [];
|
|
3558
|
+
for (let i = 0; i < kfs.length; i++) {
|
|
3559
|
+
const kf = kfs[i];
|
|
3560
|
+
const prevKf = i > 0 ? kfs[i - 1] : void 0;
|
|
3561
|
+
const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
|
|
3562
|
+
const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
|
|
3563
|
+
const thisHide = hide((_d = kf.value) != null ? _d : kf.v);
|
|
3564
|
+
const prevHide = prevKf ? thisHide && hide((_e = prevKf.value) != null ? _e : prevKf.v) : thisHide;
|
|
3565
|
+
const nextHide = nextKf ? thisHide && hide((_f = nextKf.value) != null ? _f : nextKf.v) : thisHide;
|
|
3566
|
+
if (prevHide && !nextHide) {
|
|
3567
|
+
out.push({ time: t, value: 0 });
|
|
3568
|
+
out.push({ time: t + 1, value: 1 });
|
|
3569
|
+
} else if (!prevHide && nextHide) {
|
|
3570
|
+
out.push({ time: t - 1, value: 1 });
|
|
3571
|
+
out.push({ time: t, value: 0 });
|
|
3572
|
+
}
|
|
3573
|
+
}
|
|
3574
|
+
if (out.length <= 1) return void 0;
|
|
3575
|
+
return { kind: "animated" /* Animated */, keyframes: out };
|
|
3576
|
+
}
|
|
3577
|
+
function readRangeWithCrossings(raw) {
|
|
3578
|
+
const r = readAnimatable(raw);
|
|
3579
|
+
if (r.kind !== "animated" /* Animated */) return r;
|
|
3580
|
+
const kfs = r.keyframes.map((kf) => {
|
|
3581
|
+
var _a, _b, _c, _d;
|
|
3582
|
+
return {
|
|
3583
|
+
time: (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0,
|
|
3584
|
+
value: (_c = kf.value) != null ? _c : kf.v,
|
|
3585
|
+
easing: (_d = kf.easing) != null ? _d : kf.e
|
|
3586
|
+
};
|
|
3587
|
+
});
|
|
3588
|
+
const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
|
|
3589
|
+
if (!hasReverse) {
|
|
3590
|
+
return {
|
|
3591
|
+
kind: "animated" /* Animated */,
|
|
3592
|
+
keyframes: kfs.map((kf) => ({ time: kf.time, value: kf.value, easing: kf.easing }))
|
|
3593
|
+
};
|
|
3594
|
+
}
|
|
3595
|
+
const crossingTimes = [];
|
|
3596
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
3597
|
+
const prev = kfs[i - 1];
|
|
3598
|
+
const cur = kfs[i];
|
|
3599
|
+
const dPrev = prev.value[1] - prev.value[0];
|
|
3600
|
+
const dCur = cur.value[1] - cur.value[0];
|
|
3601
|
+
if (dPrev * dCur < 0) {
|
|
3602
|
+
const t = bisectionForRangeCrossing(prev, cur);
|
|
3603
|
+
if (t !== null && t > prev.time && t < cur.time) {
|
|
3604
|
+
crossingTimes.push(Math.round(t));
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
const uniqueTs = Array.from(new Set(crossingTimes)).sort((a, b) => a - b);
|
|
3609
|
+
const out = [];
|
|
3610
|
+
let j = 0;
|
|
3611
|
+
for (const kf of kfs) {
|
|
3612
|
+
while (j < uniqueTs.length && uniqueTs[j] < kf.time) {
|
|
3613
|
+
const t = uniqueTs[j++];
|
|
3614
|
+
const v2 = interpolateRangeAt(kfs, t);
|
|
3615
|
+
const m = (v2[0] + v2[1]) / 2;
|
|
3616
|
+
out.push({ time: t, value: [m, m] });
|
|
3617
|
+
}
|
|
3618
|
+
const v = kf.value[0] > kf.value[1] ? [kf.value[1], kf.value[0]] : kf.value;
|
|
3619
|
+
out.push({ time: kf.time, value: v, easing: kf.easing });
|
|
3620
|
+
}
|
|
3621
|
+
while (j < uniqueTs.length) {
|
|
3622
|
+
const t = uniqueTs[j++];
|
|
3623
|
+
const v = interpolateRangeAt(kfs, t);
|
|
3624
|
+
const m = (v[0] + v[1]) / 2;
|
|
3625
|
+
out.push({ time: t, value: [m, m] });
|
|
3626
|
+
}
|
|
3627
|
+
return { kind: "animated" /* Animated */, keyframes: out };
|
|
3628
|
+
}
|
|
3629
|
+
function bisectionForRangeCrossing(prev, cur) {
|
|
3630
|
+
const f = (t) => {
|
|
3631
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
3632
|
+
const v0 = prev.value[0] + (cur.value[0] - prev.value[0]) * a;
|
|
3633
|
+
const v1 = prev.value[1] + (cur.value[1] - prev.value[1]) * a;
|
|
3634
|
+
return v1 - v0;
|
|
3635
|
+
};
|
|
3636
|
+
let lo = prev.time, hi = cur.time;
|
|
3637
|
+
let fLo = f(lo);
|
|
3638
|
+
if (fLo === 0) return lo;
|
|
3639
|
+
const fHi = f(hi);
|
|
3640
|
+
if (fHi === 0) return hi;
|
|
3641
|
+
if (fLo * fHi > 0) return null;
|
|
3642
|
+
for (let i = 0; i < 100; i++) {
|
|
3643
|
+
const mid = (lo + hi) / 2;
|
|
3644
|
+
const fMid = f(mid);
|
|
3645
|
+
if (fMid === 0 || Math.abs(hi - lo) < 1e-4) return mid;
|
|
3646
|
+
if (fLo * fMid < 0) {
|
|
3647
|
+
hi = mid;
|
|
3648
|
+
} else {
|
|
3649
|
+
lo = mid;
|
|
3650
|
+
fLo = fMid;
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
return (lo + hi) / 2;
|
|
3654
|
+
}
|
|
3655
|
+
function interpolateRangeAt(kfs, t) {
|
|
3656
|
+
if (t <= kfs[0].time) return kfs[0].value;
|
|
3657
|
+
if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
|
|
3658
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
3659
|
+
if (t <= kfs[i].time) {
|
|
3660
|
+
const prev = kfs[i - 1];
|
|
3661
|
+
const cur = kfs[i];
|
|
3662
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
3663
|
+
return [
|
|
3664
|
+
prev.value[0] + (cur.value[0] - prev.value[0]) * a,
|
|
3665
|
+
prev.value[1] + (cur.value[1] - prev.value[1]) * a
|
|
3666
|
+
];
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
return kfs[kfs.length - 1].value;
|
|
3670
|
+
}
|
|
3671
|
+
function pxBezierPathLength(path) {
|
|
3672
|
+
const v = path.v;
|
|
3673
|
+
if (!v || v.length < 2) return 0;
|
|
3674
|
+
let total = 0;
|
|
3675
|
+
for (let i = 0; i < v.length - 1; i++) {
|
|
3676
|
+
total += segmentLength(path, i, i + 1);
|
|
3677
|
+
}
|
|
3678
|
+
if (path.c && v.length > 1) {
|
|
3679
|
+
total += segmentLength(path, v.length - 1, 0);
|
|
3680
|
+
}
|
|
3681
|
+
return total;
|
|
3682
|
+
}
|
|
3683
|
+
function segmentLength(path, from, to) {
|
|
3684
|
+
var _a, _b, _c, _d;
|
|
3685
|
+
const v = path.v;
|
|
3686
|
+
const p0 = v[from];
|
|
3687
|
+
const p3 = v[to];
|
|
3688
|
+
const p1 = (_b = (_a = path.o) == null ? void 0 : _a[from]) != null ? _b : p0;
|
|
3689
|
+
const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
|
|
3690
|
+
const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
|
|
3691
|
+
return lut.ds[lut.ds.length - 1];
|
|
3692
|
+
}
|
|
3693
|
+
function rectToPathD(node) {
|
|
3694
|
+
var _a, _b, _c, _d;
|
|
3695
|
+
if (node.type !== "rect") return void 0;
|
|
3696
|
+
const x = Number((_a = node.x) != null ? _a : 0), y = Number((_b = node.y) != null ? _b : 0);
|
|
3697
|
+
const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
|
|
3698
|
+
return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3701
|
+
// src/effects/PlayerEffectsUtil.ts
|
|
3702
|
+
function applyPlayerEffects(root) {
|
|
3703
|
+
const ctx = {
|
|
3704
|
+
defs: [],
|
|
3705
|
+
warnings: [],
|
|
3706
|
+
errors: [],
|
|
3707
|
+
idMap: /* @__PURE__ */ new Map(),
|
|
3708
|
+
nextId: 0,
|
|
3709
|
+
contentRefInnerIds: /* @__PURE__ */ new Map(),
|
|
3710
|
+
maskAncestorChains: /* @__PURE__ */ new Map()
|
|
3711
|
+
};
|
|
3712
|
+
const working = clone(root);
|
|
3713
|
+
indexById(working, ctx.idMap);
|
|
3714
|
+
identifyContentRefTargets(working, ctx, () => genId(ctx, "inner"));
|
|
3715
|
+
collectMaskAncestorChains(working, ctx);
|
|
3716
|
+
const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);
|
|
3717
|
+
const out = applyPlayerEffects_retime(afterPass1, ctx);
|
|
3718
|
+
spliceDefs(out, ctx.defs);
|
|
3719
|
+
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
3720
|
+
}
|
|
3721
|
+
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
3722
|
+
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
3723
|
+
const fx = node.effects;
|
|
3724
|
+
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
3725
|
+
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
3726
|
+
if (!fx && !innerIdForContentRef) return node;
|
|
3727
|
+
const { transformation, repeater, maskedBy, trimPath, retime, ref, fillGradient, strokeGradient, textAlongPath } = fx != null ? fx : {};
|
|
3728
|
+
const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
|
|
3729
|
+
if (fx) delete node.effects;
|
|
3730
|
+
let n = node;
|
|
3731
|
+
n = applyTextAlongPathEffect(n, textAlongPath, ctx);
|
|
3732
|
+
n = applyFillGradientEffect(n, fillGradient, ctx);
|
|
3733
|
+
n = applyStrokeGradientEffect(n, strokeGradient, ctx);
|
|
3734
|
+
n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
|
|
3735
|
+
n = applyRepeaterEffect(n, repeater, ctx);
|
|
3736
|
+
n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
|
|
3737
|
+
if (innerIdForContentRef) {
|
|
3738
|
+
n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
|
|
3739
|
+
} else {
|
|
3740
|
+
n = applyRefAndTransformationEffect(n, ref, transformation, ctx);
|
|
3741
|
+
}
|
|
3742
|
+
if (retime) node.effects = { retime };
|
|
3743
|
+
if (originalId) ctx.idMap.set(originalId, n);
|
|
3744
|
+
return n;
|
|
3745
|
+
}
|
|
3746
|
+
function applyPlayerEffects_retime(node, ctx) {
|
|
3747
|
+
applyAllRetimeEffects(node, ctx);
|
|
3748
|
+
return node;
|
|
3749
|
+
}
|
|
3750
|
+
|
|
3751
|
+
// src/PxAnimatorUseMaterialiser.ts
|
|
3752
|
+
function materialiseAnimatedUseInstances(root) {
|
|
3753
|
+
var _a;
|
|
3754
|
+
const idMap = buildIdMap(root);
|
|
3755
|
+
const animatedIds = computeAnimatedSubtreeIds(root, idMap);
|
|
3756
|
+
if (animatedIds.size === 0) return root;
|
|
3757
|
+
let idCounter = 0;
|
|
3758
|
+
const genId3 = () => "_lw_use_mat_" + ++idCounter;
|
|
3759
|
+
const defsCollector = [];
|
|
3760
|
+
const walked = walkAndMaterialise2(root, idMap, animatedIds, genId3, defsCollector);
|
|
3761
|
+
if (defsCollector.length === 0) return walked;
|
|
3762
|
+
const defsNode = { type: "defs", children: defsCollector };
|
|
3763
|
+
const newChildren = [...(_a = walked.children) != null ? _a : [], defsNode];
|
|
3764
|
+
return __spreadProps(__spreadValues({}, walked), { children: newChildren });
|
|
3765
|
+
}
|
|
3766
|
+
function buildIdMap(root) {
|
|
3767
|
+
const map = /* @__PURE__ */ new Map();
|
|
3768
|
+
const visit = (n) => {
|
|
3769
|
+
var _a;
|
|
3770
|
+
if (typeof n.id === "string") map.set(n.id, n);
|
|
3771
|
+
(_a = n.children) == null ? void 0 : _a.forEach(visit);
|
|
3772
|
+
};
|
|
3773
|
+
visit(root);
|
|
3774
|
+
return map;
|
|
3775
|
+
}
|
|
3776
|
+
function computeAnimatedSubtreeIds(root, idMap) {
|
|
3777
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
3778
|
+
const result = /* @__PURE__ */ new Set();
|
|
3779
|
+
const hasAnim = (n, visiting) => {
|
|
3780
|
+
const cached = cache.get(n);
|
|
3781
|
+
if (cached !== void 0) return cached;
|
|
3782
|
+
if (visiting.has(n)) return false;
|
|
3783
|
+
visiting.add(n);
|
|
3784
|
+
let r = false;
|
|
3785
|
+
if (n.animate && typeof n.animate === "object" && !Array.isArray(n.animate)) {
|
|
3786
|
+
for (const _ in n.animate) {
|
|
3787
|
+
r = true;
|
|
3788
|
+
break;
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
if (!r && n.children) {
|
|
3792
|
+
for (const ch of n.children) {
|
|
3793
|
+
if (hasAnim(ch, visiting)) {
|
|
3794
|
+
r = true;
|
|
3795
|
+
break;
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
}
|
|
3799
|
+
if (!r && n.type === "use" && typeof n.href === "string") {
|
|
3800
|
+
const targetId = stripHash2(n.href);
|
|
3801
|
+
const target = targetId ? idMap.get(targetId) : void 0;
|
|
3802
|
+
if (target) r = hasAnim(target, visiting);
|
|
3803
|
+
}
|
|
3804
|
+
visiting.delete(n);
|
|
3805
|
+
cache.set(n, r);
|
|
3806
|
+
return r;
|
|
3807
|
+
};
|
|
3808
|
+
for (const [id, node] of idMap) {
|
|
3809
|
+
if (hasAnim(node, /* @__PURE__ */ new Set())) result.add(id);
|
|
3810
|
+
}
|
|
3811
|
+
return result;
|
|
3812
|
+
}
|
|
3813
|
+
function stripHash2(href) {
|
|
3814
|
+
if (typeof href !== "string") return void 0;
|
|
3815
|
+
return href.startsWith("#") ? href.slice(1) : href;
|
|
3816
|
+
}
|
|
3817
|
+
function materialiseOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector) {
|
|
3818
|
+
const clone2 = deepClonePxNode(target);
|
|
3819
|
+
regenerateIdsAndRewriteRefs(clone2, genId3);
|
|
3820
|
+
const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector) : clone2;
|
|
3821
|
+
const materialisedClone = walkAndMaterialise2(rewrittenClone, idMap, animatedIds, genId3, defsCollector);
|
|
3822
|
+
const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materialisedClone] });
|
|
3823
|
+
delete newNode.href;
|
|
3824
|
+
return applyUseOffsetToG(newNode);
|
|
3825
|
+
}
|
|
3826
|
+
function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector) {
|
|
3827
|
+
const viewBox = parseViewBox(symbolNode.viewBox);
|
|
3828
|
+
const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
|
|
3829
|
+
delete g.viewBox;
|
|
3830
|
+
delete g.preserveAspectRatio;
|
|
3831
|
+
delete g.width;
|
|
3832
|
+
delete g.height;
|
|
3833
|
+
if (!viewBox) return g;
|
|
3834
|
+
const [vbX, vbY, vbW, vbH] = viewBox;
|
|
3835
|
+
if (vbX !== 0 || vbY !== 0) {
|
|
3836
|
+
g.transform = "translate(" + -vbX + "," + -vbY + ")";
|
|
3837
|
+
}
|
|
3838
|
+
const clipId = genId3();
|
|
3839
|
+
defsCollector.push({
|
|
3840
|
+
type: "clipPath",
|
|
3841
|
+
id: clipId,
|
|
3842
|
+
children: [{ type: "rect", x: vbX, y: vbY, width: vbW, height: vbH }]
|
|
3843
|
+
});
|
|
3844
|
+
g.clipPath = "url(#" + clipId + ")";
|
|
3845
|
+
return g;
|
|
3846
|
+
}
|
|
3847
|
+
function parseViewBox(v) {
|
|
3848
|
+
if (typeof v !== "string") return void 0;
|
|
3849
|
+
const parts = v.trim().split(/[\s,]+/).map(Number);
|
|
3850
|
+
if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
|
|
3851
|
+
return [parts[0], parts[1], parts[2], parts[3]];
|
|
3852
|
+
}
|
|
3853
|
+
function walkAndMaterialise2(node, idMap, animatedIds, genId3, defsCollector) {
|
|
3854
|
+
if (node.type === "use" && typeof node.href === "string") {
|
|
3855
|
+
const targetId = stripHash2(node.href);
|
|
3856
|
+
if (targetId && animatedIds.has(targetId)) {
|
|
3857
|
+
const target = idMap.get(targetId);
|
|
3858
|
+
if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId3, defsCollector);
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
if (!node.children) return node;
|
|
3862
|
+
let changed = false;
|
|
3863
|
+
const newChildren = node.children.map((ch) => {
|
|
3864
|
+
const m = walkAndMaterialise2(ch, idMap, animatedIds, genId3, defsCollector);
|
|
3865
|
+
if (m !== ch) changed = true;
|
|
3866
|
+
return m;
|
|
3867
|
+
});
|
|
3868
|
+
return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
|
|
3869
|
+
}
|
|
3870
|
+
|
|
3871
|
+
// src/PxAnimatorMaterialiseAll.ts
|
|
3872
|
+
function materialiseAllInTree(doc, engine, opts) {
|
|
3873
|
+
var _a, _b;
|
|
3874
|
+
let root = applyPlayerEffects(doc).root;
|
|
3875
|
+
const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
|
|
3876
|
+
root = materialiseInternalLoopsInTree(root, duration);
|
|
3877
|
+
if (engine === PxAnimatorEngine.webapi) {
|
|
3878
|
+
root = materialiseMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
|
|
3879
|
+
root = materialiseAnimatedUseInstances(root);
|
|
3880
|
+
}
|
|
3881
|
+
return root;
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3884
|
+
// src/PxAnimatorDOM.ts
|
|
3885
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
3886
|
+
var DISALLOWED_SVG_TAGS_LOWER = /* @__PURE__ */ new Set([
|
|
3887
|
+
"script",
|
|
3888
|
+
"foreignobject"
|
|
3889
|
+
]);
|
|
3890
|
+
var URL_VALUE_ATTRS_LOWER = /* @__PURE__ */ new Set([
|
|
3891
|
+
"href",
|
|
3892
|
+
// <use>, <image>
|
|
3893
|
+
"xlink:href",
|
|
3894
|
+
// legacy <use>
|
|
3895
|
+
"src",
|
|
3896
|
+
// <image>
|
|
3897
|
+
"filter",
|
|
3898
|
+
// url(#filterId)
|
|
3899
|
+
"clippath",
|
|
3900
|
+
// clip-path="url(#…)"
|
|
3901
|
+
"mask",
|
|
3902
|
+
// url(#maskId)
|
|
3903
|
+
"markerstart",
|
|
3904
|
+
// marker-start="url(#…)"
|
|
3905
|
+
"markermid",
|
|
3906
|
+
// marker-mid="url(#…)"
|
|
3907
|
+
"markerend"
|
|
3908
|
+
// marker-end="url(#…)"
|
|
3909
|
+
]);
|
|
3910
|
+
var IMAGE_REF_ATTRS_LOWER = /* @__PURE__ */ new Set(["href", "xlink:href", "src"]);
|
|
3911
|
+
var DATA_RASTER_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,/i;
|
|
3912
|
+
function isDangerousAttrName(nameLower) {
|
|
3913
|
+
if (nameLower.startsWith("on")) return true;
|
|
3914
|
+
return false;
|
|
3915
|
+
}
|
|
3916
|
+
function sanitiseAttributeValue(name, value) {
|
|
3917
|
+
const nameLower = name.toLowerCase();
|
|
3918
|
+
if (isDangerousAttrName(nameLower)) {
|
|
3919
|
+
console.warn("Attribute blocked (event handler / dangerous): ", nameLower);
|
|
3920
|
+
return void 0;
|
|
3921
|
+
}
|
|
3922
|
+
if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
|
|
3923
|
+
const str = String(value);
|
|
3924
|
+
if (str.includes("url(") && !/^url\(#[^)]+\)$/.test(str)) {
|
|
3925
|
+
console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
|
|
3926
|
+
return void 0;
|
|
3927
|
+
}
|
|
3928
|
+
return value;
|
|
3929
|
+
}
|
|
3930
|
+
if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
|
|
3931
|
+
const str = String(value);
|
|
3932
|
+
if (str.startsWith("#")) return value;
|
|
3933
|
+
if (/^url\(#[^)]+\)$/.test(str)) return value;
|
|
3934
|
+
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && DATA_RASTER_IMAGE_RE.test(str)) return value;
|
|
3935
|
+
console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or base64 raster data: URI, got:', value);
|
|
3936
|
+
return void 0;
|
|
3937
|
+
}
|
|
3938
|
+
return value;
|
|
3939
|
+
}
|
|
3940
|
+
function createElement(tagName, normalisedProps, style, children, textContent) {
|
|
3941
|
+
if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {
|
|
3942
|
+
console.warn("SVG tag blocked (dangerous): ", tagName);
|
|
3943
|
+
return null;
|
|
3944
|
+
}
|
|
3945
|
+
const element = document.createElementNS(SVG_NS, tagName);
|
|
3946
|
+
for (const propName in normalisedProps) {
|
|
3947
|
+
const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);
|
|
3948
|
+
if (sanitised === void 0) continue;
|
|
3949
|
+
element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);
|
|
3950
|
+
}
|
|
3951
|
+
if (style) {
|
|
3952
|
+
for (const styleProp in style) {
|
|
3953
|
+
element.style[styleProp] = String(style[styleProp]);
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
if (children) {
|
|
3957
|
+
for (const child of children) {
|
|
3958
|
+
element.appendChild(child);
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3961
|
+
if (textContent) element.textContent = textContent;
|
|
3962
|
+
return element;
|
|
3963
|
+
}
|
|
3964
|
+
function resolveStyle(style, defs) {
|
|
3965
|
+
var _a;
|
|
3966
|
+
if (!style) return void 0;
|
|
3967
|
+
if (typeof style === "string") {
|
|
3968
|
+
return (_a = defs == null ? void 0 : defs.styles) == null ? void 0 : _a[style];
|
|
3969
|
+
}
|
|
3970
|
+
return style;
|
|
3971
|
+
}
|
|
3972
|
+
function getNormalizedProps(props) {
|
|
3973
|
+
const propsCopy = {};
|
|
3974
|
+
for (const rawKey of Object.keys(props)) {
|
|
3975
|
+
const key = kebabToCamelCaseWord(rawKey);
|
|
3976
|
+
if (INTERNAL_ATTRS.has(key)) continue;
|
|
3977
|
+
if (key === "style") continue;
|
|
3978
|
+
let value = props[rawKey];
|
|
3979
|
+
if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {
|
|
3980
|
+
propsCopy[key] = toRGBA(value);
|
|
3981
|
+
} else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && value.value && typeof value.value === "object") {
|
|
3982
|
+
propsCopy["transform"] = composeTransformParts(value.value, { withUnits: false });
|
|
3983
|
+
} else if (TRANSFORM_FN_NAMES.has(key)) {
|
|
3984
|
+
if (Array.isArray(value)) {
|
|
3985
|
+
if (key === "translate") value = value.map((v) => v + "px");
|
|
3986
|
+
value = value.join(",");
|
|
3987
|
+
}
|
|
3988
|
+
if (key === "rotate") value = value + "deg";
|
|
3989
|
+
propsCopy["transform"] = key + "(" + value + ")";
|
|
3990
|
+
} else if (value !== void 0 && value !== null) {
|
|
3991
|
+
propsCopy[key] = String(value);
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
return propsCopy;
|
|
3995
|
+
}
|
|
3996
|
+
function renderNode(node, defs) {
|
|
3997
|
+
if (!node) return null;
|
|
3998
|
+
const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
|
|
3999
|
+
const nodeDefs = getDefs(node) || defs;
|
|
4000
|
+
const resolvedStyle = resolveStyle(style, nodeDefs);
|
|
4001
|
+
let childElements;
|
|
4002
|
+
if (children) {
|
|
4003
|
+
for (const ch of children) {
|
|
4004
|
+
const child = renderNode(ch, nodeDefs);
|
|
4005
|
+
if (child) {
|
|
4006
|
+
if (!childElements) childElements = [];
|
|
4007
|
+
childElements.push(child);
|
|
4008
|
+
}
|
|
4009
|
+
}
|
|
1304
4010
|
}
|
|
1305
|
-
return
|
|
4011
|
+
return createElement(
|
|
4012
|
+
type || "g",
|
|
4013
|
+
getNormalizedProps(props),
|
|
4014
|
+
resolvedStyle,
|
|
4015
|
+
childElements,
|
|
4016
|
+
props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
|
|
4017
|
+
);
|
|
1306
4018
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
4019
|
+
|
|
4020
|
+
// src/PxAnimatorTriggers.ts
|
|
4021
|
+
function setupAnimationTriggers(api, config) {
|
|
4022
|
+
const { startOn, outAction = "continue", scrollIntoViewThreshold = 0.5 } = config;
|
|
4023
|
+
const root = api.getRootElement();
|
|
4024
|
+
if (!root) {
|
|
4025
|
+
console.warn("setupAnimationTriggers: No root element found for animation.");
|
|
4026
|
+
return api;
|
|
4027
|
+
}
|
|
4028
|
+
const start = () => {
|
|
4029
|
+
api.play();
|
|
4030
|
+
};
|
|
4031
|
+
const handleEndAction = () => {
|
|
4032
|
+
switch (outAction) {
|
|
4033
|
+
case "pause":
|
|
4034
|
+
api.pause();
|
|
4035
|
+
break;
|
|
4036
|
+
case "reset":
|
|
4037
|
+
api.cancel();
|
|
4038
|
+
break;
|
|
4039
|
+
case "reverse":
|
|
4040
|
+
api.play();
|
|
4041
|
+
break;
|
|
4042
|
+
case "continue":
|
|
4043
|
+
default:
|
|
4044
|
+
break;
|
|
4045
|
+
}
|
|
4046
|
+
};
|
|
4047
|
+
switch (startOn) {
|
|
4048
|
+
case "load": {
|
|
4049
|
+
const startHandler = () => start();
|
|
4050
|
+
if (document.readyState === "complete") {
|
|
4051
|
+
startHandler();
|
|
4052
|
+
} else {
|
|
4053
|
+
window.addEventListener("load", startHandler, { once: true });
|
|
4054
|
+
}
|
|
1317
4055
|
break;
|
|
1318
4056
|
}
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
if (keyframes.length === 0) return null;
|
|
1326
|
-
const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
|
|
1327
|
-
let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
|
|
1328
|
-
localProgress = clamp(localProgress, 0, 1);
|
|
1329
|
-
const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
|
|
1330
|
-
if (easing && Array.isArray(easing)) {
|
|
1331
|
-
try {
|
|
1332
|
-
localProgress = cubicBezier(easing)(localProgress);
|
|
1333
|
-
} catch (e) {
|
|
4057
|
+
case "mouseOver": {
|
|
4058
|
+
const mouseOverHandler = () => start();
|
|
4059
|
+
const mouseOutHandler = () => handleEndAction();
|
|
4060
|
+
root.addEventListener("mouseenter", mouseOverHandler);
|
|
4061
|
+
root.addEventListener("mouseleave", mouseOutHandler);
|
|
4062
|
+
break;
|
|
1334
4063
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
cssAttrName = propName;
|
|
1362
|
-
} else if (cssAttrName === "translate") {
|
|
1363
|
-
const v = interpolateVec(
|
|
1364
|
-
prevV || [0, 0],
|
|
1365
|
-
nextV || [0, 0],
|
|
1366
|
-
localProgress
|
|
1367
|
-
);
|
|
1368
|
-
cssValue = "translate(" + v.join(",") + ")";
|
|
1369
|
-
cssAttrName = "transform";
|
|
1370
|
-
} else if (cssAttrName === "rotate") {
|
|
1371
|
-
const v = interpolateNum(
|
|
1372
|
-
+(prevV || 0),
|
|
1373
|
-
+(nextV || 0),
|
|
1374
|
-
localProgress
|
|
1375
|
-
);
|
|
1376
|
-
cssValue = "rotate(" + v + ")";
|
|
1377
|
-
cssAttrName = "transform";
|
|
1378
|
-
} else if (cssAttrName === "scale") {
|
|
1379
|
-
const v = interpolateVec(
|
|
1380
|
-
prevV || [1, 1],
|
|
1381
|
-
nextV || [1, 1],
|
|
1382
|
-
localProgress
|
|
1383
|
-
);
|
|
1384
|
-
cssValue = "scale(" + v.join(",") + ")";
|
|
1385
|
-
cssAttrName = "transform";
|
|
1386
|
-
} else {
|
|
1387
|
-
const num = interpolateNum(
|
|
1388
|
-
+(prevV || 0),
|
|
1389
|
-
+(nextV || 0),
|
|
1390
|
-
localProgress
|
|
1391
|
-
);
|
|
1392
|
-
cssValue = num;
|
|
1393
|
-
}
|
|
1394
|
-
if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
|
|
1395
|
-
cssValue = cssValue * 100 + "%";
|
|
1396
|
-
}
|
|
1397
|
-
return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
|
|
1398
|
-
}
|
|
1399
|
-
function calcAnimationValues(animDef, progress) {
|
|
1400
|
-
const result = {};
|
|
1401
|
-
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
1402
|
-
const computed = calcPropertyValue(propName, propAnim, progress);
|
|
1403
|
-
if (computed) {
|
|
1404
|
-
result[computed.k] = computed.v;
|
|
4064
|
+
case "click": {
|
|
4065
|
+
const clickHandler = () => {
|
|
4066
|
+
if (api.isPlaying()) {
|
|
4067
|
+
handleEndAction();
|
|
4068
|
+
} else {
|
|
4069
|
+
start();
|
|
4070
|
+
}
|
|
4071
|
+
};
|
|
4072
|
+
root.addEventListener("click", clickHandler);
|
|
4073
|
+
break;
|
|
4074
|
+
}
|
|
4075
|
+
case "scrollIntoView": {
|
|
4076
|
+
const observer = new IntersectionObserver(
|
|
4077
|
+
(entries) => {
|
|
4078
|
+
entries.forEach((entry) => {
|
|
4079
|
+
if (entry.isIntersecting && entry.intersectionRatio >= scrollIntoViewThreshold) {
|
|
4080
|
+
start();
|
|
4081
|
+
} else {
|
|
4082
|
+
handleEndAction();
|
|
4083
|
+
}
|
|
4084
|
+
});
|
|
4085
|
+
},
|
|
4086
|
+
{ threshold: scrollIntoViewThreshold }
|
|
4087
|
+
);
|
|
4088
|
+
observer.observe(root);
|
|
4089
|
+
break;
|
|
1405
4090
|
}
|
|
4091
|
+
case "programmatic":
|
|
4092
|
+
break;
|
|
1406
4093
|
}
|
|
1407
|
-
return
|
|
4094
|
+
return api;
|
|
1408
4095
|
}
|
|
1409
4096
|
|
|
1410
4097
|
// src/PxAnimatorFrameLoop.ts
|
|
@@ -1413,7 +4100,7 @@ function getSelector(id) {
|
|
|
1413
4100
|
}
|
|
1414
4101
|
function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
1415
4102
|
const config = getAnimatorConfig(doc) || {};
|
|
1416
|
-
const bindings = getNormalisedBindings(doc);
|
|
4103
|
+
const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
|
|
1417
4104
|
const _iterations = config.iterations;
|
|
1418
4105
|
let iterations = 1;
|
|
1419
4106
|
if (typeof _iterations === "number") iterations = _iterations || 1;
|
|
@@ -1531,6 +4218,10 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
1531
4218
|
};
|
|
1532
4219
|
const startAnim = () => {
|
|
1533
4220
|
if (playing) return;
|
|
4221
|
+
if (Number.isFinite(totalDuration) && timeBeforeLastStartMs >= totalDuration) {
|
|
4222
|
+
timeBeforeLastStartMs = 0;
|
|
4223
|
+
finishCalled = false;
|
|
4224
|
+
}
|
|
1534
4225
|
playing = true;
|
|
1535
4226
|
lastStartedTs = Date.now();
|
|
1536
4227
|
loopAnim(true);
|
|
@@ -1681,6 +4372,9 @@ function createCssKf(kf, t, propName, unsupportedSet) {
|
|
|
1681
4372
|
let cssKey = propName;
|
|
1682
4373
|
if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
|
|
1683
4374
|
cssValue = toRGBA(value);
|
|
4375
|
+
} else if (propName === "transform" && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
4376
|
+
cssValue = composeTransformParts(value, { withUnits: true });
|
|
4377
|
+
cssKey = "transform";
|
|
1684
4378
|
} else if (TRANSFORM_FN_NAMES.has(propName)) {
|
|
1685
4379
|
if (Array.isArray(value)) {
|
|
1686
4380
|
if (propName === "translate") value = value.map((v) => v + "px");
|
|
@@ -1697,28 +4391,59 @@ function createCssKf(kf, t, propName, unsupportedSet) {
|
|
|
1697
4391
|
cssKf[cssKey] = cssValue;
|
|
1698
4392
|
return cssKf;
|
|
1699
4393
|
}
|
|
4394
|
+
function clipKeyframesToDuration(propName, keyframes, duration) {
|
|
4395
|
+
var _a, _b, _c, _d, _e;
|
|
4396
|
+
const result = [];
|
|
4397
|
+
for (let i = 0; i < keyframes.length; i++) {
|
|
4398
|
+
const kf = keyframes[i];
|
|
4399
|
+
const t = (_a = kf.t) != null ? _a : 0;
|
|
4400
|
+
if (t < 0) {
|
|
4401
|
+
const next = keyframes[i + 1];
|
|
4402
|
+
if (next && ((_b = next.t) != null ? _b : 0) >= 0) {
|
|
4403
|
+
const nextT = (_c = next.t) != null ? _c : 0;
|
|
4404
|
+
const localFrac = (0 - t) / (nextT - t);
|
|
4405
|
+
const easedFrac = kf.e ? cubicBezier(kf.e)(localFrac) : localFrac;
|
|
4406
|
+
const { right: rightEasing } = splitEasing(kf.e, localFrac);
|
|
4407
|
+
result.push({ t: 0, v: interpolateValue(propName, kf.v, next.v, easedFrac), e: rightEasing });
|
|
4408
|
+
}
|
|
4409
|
+
continue;
|
|
4410
|
+
}
|
|
4411
|
+
if (t > duration) {
|
|
4412
|
+
const prev = keyframes[i - 1];
|
|
4413
|
+
if (prev && ((_d = prev.t) != null ? _d : 0) <= duration) {
|
|
4414
|
+
const prevT = (_e = prev.t) != null ? _e : 0;
|
|
4415
|
+
const localFrac = (duration - prevT) / (t - prevT);
|
|
4416
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
4417
|
+
const { left: leftEasing } = splitEasing(prev.e, localFrac);
|
|
4418
|
+
if (result.length > 0) result[result.length - 1] = __spreadProps(__spreadValues({}, result[result.length - 1]), { e: leftEasing });
|
|
4419
|
+
result.push({ t: duration, v: interpolateValue(propName, prev.v, kf.v, easedFrac), e: void 0 });
|
|
4420
|
+
}
|
|
4421
|
+
break;
|
|
4422
|
+
}
|
|
4423
|
+
result.push(kf);
|
|
4424
|
+
}
|
|
4425
|
+
return result;
|
|
4426
|
+
}
|
|
1700
4427
|
function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
|
|
1701
|
-
var _a
|
|
4428
|
+
var _a;
|
|
1702
4429
|
const result = /* @__PURE__ */ new Map();
|
|
1703
4430
|
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
1704
|
-
const
|
|
4431
|
+
const duration = config.duration || 1;
|
|
4432
|
+
const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.kfs || propAnim.keyframes || [], duration);
|
|
1705
4433
|
const cssKeyframes = [];
|
|
1706
|
-
for (let i = 0; i <
|
|
1707
|
-
const kf =
|
|
1708
|
-
|
|
1709
|
-
t = clamp(t / (config.duration || 1), 0, 1);
|
|
4434
|
+
for (let i = 0; i < clippedKeyframes.length; i++) {
|
|
4435
|
+
const kf = clippedKeyframes[i];
|
|
4436
|
+
const t = clamp(((_a = kf.t) != null ? _a : 0) / duration, 0, 1);
|
|
1710
4437
|
const cssKf = createCssKf(kf, t, propName, unsupportedSet);
|
|
1711
4438
|
if (i === 0 && (cssKf.offset || 0) > 0) {
|
|
1712
|
-
cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), {
|
|
1713
|
-
offset: 0
|
|
1714
|
-
}));
|
|
4439
|
+
cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), { offset: 0 }));
|
|
1715
4440
|
}
|
|
1716
4441
|
cssKeyframes.push(cssKf);
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
}
|
|
4442
|
+
}
|
|
4443
|
+
if (cssKeyframes.length > 0 && (cssKeyframes[cssKeyframes.length - 1].offset || 0) < 1) {
|
|
4444
|
+
cssKeyframes.push(__spreadProps(__spreadValues({}, cssKeyframes[cssKeyframes.length - 1]), {
|
|
4445
|
+
offset: 1
|
|
4446
|
+
}));
|
|
1722
4447
|
}
|
|
1723
4448
|
if (cssKeyframes.length > 0) {
|
|
1724
4449
|
result.set(propName, cssKeyframes);
|
|
@@ -1727,8 +4452,8 @@ function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
|
|
|
1727
4452
|
return result;
|
|
1728
4453
|
}
|
|
1729
4454
|
function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs) {
|
|
4455
|
+
var _a;
|
|
1730
4456
|
const config = getAnimatorConfig(doc) || {};
|
|
1731
|
-
const bindings = getNormalisedBindings(doc);
|
|
1732
4457
|
if (!rootElement) {
|
|
1733
4458
|
if (doc.id) {
|
|
1734
4459
|
const rootSelector = getSelector(doc.id);
|
|
@@ -1738,6 +4463,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
1738
4463
|
console.warn("createFrameLoopAnimator: No root element provided");
|
|
1739
4464
|
}
|
|
1740
4465
|
}
|
|
4466
|
+
const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);
|
|
1741
4467
|
const animations = [];
|
|
1742
4468
|
const _iterations = config.iterations;
|
|
1743
4469
|
let iterations;
|
|
@@ -1764,7 +4490,11 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
1764
4490
|
const effectOptions = {
|
|
1765
4491
|
duration: config.duration,
|
|
1766
4492
|
delay: positiveDelay,
|
|
1767
|
-
|
|
4493
|
+
// Default to 'forwards' so elements hold their final state after the
|
|
4494
|
+
// animation ends — consistent with Lottie and other animation runtimes.
|
|
4495
|
+
// Without this, seeking to the last frame reverts elements to their
|
|
4496
|
+
// pre-animation state (the Web Animations API "after" phase with fill:'none').
|
|
4497
|
+
fill: (_a = config.fill) != null ? _a : "forwards",
|
|
1768
4498
|
direction: config.direction,
|
|
1769
4499
|
iterations
|
|
1770
4500
|
};
|
|
@@ -1776,12 +4506,12 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
1776
4506
|
const effect = new KeyframeEffect(element, keyframes, effectOptions);
|
|
1777
4507
|
const anim = new Animation(effect, document.timeline);
|
|
1778
4508
|
if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
|
|
1779
|
-
var
|
|
1780
|
-
return (
|
|
4509
|
+
var _a2;
|
|
4510
|
+
return (_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
|
|
1781
4511
|
};
|
|
1782
4512
|
if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
|
|
1783
|
-
var
|
|
1784
|
-
return (
|
|
4513
|
+
var _a2;
|
|
4514
|
+
return (_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
|
|
1785
4515
|
};
|
|
1786
4516
|
if (seekPosition) {
|
|
1787
4517
|
anim.currentTime = seekPosition;
|
|
@@ -1802,29 +4532,29 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
1802
4532
|
"isReady": () => true,
|
|
1803
4533
|
"getRootElement": () => rootElement || null,
|
|
1804
4534
|
"isPlaying": () => {
|
|
1805
|
-
var
|
|
1806
|
-
return ((
|
|
4535
|
+
var _a2;
|
|
4536
|
+
return ((_a2 = animations[0]) == null ? void 0 : _a2.playState) === "running";
|
|
1807
4537
|
},
|
|
1808
4538
|
"play": () => {
|
|
1809
|
-
var
|
|
4539
|
+
var _a2;
|
|
1810
4540
|
animations.forEach((a) => a.play());
|
|
1811
|
-
(
|
|
4541
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
|
|
1812
4542
|
},
|
|
1813
4543
|
"pause": () => {
|
|
1814
|
-
var
|
|
4544
|
+
var _a2;
|
|
1815
4545
|
animations.forEach((a) => a.pause());
|
|
1816
|
-
(
|
|
4546
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
|
|
1817
4547
|
},
|
|
1818
4548
|
"cancel": () => {
|
|
1819
|
-
var
|
|
4549
|
+
var _a2;
|
|
1820
4550
|
animations.forEach((a) => a.cancel());
|
|
1821
|
-
(
|
|
4551
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
|
|
1822
4552
|
},
|
|
1823
4553
|
"finish": () => {
|
|
1824
|
-
var
|
|
4554
|
+
var _a2;
|
|
1825
4555
|
for (const a of animations) {
|
|
1826
4556
|
try {
|
|
1827
|
-
if (((
|
|
4557
|
+
if (((_a2 = a.effect) == null ? void 0 : _a2.getTiming().iterations) === Infinity) {
|
|
1828
4558
|
a.effect.updateTiming({ iterations: 1 });
|
|
1829
4559
|
a.finish();
|
|
1830
4560
|
a.effect.updateTiming({ iterations: Infinity });
|
|
@@ -1841,8 +4571,8 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
1841
4571
|
return api;
|
|
1842
4572
|
},
|
|
1843
4573
|
"getCurrentTime": () => {
|
|
1844
|
-
var
|
|
1845
|
-
const res = (_b = (
|
|
4574
|
+
var _a2, _b;
|
|
4575
|
+
const res = (_b = (_a2 = animations[0]) == null ? void 0 : _a2.currentTime) != null ? _b : null;
|
|
1846
4576
|
return res !== null ? +res : null;
|
|
1847
4577
|
},
|
|
1848
4578
|
"setCurrentTime": (time) => {
|
|
@@ -1865,15 +4595,15 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
1865
4595
|
function createAnimatorFromConfig(doc, adapter, callbacks, rootElement) {
|
|
1866
4596
|
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
1867
4597
|
let res;
|
|
1868
|
-
if (animatorConfig.mode ===
|
|
4598
|
+
if (animatorConfig.mode === PxAnimatorMode.frames) {
|
|
1869
4599
|
res = createFrameLoopAnimator(doc, adapter, callbacks, rootElement);
|
|
1870
4600
|
} else {
|
|
1871
4601
|
res = createWebApiAnimator(
|
|
1872
4602
|
doc,
|
|
1873
4603
|
callbacks,
|
|
1874
4604
|
rootElement,
|
|
1875
|
-
animatorConfig.mode ===
|
|
1876
|
-
//
|
|
4605
|
+
animatorConfig.mode === PxAnimatorMode.webapi
|
|
4606
|
+
// forcing webapi
|
|
1877
4607
|
) || createFrameLoopAnimator(doc, adapter, callbacks, rootElement);
|
|
1878
4608
|
}
|
|
1879
4609
|
if (animatorConfig.debugInstName) {
|
|
@@ -1899,6 +4629,7 @@ function deepClone(value) {
|
|
|
1899
4629
|
return cloned;
|
|
1900
4630
|
}
|
|
1901
4631
|
function generateNewIds(doc) {
|
|
4632
|
+
var _a, _b;
|
|
1902
4633
|
const cloned = deepClone(doc);
|
|
1903
4634
|
const idMap = /* @__PURE__ */ new Map();
|
|
1904
4635
|
const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
|
|
@@ -1924,6 +4655,8 @@ function generateNewIds(doc) {
|
|
|
1924
4655
|
const newId = generateUniqueId();
|
|
1925
4656
|
idMap.set(oldId, newId);
|
|
1926
4657
|
node.id = newId;
|
|
4658
|
+
} else if (node.animate) {
|
|
4659
|
+
node.id = generateUniqueId();
|
|
1927
4660
|
}
|
|
1928
4661
|
if (Array.isArray(node.children)) {
|
|
1929
4662
|
for (const child of node.children) {
|
|
@@ -1965,23 +4698,21 @@ function generateNewIds(doc) {
|
|
|
1965
4698
|
value[styleProp] = replaceUrlRefs(styleValue, idMap);
|
|
1966
4699
|
}
|
|
1967
4700
|
}
|
|
1968
|
-
} else if (typeof value === "object" && value !== null
|
|
4701
|
+
} else if (typeof value === "object" && value !== null) {
|
|
1969
4702
|
updateRefs(value);
|
|
1970
4703
|
}
|
|
1971
4704
|
}
|
|
1972
4705
|
}
|
|
1973
4706
|
collectIds(cloned);
|
|
1974
4707
|
updateRefs(cloned);
|
|
1975
|
-
const
|
|
1976
|
-
if (
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
binding.id = newId;
|
|
1982
|
-
}
|
|
1983
|
-
}
|
|
4708
|
+
const docAnimate = (_a = cloned.animator) == null ? void 0 : _a.animate;
|
|
4709
|
+
if (docAnimate && typeof docAnimate === "object") {
|
|
4710
|
+
const updatedAnimate = {};
|
|
4711
|
+
for (const [id, anim] of Object.entries(docAnimate)) {
|
|
4712
|
+
const newId = (_b = idMap.get(id)) != null ? _b : id;
|
|
4713
|
+
updatedAnimate[newId] = anim;
|
|
1984
4714
|
}
|
|
4715
|
+
cloned.animator = __spreadProps(__spreadValues({}, cloned.animator), { animate: updatedAnimate });
|
|
1985
4716
|
}
|
|
1986
4717
|
return cloned;
|
|
1987
4718
|
}
|
|
@@ -1992,8 +4723,12 @@ function replaceUrlRefs(value, idMap) {
|
|
|
1992
4723
|
});
|
|
1993
4724
|
}
|
|
1994
4725
|
function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
|
|
4726
|
+
const effectsWarnings = validateNodeEffects(doc);
|
|
4727
|
+
for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
|
|
1995
4728
|
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
1996
4729
|
animatorConfig.debug = true;
|
|
4730
|
+
const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi;
|
|
4731
|
+
doc = materialiseAllInTree(doc, engine);
|
|
1997
4732
|
let rootElement = null;
|
|
1998
4733
|
if (containerElement && doc.children) {
|
|
1999
4734
|
doc = generateNewIds(doc);
|
|
@@ -2007,14 +4742,22 @@ function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
|
|
|
2007
4742
|
}
|
|
2008
4743
|
return createAnimatorFromConfig(doc, adapter, callbacks, rootElement);
|
|
2009
4744
|
}
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
4745
|
+
var PX_ANIMATOR_DATA_KEY = "data";
|
|
4746
|
+
function createAnimator(options) {
|
|
4747
|
+
const { src, data, adapter, callbacks, container } = options;
|
|
4748
|
+
if (data !== void 0 && src !== void 0) {
|
|
4749
|
+
throw new Error("createAnimator: provide either `src` or `data`, not both");
|
|
4750
|
+
}
|
|
4751
|
+
if (data === void 0 && src === void 0) {
|
|
4752
|
+
throw new Error("createAnimator: either `src` or `data` is required");
|
|
4753
|
+
}
|
|
4754
|
+
if (data !== void 0) {
|
|
4755
|
+
return createAnimatorImpl(data, adapter, callbacks, container);
|
|
2013
4756
|
}
|
|
2014
4757
|
let animator = null;
|
|
2015
|
-
fetch(
|
|
4758
|
+
fetch(src).then((res) => res.json()).then((json) => {
|
|
2016
4759
|
if (isPxElementFileFormat(json)) {
|
|
2017
|
-
animator = createAnimatorImpl(json, adapter, callbacks,
|
|
4760
|
+
animator = createAnimatorImpl(json, adapter, callbacks, container);
|
|
2018
4761
|
} else {
|
|
2019
4762
|
console.error("Invalid animation document format");
|
|
2020
4763
|
}
|
|
@@ -2054,7 +4797,7 @@ function loadTagAnimators() {
|
|
|
2054
4797
|
if (!element[PX_ANIM_ATTR_NAME]) {
|
|
2055
4798
|
const src = element.getAttribute(PX_ANIM_SRC_ATTR_NAME);
|
|
2056
4799
|
if (src) {
|
|
2057
|
-
element[PX_ANIM_ATTR_NAME] = createAnimator(src,
|
|
4800
|
+
element[PX_ANIM_ATTR_NAME] = createAnimator({ src, container: element });
|
|
2058
4801
|
}
|
|
2059
4802
|
}
|
|
2060
4803
|
}
|
|
@@ -2064,20 +4807,269 @@ if (typeof window !== "undefined") {
|
|
|
2064
4807
|
window["createAnimator"] = createAnimator;
|
|
2065
4808
|
window["setupAnimationTriggers"] = setupAnimationTriggers;
|
|
2066
4809
|
}
|
|
4810
|
+
|
|
4811
|
+
// src/effects/PlayerEffectsUtil.visualModel.ts
|
|
4812
|
+
var IDENTITY = [1, 0, 0, 1, 0, 0];
|
|
4813
|
+
function mul(m, n) {
|
|
4814
|
+
return [
|
|
4815
|
+
m[0] * n[0] + m[2] * n[1],
|
|
4816
|
+
m[1] * n[0] + m[3] * n[1],
|
|
4817
|
+
m[0] * n[2] + m[2] * n[3],
|
|
4818
|
+
m[1] * n[2] + m[3] * n[3],
|
|
4819
|
+
m[0] * n[4] + m[2] * n[5] + m[4],
|
|
4820
|
+
m[1] * n[4] + m[3] * n[5] + m[5]
|
|
4821
|
+
];
|
|
4822
|
+
}
|
|
4823
|
+
var translateM = (x, y) => [1, 0, 0, 1, x, y];
|
|
4824
|
+
var scaleM = (sx, sy) => [sx, 0, 0, sy, 0, 0];
|
|
4825
|
+
function rotateM(deg) {
|
|
4826
|
+
const r = deg * Math.PI / 180;
|
|
4827
|
+
return [Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0];
|
|
4828
|
+
}
|
|
4829
|
+
var skewXM = (deg) => [1, 0, Math.tan(deg * Math.PI / 180), 1, 0, 0];
|
|
4830
|
+
var skewYM = (deg) => [1, Math.tan(deg * Math.PI / 180), 0, 1, 0, 0];
|
|
4831
|
+
function parseTransformString(s) {
|
|
4832
|
+
let m = IDENTITY;
|
|
4833
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
4834
|
+
let hit;
|
|
4835
|
+
while (hit = re.exec(s)) {
|
|
4836
|
+
const fn = hit[1];
|
|
4837
|
+
const a = hit[2].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
4838
|
+
if (fn === "translate") m = mul(m, translateM(a[0] || 0, a[1] || 0));
|
|
4839
|
+
else if (fn === "scale") m = mul(m, scaleM(a[0], a.length > 1 ? a[1] : a[0]));
|
|
4840
|
+
else if (fn === "rotate") m = mul(m, rotateM(a[0]));
|
|
4841
|
+
else if (fn === "skewX") m = mul(m, skewXM(a[0]));
|
|
4842
|
+
else if (fn === "skewY") m = mul(m, skewYM(a[0]));
|
|
4843
|
+
else if (fn === "matrix") m = mul(m, [a[0], a[1], a[2], a[3], a[4], a[5]]);
|
|
4844
|
+
}
|
|
4845
|
+
return m;
|
|
4846
|
+
}
|
|
4847
|
+
function partsToMatrix(p) {
|
|
4848
|
+
let m = IDENTITY;
|
|
4849
|
+
if (p.translate) m = mul(m, translateM(p.translate[0], p.translate[1]));
|
|
4850
|
+
const pivot = p.origin && (p.rotate !== void 0 || p.scale);
|
|
4851
|
+
if (pivot) m = mul(m, translateM(p.origin[0], p.origin[1]));
|
|
4852
|
+
if (p.rotate !== void 0) m = mul(m, rotateM(p.rotate));
|
|
4853
|
+
if (p.scale) m = mul(m, scaleM(p.scale[0], p.scale[1]));
|
|
4854
|
+
if (pivot) m = mul(m, translateM(-p.origin[0], -p.origin[1]));
|
|
4855
|
+
return m;
|
|
4856
|
+
}
|
|
4857
|
+
function lerp(a, b, f) {
|
|
4858
|
+
return a + (b - a) * f;
|
|
4859
|
+
}
|
|
4860
|
+
function interpParts(kfs, t) {
|
|
4861
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
4862
|
+
if (!kfs.length) return {};
|
|
4863
|
+
if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value || {};
|
|
4864
|
+
if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value || {};
|
|
4865
|
+
let i = 0;
|
|
4866
|
+
while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
|
|
4867
|
+
const a = kfs[i], b = kfs[i + 1];
|
|
4868
|
+
const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
|
|
4869
|
+
const va = a.value || {}, vb = b.value || {};
|
|
4870
|
+
const out = {};
|
|
4871
|
+
if (va.translate && vb.translate) out.translate = [lerp(va.translate[0], vb.translate[0], f), lerp(va.translate[1], vb.translate[1], f)];
|
|
4872
|
+
else out.translate = va.translate || vb.translate;
|
|
4873
|
+
if (va.rotate !== void 0 && vb.rotate !== void 0) out.rotate = lerp(va.rotate, vb.rotate, f);
|
|
4874
|
+
else out.rotate = (_g = va.rotate) != null ? _g : vb.rotate;
|
|
4875
|
+
if (va.scale && vb.scale) out.scale = [lerp(va.scale[0], vb.scale[0], f), lerp(va.scale[1], vb.scale[1], f)];
|
|
4876
|
+
else out.scale = va.scale || vb.scale;
|
|
4877
|
+
out.origin = va.origin || vb.origin;
|
|
4878
|
+
return out;
|
|
4879
|
+
}
|
|
4880
|
+
function evalTransformValue(v, t) {
|
|
4881
|
+
if (v === void 0 || v === null) return IDENTITY;
|
|
4882
|
+
if (typeof v === "string") return parseTransformString(v);
|
|
4883
|
+
if (v.keyframes) return partsToMatrix(interpParts(v.keyframes, t));
|
|
4884
|
+
if (v.value) return partsToMatrix(v.value);
|
|
4885
|
+
return IDENTITY;
|
|
4886
|
+
}
|
|
4887
|
+
function nodeMatrix(node, t) {
|
|
4888
|
+
if (node.animate && node.animate.transform) return evalTransformValue(node.animate.transform, t);
|
|
4889
|
+
if (node.transform !== void 0) return evalTransformValue(node.transform, t);
|
|
4890
|
+
return IDENTITY;
|
|
4891
|
+
}
|
|
4892
|
+
function evalScalar(animated, staticVal, fallback, t) {
|
|
4893
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4894
|
+
if (animated && animated.keyframes && animated.keyframes.length) {
|
|
4895
|
+
const kfs = animated.keyframes;
|
|
4896
|
+
if (t <= ((_a = kfs[0].time) != null ? _a : 0)) return kfs[0].value;
|
|
4897
|
+
if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value;
|
|
4898
|
+
let i = 0;
|
|
4899
|
+
while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
|
|
4900
|
+
const a = kfs[i], b = kfs[i + 1];
|
|
4901
|
+
const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
|
|
4902
|
+
return lerp(a.value, b.value, f);
|
|
4903
|
+
}
|
|
4904
|
+
return staticVal !== void 0 ? Number(staticVal) : fallback;
|
|
4905
|
+
}
|
|
4906
|
+
var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
|
|
4907
|
+
var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
|
|
4908
|
+
function buildIdMap2(node, map) {
|
|
4909
|
+
var _a;
|
|
4910
|
+
if (typeof node.id === "string") map.set(node.id, node);
|
|
4911
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => buildIdMap2(c, map));
|
|
4912
|
+
}
|
|
4913
|
+
function num(v) {
|
|
4914
|
+
return v === void 0 || v === null ? 0 : Number(v);
|
|
4915
|
+
}
|
|
4916
|
+
function round(n) {
|
|
4917
|
+
return Math.round(n * 100) / 100 + 0;
|
|
4918
|
+
}
|
|
4919
|
+
function geomKey(node) {
|
|
4920
|
+
var _a;
|
|
4921
|
+
switch (node.type) {
|
|
4922
|
+
case "rect":
|
|
4923
|
+
return num(node.width) + "," + num(node.height) + "," + num(node.x) + "," + num(node.y);
|
|
4924
|
+
case "ellipse":
|
|
4925
|
+
return num(node.rx) + "," + num(node.ry) + "," + num(node.cx) + "," + num(node.cy);
|
|
4926
|
+
case "circle":
|
|
4927
|
+
return num(node.r) + "," + num(node.cx) + "," + num(node.cy);
|
|
4928
|
+
case "path":
|
|
4929
|
+
return String((_a = node.d) != null ? _a : "");
|
|
4930
|
+
default:
|
|
4931
|
+
return "";
|
|
4932
|
+
}
|
|
4933
|
+
}
|
|
4934
|
+
function describePrimitive(node, m, t) {
|
|
4935
|
+
var _a, _b, _c, _d, _e;
|
|
4936
|
+
const fill = (_a = node.fill) != null ? _a : "";
|
|
4937
|
+
const stroke = (_b = node.stroke) != null ? _b : "";
|
|
4938
|
+
const sw = (_d = (_c = node["stroke-width"]) != null ? _c : node.strokeWidth) != null ? _d : "";
|
|
4939
|
+
const opacity = round(evalScalar((_e = node.animate) == null ? void 0 : _e.opacity, node.opacity, 1, t));
|
|
4940
|
+
const masked = node.mask ? 1 : 0;
|
|
4941
|
+
const mat = m.map(round).join(",");
|
|
4942
|
+
return node.type + "|" + geomKey(node) + "|[" + mat + "]|f:" + fill + "|s:" + stroke + "|sw:" + (num(sw) || "") + "|o:" + opacity + "|m:" + masked;
|
|
4943
|
+
}
|
|
4944
|
+
function flatten(node, parent, t, idMap, out) {
|
|
4945
|
+
var _a;
|
|
4946
|
+
const type = node.type || "";
|
|
4947
|
+
if (SKIP_TYPES.has(type)) return;
|
|
4948
|
+
const m = mul(parent, nodeMatrix(node, t));
|
|
4949
|
+
if (type === "use") {
|
|
4950
|
+
const targetId = typeof node.href === "string" ? node.href.replace(/^#/, "") : "";
|
|
4951
|
+
const target = idMap.get(targetId);
|
|
4952
|
+
const useM = mul(m, translateM(num(node.x), num(node.y)));
|
|
4953
|
+
if (target) flatten(target, useM, t, idMap, out);
|
|
4954
|
+
else out.push("UNRESOLVED_USE:#" + targetId);
|
|
4955
|
+
return;
|
|
4956
|
+
}
|
|
4957
|
+
if (CONTAINER_TYPES.has(type)) {
|
|
4958
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => flatten(c, m, t, idMap, out));
|
|
4959
|
+
return;
|
|
4960
|
+
}
|
|
4961
|
+
out.push(describePrimitive(node, m, t));
|
|
4962
|
+
}
|
|
4963
|
+
function collectSampleTimes(node, into) {
|
|
4964
|
+
var _a;
|
|
4965
|
+
into.add(0);
|
|
4966
|
+
const scanAnim = (anim) => {
|
|
4967
|
+
var _a2;
|
|
4968
|
+
if (!anim || typeof anim !== "object") return;
|
|
4969
|
+
for (const key of Object.keys(anim)) {
|
|
4970
|
+
const kfs = (_a2 = anim[key]) == null ? void 0 : _a2.keyframes;
|
|
4971
|
+
if (Array.isArray(kfs)) kfs.forEach((kf) => {
|
|
4972
|
+
var _a3;
|
|
4973
|
+
return into.add((_a3 = kf.time) != null ? _a3 : 0);
|
|
4974
|
+
});
|
|
4975
|
+
}
|
|
4976
|
+
};
|
|
4977
|
+
scanAnim(node.animate);
|
|
4978
|
+
if (node.transform && typeof node.transform === "object" && node.transform.keyframes) {
|
|
4979
|
+
node.transform.keyframes.forEach((kf) => {
|
|
4980
|
+
var _a2;
|
|
4981
|
+
return into.add((_a2 = kf.time) != null ? _a2 : 0);
|
|
4982
|
+
});
|
|
4983
|
+
}
|
|
4984
|
+
(_a = node.children) == null ? void 0 : _a.forEach((c) => collectSampleTimes(c, into));
|
|
4985
|
+
}
|
|
4986
|
+
function visualModelAt(root, t) {
|
|
4987
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
4988
|
+
buildIdMap2(root, idMap);
|
|
4989
|
+
const out = [];
|
|
4990
|
+
flatten(root, IDENTITY, t, idMap, out);
|
|
4991
|
+
return out.sort();
|
|
4992
|
+
}
|
|
4993
|
+
function diffInEffect(a, b) {
|
|
4994
|
+
const times = /* @__PURE__ */ new Set();
|
|
4995
|
+
collectSampleTimes(a, times);
|
|
4996
|
+
collectSampleTimes(b, times);
|
|
4997
|
+
const diffs = [];
|
|
4998
|
+
for (const t of Array.from(times).sort((x, y) => x - y)) {
|
|
4999
|
+
const ma = visualModelAt(a, t);
|
|
5000
|
+
const mb = visualModelAt(b, t);
|
|
5001
|
+
const onlyInA = subtractMultiset(ma, mb);
|
|
5002
|
+
const onlyInB = subtractMultiset(mb, ma);
|
|
5003
|
+
if (onlyInA.length || onlyInB.length) diffs.push({ time: t, onlyInA, onlyInB });
|
|
5004
|
+
}
|
|
5005
|
+
return diffs;
|
|
5006
|
+
}
|
|
5007
|
+
function subtractMultiset(a, b) {
|
|
5008
|
+
const counts = /* @__PURE__ */ new Map();
|
|
5009
|
+
for (const x of b) counts.set(x, (counts.get(x) || 0) + 1);
|
|
5010
|
+
const extra = [];
|
|
5011
|
+
for (const x of a) {
|
|
5012
|
+
const c = counts.get(x) || 0;
|
|
5013
|
+
if (c > 0) counts.set(x, c - 1);
|
|
5014
|
+
else extra.push(x);
|
|
5015
|
+
}
|
|
5016
|
+
return extra;
|
|
5017
|
+
}
|
|
2067
5018
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2068
5019
|
0 && (module.exports = {
|
|
2069
5020
|
COLOUR_ATTR_NAMES,
|
|
5021
|
+
PX_ANIMATOR_DATA_KEY,
|
|
2070
5022
|
PX_ANIM_ATTR_NAME,
|
|
2071
5023
|
PX_ANIM_SRC_ATTR_NAME,
|
|
5024
|
+
PX_TRANSFORM_PART_KEYS,
|
|
5025
|
+
PxAnimatedSvgDocumentSchema,
|
|
5026
|
+
PxAnimationDefinitionSchema,
|
|
5027
|
+
PxAnimatorConfigSchema,
|
|
5028
|
+
PxAnimatorEngine,
|
|
5029
|
+
PxAnimatorMode,
|
|
5030
|
+
PxAttrValueSchema,
|
|
5031
|
+
PxBezierPathSchema,
|
|
5032
|
+
PxBindingSchema,
|
|
5033
|
+
PxDefsSchema,
|
|
5034
|
+
PxEasingOrRefSchema,
|
|
5035
|
+
PxEffectsSchema,
|
|
5036
|
+
PxElementAnimationSchema,
|
|
5037
|
+
PxFillGradientEffectSchema,
|
|
5038
|
+
PxGradientSpreadMethod,
|
|
5039
|
+
PxGradientStopSchema,
|
|
5040
|
+
PxGradientType,
|
|
5041
|
+
PxGradientUnits,
|
|
5042
|
+
PxKeyframeSchema,
|
|
5043
|
+
PxLoopSchema,
|
|
5044
|
+
PxMaskedByEffectSchema,
|
|
5045
|
+
PxNodeBase,
|
|
5046
|
+
PxNodeSchema,
|
|
5047
|
+
PxPropertyAnimationSchema,
|
|
5048
|
+
PxRefEffectSchema,
|
|
5049
|
+
PxRepeaterEffectSchema,
|
|
5050
|
+
PxRetimeEffectSchema,
|
|
5051
|
+
PxStrokeGradientEffectSchema,
|
|
5052
|
+
PxSvgNodeExtra,
|
|
5053
|
+
PxTextAlongPathEffectSchema,
|
|
5054
|
+
PxTransformPartsSchema,
|
|
5055
|
+
PxTransformValueSchema,
|
|
5056
|
+
PxTransformationEffectSchema,
|
|
5057
|
+
PxTriggerSchema,
|
|
5058
|
+
PxTrimPathEffectSchema,
|
|
2072
5059
|
STYLE_ATTR_NAMES,
|
|
2073
5060
|
TRANSFORM_FN_NAMES,
|
|
5061
|
+
applyPlayerEffects,
|
|
2074
5062
|
calcAnimationValues,
|
|
2075
5063
|
camelCaseToKebabWordIfNeeded,
|
|
5064
|
+
collectSampleTimes,
|
|
2076
5065
|
createAnimator,
|
|
2077
5066
|
createAnimatorImpl,
|
|
2078
5067
|
createBasicFrameLoopAnimator,
|
|
2079
5068
|
createFrameLoopAnimator,
|
|
2080
5069
|
createWebApiAnimator,
|
|
5070
|
+
describeSchema,
|
|
5071
|
+
diffInEffect,
|
|
5072
|
+
evaluateMotionPathSegment,
|
|
2081
5073
|
generateNewIds,
|
|
2082
5074
|
getAnimatorConfig,
|
|
2083
5075
|
getBindings,
|
|
@@ -2087,9 +5079,20 @@ if (typeof window !== "undefined") {
|
|
|
2087
5079
|
isPxElementFileFormat,
|
|
2088
5080
|
isPxElementFileFormatDeep,
|
|
2089
5081
|
loadTagAnimators,
|
|
5082
|
+
materialiseAllInTree,
|
|
5083
|
+
materialiseAnimatedUseInstances,
|
|
5084
|
+
materialiseInternalLoopsInPropAnim,
|
|
5085
|
+
materialiseInternalLoopsInTree,
|
|
5086
|
+
materialiseMotionPathInPropAnim,
|
|
5087
|
+
materialiseMotionPathsInTree,
|
|
2090
5088
|
normalizeDocument,
|
|
5089
|
+
propAnimIsMotionPath,
|
|
5090
|
+
px,
|
|
2091
5091
|
renderNode,
|
|
5092
|
+
schemaKeys,
|
|
2092
5093
|
setupAnimationTriggers,
|
|
2093
|
-
toRGBA
|
|
5094
|
+
toRGBA,
|
|
5095
|
+
validateNodeEffects,
|
|
5096
|
+
visualModelAt
|
|
2094
5097
|
});
|
|
2095
5098
|
//# sourceMappingURL=index.cjs.map
|