@pixodesk/svg-animator-web 1.0.21 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.cjs +615 -412
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -3
- package/dist/index.d.ts +16 -3
- package/dist/index.js +613 -411
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.prerendered-waapi.umd.js +1687 -0
- package/dist/index.prerendered-waapi.umd.js.map +1 -0
- package/dist/index.prerendered-waapi.umd.min.js +1 -0
- package/dist/index.prerendered.umd.js +2200 -0
- package/dist/index.prerendered.umd.js.map +1 -0
- package/dist/index.prerendered.umd.min.js +1 -0
- package/dist/index.umd.js +756 -976
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +17 -12
|
@@ -0,0 +1,1687 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var PixodeskAnimator = (() => {
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
22
|
+
};
|
|
23
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
+
var __export = (target, all) => {
|
|
25
|
+
for (var name in all)
|
|
26
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
27
|
+
};
|
|
28
|
+
var __copyProps = (to, from, except, desc) => {
|
|
29
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
30
|
+
for (let key of __getOwnPropNames(from))
|
|
31
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
32
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
33
|
+
}
|
|
34
|
+
return to;
|
|
35
|
+
};
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
|
|
38
|
+
// src/index.prerendered-waapi.ts
|
|
39
|
+
var index_prerendered_waapi_exports = {};
|
|
40
|
+
__export(index_prerendered_waapi_exports, {
|
|
41
|
+
PX_ANIMATOR_DATA_KEY: () => PX_ANIMATOR_DATA_KEY,
|
|
42
|
+
createAnimator: () => createPrerenderedWaapiAnimator,
|
|
43
|
+
setupAnimationTriggers: () => setupAnimationTriggers
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// ../svg-animator-core/src/PxAnimatorConstants.ts
|
|
47
|
+
var PxAnimatorMode = {
|
|
48
|
+
auto: "auto",
|
|
49
|
+
waapi: "waapi",
|
|
50
|
+
frames: "frames"
|
|
51
|
+
};
|
|
52
|
+
var PxAnimatorEngine = {
|
|
53
|
+
waapi: PxAnimatorMode.waapi,
|
|
54
|
+
frames: PxAnimatorMode.frames
|
|
55
|
+
};
|
|
56
|
+
var PxLoopExtend = {
|
|
57
|
+
/** Segment from the START; the animation is extended BEFORE the first keyframe
|
|
58
|
+
* (intro loops that run before the main timeline begins). */
|
|
59
|
+
before: "before",
|
|
60
|
+
/** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
|
|
61
|
+
* loops that continue once the main timeline has finished). */
|
|
62
|
+
after: "after"
|
|
63
|
+
};
|
|
64
|
+
function getAnimatorConfig(doc) {
|
|
65
|
+
var _a;
|
|
66
|
+
return (doc == null ? void 0 : doc.animator) || ((_a = doc == null ? void 0 : doc.meta) == null ? void 0 : _a.animator);
|
|
67
|
+
}
|
|
68
|
+
function getDefs(doc) {
|
|
69
|
+
var _a;
|
|
70
|
+
if (!doc) return void 0;
|
|
71
|
+
return (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.definitions;
|
|
72
|
+
}
|
|
73
|
+
function getBindings(doc) {
|
|
74
|
+
var _a;
|
|
75
|
+
if (!doc) return void 0;
|
|
76
|
+
const animateById = (_a = getAnimatorConfig(doc)) == null ? void 0 : _a.animateById;
|
|
77
|
+
if (!animateById) return void 0;
|
|
78
|
+
return Object.entries(animateById).map(([id, anim]) => ({ id, animate: anim }));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ../svg-animator-core/src/PxAnimatorUtil.ts
|
|
82
|
+
function bezierToSvgPath(path, forceCurves = false) {
|
|
83
|
+
var _a, _b, _c, _d;
|
|
84
|
+
const v = path.v;
|
|
85
|
+
const i = path.i;
|
|
86
|
+
const o = path.o;
|
|
87
|
+
const c = path.c;
|
|
88
|
+
if (!v.length) return "";
|
|
89
|
+
const d = [];
|
|
90
|
+
const len = v.length;
|
|
91
|
+
d.push("M" + v[0][0] + "," + v[0][1]);
|
|
92
|
+
for (let idx = 1; idx < len; idx++) {
|
|
93
|
+
const prevV = v[idx - 1];
|
|
94
|
+
const prevO = (_a = o == null ? void 0 : o[idx - 1]) != null ? _a : prevV;
|
|
95
|
+
const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
|
|
96
|
+
const currV = v[idx];
|
|
97
|
+
const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
|
|
98
|
+
if (isLine) {
|
|
99
|
+
d.push("L" + currV[0] + "," + currV[1]);
|
|
100
|
+
} else {
|
|
101
|
+
d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (c && len > 0) {
|
|
105
|
+
const lastV = v[len - 1];
|
|
106
|
+
const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
|
|
107
|
+
const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
|
|
108
|
+
const firstV = v[0];
|
|
109
|
+
const isLine = !forceCurves && (lastO[0] === lastV[0] && lastO[1] === lastV[1]) && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
|
|
110
|
+
if (!isLine) {
|
|
111
|
+
d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
|
|
112
|
+
}
|
|
113
|
+
d.push("z");
|
|
114
|
+
}
|
|
115
|
+
return d.join("");
|
|
116
|
+
}
|
|
117
|
+
function interpolateNum(a, b, t) {
|
|
118
|
+
return a + (b - a) * t;
|
|
119
|
+
}
|
|
120
|
+
function interpolateVec(a, b, t) {
|
|
121
|
+
const res = [];
|
|
122
|
+
const count = Math.max(a.length, b.length);
|
|
123
|
+
for (let i = 0; i < count; i++) {
|
|
124
|
+
res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
|
|
125
|
+
}
|
|
126
|
+
return res;
|
|
127
|
+
}
|
|
128
|
+
function interpolateColor(a, b, t) {
|
|
129
|
+
return [
|
|
130
|
+
interpolateNum(a[0] || 0, b[0] || 0, t),
|
|
131
|
+
interpolateNum(a[1] || 0, b[1] || 0, t),
|
|
132
|
+
interpolateNum(a[2] || 0, b[2] || 0, t),
|
|
133
|
+
interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
function interpolateBeziers(paths1, paths2, progress) {
|
|
137
|
+
const count = Math.max(paths1.length, paths2.length);
|
|
138
|
+
const res = [];
|
|
139
|
+
for (let i = 0; i < count; i++) {
|
|
140
|
+
res.push(interpolateBezier(paths1[i], paths2[i], progress));
|
|
141
|
+
}
|
|
142
|
+
return res;
|
|
143
|
+
}
|
|
144
|
+
function interpolateBezier(path1, path2, progress) {
|
|
145
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
146
|
+
if (!path1 || !path2) return path1 || path2 || { v: [] };
|
|
147
|
+
const t = Math.min(Math.max(progress, 0), 1);
|
|
148
|
+
const len = Math.min(path1.v.length, path2.v.length);
|
|
149
|
+
const v = [];
|
|
150
|
+
const i = [];
|
|
151
|
+
const o = [];
|
|
152
|
+
for (let idx = 0; idx < len; idx++) {
|
|
153
|
+
const v1 = path1.v[idx];
|
|
154
|
+
const v2 = path2.v[idx];
|
|
155
|
+
v.push(interpolateVec(v1, v2, t));
|
|
156
|
+
const i1 = (_b = (_a = path1.i) == null ? void 0 : _a[idx]) != null ? _b : v1;
|
|
157
|
+
const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
|
|
158
|
+
i.push(interpolateVec(i1, i2, t));
|
|
159
|
+
const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
|
|
160
|
+
const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
|
|
161
|
+
o.push(interpolateVec(o1, o2, t));
|
|
162
|
+
}
|
|
163
|
+
return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
|
|
164
|
+
}
|
|
165
|
+
function solveCubicBezierX(p1x, p2x, x) {
|
|
166
|
+
if (x <= 0) return 0;
|
|
167
|
+
if (x >= 1) return 1;
|
|
168
|
+
const cx = 3 * p1x;
|
|
169
|
+
const bx = 3 * (p2x - p1x) - cx;
|
|
170
|
+
const ax = 1 - cx - bx;
|
|
171
|
+
function sampleX(t) {
|
|
172
|
+
return ((ax * t + bx) * t + cx) * t;
|
|
173
|
+
}
|
|
174
|
+
function sampleDX(t) {
|
|
175
|
+
return (3 * ax * t + 2 * bx) * t + cx;
|
|
176
|
+
}
|
|
177
|
+
let t2 = x;
|
|
178
|
+
let t0 = 0;
|
|
179
|
+
let t1 = 1;
|
|
180
|
+
for (let i = 0; i < 8; i++) {
|
|
181
|
+
const x2 = sampleX(t2) - x;
|
|
182
|
+
if (Math.abs(x2) < 1e-6) return t2;
|
|
183
|
+
const d2 = sampleDX(t2);
|
|
184
|
+
if (Math.abs(d2) < 1e-6) break;
|
|
185
|
+
t2 -= x2 / d2;
|
|
186
|
+
}
|
|
187
|
+
t2 = x;
|
|
188
|
+
while (t0 < t1) {
|
|
189
|
+
const x2 = sampleX(t2);
|
|
190
|
+
if (Math.abs(x2 - x) < 1e-6) return t2;
|
|
191
|
+
if (x > x2) t0 = t2;
|
|
192
|
+
else t1 = t2;
|
|
193
|
+
t2 = (t1 + t0) / 2;
|
|
194
|
+
}
|
|
195
|
+
return t2;
|
|
196
|
+
}
|
|
197
|
+
function cubicBezier(easing) {
|
|
198
|
+
const [p1x, p1y, p2x, p2y] = easing;
|
|
199
|
+
const cy = 3 * p1y;
|
|
200
|
+
const by = 3 * (p2y - p1y) - cy;
|
|
201
|
+
const ay = 1 - cy - by;
|
|
202
|
+
function sampleCurveY(t) {
|
|
203
|
+
return ((ay * t + by) * t + cy) * t;
|
|
204
|
+
}
|
|
205
|
+
return function(x) {
|
|
206
|
+
return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function lerp2(a, b, t) {
|
|
210
|
+
return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
|
|
211
|
+
}
|
|
212
|
+
function subdivideCubicBezier(p0, p1, p2, p3, t) {
|
|
213
|
+
const q0 = lerp2(p0, p1, t);
|
|
214
|
+
const q1 = lerp2(p1, p2, t);
|
|
215
|
+
const q2 = lerp2(p2, p3, t);
|
|
216
|
+
const r0 = lerp2(q0, q1, t);
|
|
217
|
+
const r1 = lerp2(q1, q2, t);
|
|
218
|
+
const s = lerp2(r0, r1, t);
|
|
219
|
+
return {
|
|
220
|
+
left: [p0, q0, r0, s],
|
|
221
|
+
right: [s, r1, q2, p3]
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function splitEasing(easing, xFraction) {
|
|
225
|
+
if (!easing) return { left: void 0, right: void 0 };
|
|
226
|
+
if (xFraction <= 0) return { left: void 0, right: easing };
|
|
227
|
+
if (xFraction >= 1) return { left: easing, right: void 0 };
|
|
228
|
+
const [x1, y1, x2, y2] = easing;
|
|
229
|
+
const t = solveCubicBezierX(x1, x2, xFraction);
|
|
230
|
+
const p0 = [0, 0];
|
|
231
|
+
const p1 = [x1, y1];
|
|
232
|
+
const p2 = [x2, y2];
|
|
233
|
+
const p3 = [1, 1];
|
|
234
|
+
const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
|
|
235
|
+
const sx = left[3][0];
|
|
236
|
+
const sy = left[3][1];
|
|
237
|
+
let leftEasing;
|
|
238
|
+
if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
|
|
239
|
+
leftEasing = [
|
|
240
|
+
left[1][0] / sx,
|
|
241
|
+
left[1][1] / sy,
|
|
242
|
+
left[2][0] / sx,
|
|
243
|
+
left[2][1] / sy
|
|
244
|
+
];
|
|
245
|
+
}
|
|
246
|
+
let rightEasing;
|
|
247
|
+
const rx = 1 - sx;
|
|
248
|
+
const ry = 1 - sy;
|
|
249
|
+
if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
|
|
250
|
+
rightEasing = [
|
|
251
|
+
(right[1][0] - sx) / rx,
|
|
252
|
+
(right[1][1] - sy) / ry,
|
|
253
|
+
(right[2][0] - sx) / rx,
|
|
254
|
+
(right[2][1] - sy) / ry
|
|
255
|
+
];
|
|
256
|
+
}
|
|
257
|
+
return { left: leftEasing, right: rightEasing };
|
|
258
|
+
}
|
|
259
|
+
function reverseEasing(easing) {
|
|
260
|
+
if (!easing) return void 0;
|
|
261
|
+
return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
|
|
262
|
+
}
|
|
263
|
+
function toRGBA(color) {
|
|
264
|
+
const r = Math.round(color[0] * 255);
|
|
265
|
+
const g = Math.round(color[1] * 255);
|
|
266
|
+
const b = Math.round(color[2] * 255);
|
|
267
|
+
return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
|
|
268
|
+
}
|
|
269
|
+
function parseRgba(s) {
|
|
270
|
+
var _a;
|
|
271
|
+
const inner = (_a = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a[1];
|
|
272
|
+
if (!inner) throw new Error("Invalid rgb/rgba format");
|
|
273
|
+
const parts = inner.split(",").map((v) => +v.trim());
|
|
274
|
+
return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
|
|
275
|
+
}
|
|
276
|
+
function parseHex(s) {
|
|
277
|
+
const hex = s.slice(1);
|
|
278
|
+
const isShort = hex.length <= 4;
|
|
279
|
+
const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
|
|
280
|
+
const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
|
|
281
|
+
const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
|
|
282
|
+
const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
|
|
283
|
+
const result = [
|
|
284
|
+
parseInt(r, 16) / 255,
|
|
285
|
+
parseInt(g, 16) / 255,
|
|
286
|
+
parseInt(b, 16) / 255
|
|
287
|
+
];
|
|
288
|
+
if (a !== null) {
|
|
289
|
+
result.push(parseInt(a, 16) / 255);
|
|
290
|
+
}
|
|
291
|
+
return result;
|
|
292
|
+
}
|
|
293
|
+
function parseColor(s) {
|
|
294
|
+
if (!s) return void 0;
|
|
295
|
+
if (Array.isArray(s)) return s;
|
|
296
|
+
if (typeof s !== "string") return void 0;
|
|
297
|
+
if (s.startsWith("#")) {
|
|
298
|
+
return parseHex(s);
|
|
299
|
+
} else if (s.startsWith("rgb")) {
|
|
300
|
+
return parseRgba(s);
|
|
301
|
+
} else {
|
|
302
|
+
console.warn("Unsupported color format: " + s);
|
|
303
|
+
}
|
|
304
|
+
return void 0;
|
|
305
|
+
}
|
|
306
|
+
var COLOUR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
|
|
307
|
+
var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
|
|
308
|
+
function composeTransformParts(parts, opts) {
|
|
309
|
+
var _a;
|
|
310
|
+
if (!parts) return "";
|
|
311
|
+
const withUnits = (_a = opts == null ? void 0 : opts.withUnits) != null ? _a : true;
|
|
312
|
+
const segs = [];
|
|
313
|
+
const t = parts.translate;
|
|
314
|
+
const o = parts.origin;
|
|
315
|
+
const r = parts.rotate;
|
|
316
|
+
const k = parts.skew;
|
|
317
|
+
const s = parts.scale;
|
|
318
|
+
const tu = withUnits ? "px" : "";
|
|
319
|
+
const ru = withUnits ? "deg" : "";
|
|
320
|
+
if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
|
|
321
|
+
if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
|
|
322
|
+
if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
|
|
323
|
+
if (k !== void 0 && k !== null) segs.push("skewX(" + k + ru + ")");
|
|
324
|
+
if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
|
|
325
|
+
if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
|
|
326
|
+
return segs.join("");
|
|
327
|
+
}
|
|
328
|
+
function kebabToCamelCaseWord(kebab) {
|
|
329
|
+
return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
|
|
330
|
+
}
|
|
331
|
+
function isCamelCaseWord(word) {
|
|
332
|
+
return !word.includes("-") && /[a-z][A-Z]/.test(word);
|
|
333
|
+
}
|
|
334
|
+
var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
|
|
335
|
+
// Transform/positioning
|
|
336
|
+
"viewBox",
|
|
337
|
+
"preserveAspectRatio",
|
|
338
|
+
// Gradient
|
|
339
|
+
"gradientUnits",
|
|
340
|
+
"gradientTransform",
|
|
341
|
+
"spreadMethod",
|
|
342
|
+
// Pattern
|
|
343
|
+
"patternUnits",
|
|
344
|
+
"patternContentUnits",
|
|
345
|
+
"patternTransform",
|
|
346
|
+
// Clipping/masking
|
|
347
|
+
"clipPathUnits",
|
|
348
|
+
"maskUnits",
|
|
349
|
+
"maskContentUnits",
|
|
350
|
+
// Marker (SVG spec keeps these camelCase, like viewBox)
|
|
351
|
+
"markerUnits",
|
|
352
|
+
"markerWidth",
|
|
353
|
+
"markerHeight",
|
|
354
|
+
"refX",
|
|
355
|
+
"refY",
|
|
356
|
+
// Text
|
|
357
|
+
"textLength",
|
|
358
|
+
"lengthAdjust",
|
|
359
|
+
"startOffset",
|
|
360
|
+
// Filter
|
|
361
|
+
"filterUnits",
|
|
362
|
+
"primitiveUnits",
|
|
363
|
+
"tableValues",
|
|
364
|
+
// feFuncR/G/B/A transfer table (type="table")
|
|
365
|
+
"stdDeviation",
|
|
366
|
+
"baseFrequency",
|
|
367
|
+
"numOctaves",
|
|
368
|
+
"surfaceScale",
|
|
369
|
+
"diffuseConstant",
|
|
370
|
+
"specularConstant",
|
|
371
|
+
"specularExponent",
|
|
372
|
+
"kernelMatrix",
|
|
373
|
+
"kernelUnitLength",
|
|
374
|
+
"edgeMode",
|
|
375
|
+
"preserveAlpha",
|
|
376
|
+
"targetX",
|
|
377
|
+
"targetY"
|
|
378
|
+
// // Animation
|
|
379
|
+
// 'attributeName',
|
|
380
|
+
// 'attributeType',
|
|
381
|
+
// 'calcMode',
|
|
382
|
+
// 'keyTimes',
|
|
383
|
+
// 'keySplines',
|
|
384
|
+
// 'repeatCount',
|
|
385
|
+
// 'repeatDur'
|
|
386
|
+
]);
|
|
387
|
+
function camelCaseToKebabWordIfNeeded(camel) {
|
|
388
|
+
return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
389
|
+
}
|
|
390
|
+
function clamp(value, min, max) {
|
|
391
|
+
return Math.max(min, Math.min(value, max));
|
|
392
|
+
}
|
|
393
|
+
function bezier2D_pointAt(P0, P1, P2, P3, t) {
|
|
394
|
+
if (t <= 0) return [P0[0], P0[1]];
|
|
395
|
+
if (t >= 1) return [P3[0], P3[1]];
|
|
396
|
+
const u = 1 - t;
|
|
397
|
+
const u2 = u * u;
|
|
398
|
+
const u3 = u2 * u;
|
|
399
|
+
const t2 = t * t;
|
|
400
|
+
const t3 = t2 * t;
|
|
401
|
+
const w0 = u3;
|
|
402
|
+
const w1 = 3 * t * u2;
|
|
403
|
+
const w2 = 3 * t2 * u;
|
|
404
|
+
const w3 = t3;
|
|
405
|
+
return [
|
|
406
|
+
w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
|
|
407
|
+
w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
|
|
408
|
+
];
|
|
409
|
+
}
|
|
410
|
+
var BEZIER_T_NUDGE = 1e-4;
|
|
411
|
+
function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
|
|
412
|
+
const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
|
|
413
|
+
if (result[0] === 0 && result[1] === 0) {
|
|
414
|
+
const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
|
|
415
|
+
return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
|
|
416
|
+
}
|
|
417
|
+
return result;
|
|
418
|
+
}
|
|
419
|
+
function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
|
|
420
|
+
const u = 1 - t;
|
|
421
|
+
const a = 3 * u * u;
|
|
422
|
+
const b = 6 * t * u;
|
|
423
|
+
const c = 3 * t * t;
|
|
424
|
+
return [
|
|
425
|
+
a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
|
|
426
|
+
a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
|
|
427
|
+
];
|
|
428
|
+
}
|
|
429
|
+
function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
|
|
430
|
+
const n = steps + 1;
|
|
431
|
+
const ts = new Float64Array(n);
|
|
432
|
+
const ds = new Float64Array(n);
|
|
433
|
+
let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
|
|
434
|
+
ts[0] = 0;
|
|
435
|
+
ds[0] = 0;
|
|
436
|
+
let cum = 0;
|
|
437
|
+
for (let i = 1; i < n; i++) {
|
|
438
|
+
const t = i / steps;
|
|
439
|
+
const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
|
|
440
|
+
const dx = cur[0] - prev[0];
|
|
441
|
+
const dy = cur[1] - prev[1];
|
|
442
|
+
cum += Math.sqrt(dx * dx + dy * dy);
|
|
443
|
+
ts[i] = t;
|
|
444
|
+
ds[i] = cum;
|
|
445
|
+
prev = cur;
|
|
446
|
+
}
|
|
447
|
+
return { ts, ds };
|
|
448
|
+
}
|
|
449
|
+
function bezier2D_arcAtT(lut, t) {
|
|
450
|
+
const { ts, ds } = lut;
|
|
451
|
+
const last = ts.length - 1;
|
|
452
|
+
if (t <= ts[0]) return ds[0];
|
|
453
|
+
if (t >= ts[last]) return ds[last];
|
|
454
|
+
let lo = 1, hi = last;
|
|
455
|
+
while (lo < hi) {
|
|
456
|
+
const mid = lo + hi >>> 1;
|
|
457
|
+
if (ts[mid] < t) lo = mid + 1;
|
|
458
|
+
else hi = mid;
|
|
459
|
+
}
|
|
460
|
+
const tPrev = ts[hi - 1];
|
|
461
|
+
const span = ts[hi] - tPrev;
|
|
462
|
+
const frac = span > 0 ? (t - tPrev) / span : 0;
|
|
463
|
+
return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);
|
|
464
|
+
}
|
|
465
|
+
function invertEasing(easing) {
|
|
466
|
+
if (!easing) return (y) => y;
|
|
467
|
+
const flipped = [easing[1], easing[0], easing[3], easing[2]];
|
|
468
|
+
return cubicBezier(flipped);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// ../svg-animator-core/src/PxMotionPath.ts
|
|
472
|
+
function getKfTranslate(kf) {
|
|
473
|
+
var _a;
|
|
474
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
475
|
+
if (!v) return void 0;
|
|
476
|
+
if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
|
|
477
|
+
return [v[0], v[1]];
|
|
478
|
+
}
|
|
479
|
+
const tr = v.translate;
|
|
480
|
+
if (Array.isArray(tr) && tr.length >= 2) return [tr[0], tr[1]];
|
|
481
|
+
return void 0;
|
|
482
|
+
}
|
|
483
|
+
function getKfTime(kf) {
|
|
484
|
+
var _a, _b;
|
|
485
|
+
return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
|
|
486
|
+
}
|
|
487
|
+
function getKfEasing(kf) {
|
|
488
|
+
var _a;
|
|
489
|
+
return (_a = kf.easing) != null ? _a : kf.e;
|
|
490
|
+
}
|
|
491
|
+
function propAnimIsMotionPath(anim) {
|
|
492
|
+
var _a, _b, _c;
|
|
493
|
+
const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
|
|
494
|
+
if (!Array.isArray(kfs)) return false;
|
|
495
|
+
if (anim.autoOrient) return true;
|
|
496
|
+
for (const kf of kfs) {
|
|
497
|
+
if (((_b = kf.tangentIn) != null ? _b : kf.ti) || ((_c = kf.tangentOut) != null ? _c : kf.to)) return true;
|
|
498
|
+
}
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
var _segmentCache = /* @__PURE__ */ new WeakMap();
|
|
502
|
+
function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
|
|
503
|
+
var _a, _b;
|
|
504
|
+
let byNext = _segmentCache.get(prevKf);
|
|
505
|
+
const existing = byNext == null ? void 0 : byNext.get(nextKf);
|
|
506
|
+
if (existing) return existing;
|
|
507
|
+
const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
|
|
508
|
+
const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
|
|
509
|
+
const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
|
|
510
|
+
const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
|
|
511
|
+
const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
|
|
512
|
+
const entry = {
|
|
513
|
+
P0: prevPos,
|
|
514
|
+
P1,
|
|
515
|
+
P2,
|
|
516
|
+
P3: nextPos,
|
|
517
|
+
lut,
|
|
518
|
+
totalArc: lut.ds[lut.ds.length - 1]
|
|
519
|
+
};
|
|
520
|
+
if (!byNext) {
|
|
521
|
+
byNext = /* @__PURE__ */ new WeakMap();
|
|
522
|
+
_segmentCache.set(prevKf, byNext);
|
|
523
|
+
}
|
|
524
|
+
byNext.set(nextKf, entry);
|
|
525
|
+
return entry;
|
|
526
|
+
}
|
|
527
|
+
var DEFAULT_FLATNESS_TOL = 0.5;
|
|
528
|
+
var DEFAULT_ROTATION_TOL = 5;
|
|
529
|
+
var DEFAULT_MAX_SAMPLES = 32;
|
|
530
|
+
function materialiseMotionPathInPropAnim(anim, opts) {
|
|
531
|
+
var _a, _b, _c, _d;
|
|
532
|
+
if (!propAnimIsMotionPath(anim)) return anim;
|
|
533
|
+
const kfs = (_a = anim.keyframes) != null ? _a : anim.kfs;
|
|
534
|
+
if (!Array.isArray(kfs) || kfs.length < 2) return anim;
|
|
535
|
+
const autoOrient = !!anim.autoOrient;
|
|
536
|
+
const flatnessTol = (_b = opts == null ? void 0 : opts.flatnessTolerance) != null ? _b : DEFAULT_FLATNESS_TOL;
|
|
537
|
+
const rotationTol = (_c = opts == null ? void 0 : opts.rotationTolerance) != null ? _c : DEFAULT_ROTATION_TOL;
|
|
538
|
+
const maxSamples = (_d = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _d : DEFAULT_MAX_SAMPLES;
|
|
539
|
+
const out = [];
|
|
540
|
+
const firstPos = getKfTranslate(kfs[0]);
|
|
541
|
+
if (!firstPos) return anim;
|
|
542
|
+
const firstRotate = autoOrient ? derivAngleForFirstKf(kfs[0], kfs[1]) : void 0;
|
|
543
|
+
out.push(makeOutKf(
|
|
544
|
+
getKfTime(kfs[0]),
|
|
545
|
+
buildOutKfValue(getKfValueParts(kfs[0]), getKfValueParts(kfs[0]), 0, firstPos, firstRotate, autoOrient)
|
|
546
|
+
));
|
|
547
|
+
for (let i = 0; i < kfs.length - 1; i++) {
|
|
548
|
+
const prevKf = kfs[i];
|
|
549
|
+
const nextKf = kfs[i + 1];
|
|
550
|
+
const prevPos = getKfTranslate(prevKf);
|
|
551
|
+
const nextPos = getKfTranslate(nextKf);
|
|
552
|
+
if (!prevPos || !nextPos) {
|
|
553
|
+
out.push(makeOutKf(
|
|
554
|
+
getKfTime(nextKf),
|
|
555
|
+
buildOutKfValue(getKfValueParts(nextKf), getKfValueParts(nextKf), 1, nextPos != null ? nextPos : [0, 0], void 0, autoOrient)
|
|
556
|
+
));
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
if (autoOrient && i > 0) {
|
|
560
|
+
insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
|
|
561
|
+
}
|
|
562
|
+
materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
|
|
563
|
+
}
|
|
564
|
+
const lastInE = getKfEasing(kfs[kfs.length - 1]);
|
|
565
|
+
if (lastInE) out[out.length - 1].e = lastInE;
|
|
566
|
+
if (autoOrient) unwrapAutoOrientRotations(out);
|
|
567
|
+
const result = { kfs: out };
|
|
568
|
+
if (anim.loop !== void 0) result.loop = anim.loop;
|
|
569
|
+
return result;
|
|
570
|
+
}
|
|
571
|
+
function unwrapAutoOrientRotations(kfs) {
|
|
572
|
+
var _a;
|
|
573
|
+
let prev;
|
|
574
|
+
for (const kf of kfs) {
|
|
575
|
+
const v = (_a = kf.v) != null ? _a : kf.value;
|
|
576
|
+
if (!v || typeof v.rotate !== "number") continue;
|
|
577
|
+
if (prev === void 0) {
|
|
578
|
+
prev = v.rotate;
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
let r = v.rotate;
|
|
582
|
+
while (r - prev > 180) r -= 360;
|
|
583
|
+
while (r - prev < -180) r += 360;
|
|
584
|
+
v.rotate = r;
|
|
585
|
+
prev = r;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
function makeOutKf(time, value) {
|
|
589
|
+
return { t: time, v: value };
|
|
590
|
+
}
|
|
591
|
+
function getKfValueParts(kf) {
|
|
592
|
+
var _a;
|
|
593
|
+
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
594
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
|
|
595
|
+
return v;
|
|
596
|
+
}
|
|
597
|
+
function interpolatePart(prev, next, p) {
|
|
598
|
+
if (prev === void 0) return next;
|
|
599
|
+
if (next === void 0) return prev;
|
|
600
|
+
if (typeof prev === "number" && typeof next === "number") {
|
|
601
|
+
return prev + (next - prev) * p;
|
|
602
|
+
}
|
|
603
|
+
if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {
|
|
604
|
+
const out = new Array(prev.length);
|
|
605
|
+
for (let i = 0; i < prev.length; i++) {
|
|
606
|
+
const a = typeof prev[i] === "number" ? prev[i] : 0;
|
|
607
|
+
const b = typeof next[i] === "number" ? next[i] : 0;
|
|
608
|
+
out[i] = a + (b - a) * p;
|
|
609
|
+
}
|
|
610
|
+
return out;
|
|
611
|
+
}
|
|
612
|
+
return p < 0.5 ? prev : next;
|
|
613
|
+
}
|
|
614
|
+
function buildOutKfValue(prevV, nextV, p, translate, rotateDegFromAutoOrient, autoOrient) {
|
|
615
|
+
const value = { translate };
|
|
616
|
+
const keys = /* @__PURE__ */ new Set();
|
|
617
|
+
if (prevV) for (const k of Object.keys(prevV)) keys.add(k);
|
|
618
|
+
if (nextV) for (const k of Object.keys(nextV)) keys.add(k);
|
|
619
|
+
for (const k of keys) {
|
|
620
|
+
if (k === "translate") continue;
|
|
621
|
+
if (k === "rotate" && autoOrient) continue;
|
|
622
|
+
const pv = prevV == null ? void 0 : prevV[k];
|
|
623
|
+
const nv = nextV == null ? void 0 : nextV[k];
|
|
624
|
+
if (pv === void 0 && nv === void 0) continue;
|
|
625
|
+
value[k] = interpolatePart(pv, nv, p);
|
|
626
|
+
}
|
|
627
|
+
if (rotateDegFromAutoOrient !== void 0) {
|
|
628
|
+
value.rotate = rotateDegFromAutoOrient + explicitRotateAt(prevV, nextV, p);
|
|
629
|
+
}
|
|
630
|
+
return value;
|
|
631
|
+
}
|
|
632
|
+
function explicitRotateAt(prevV, nextV, p) {
|
|
633
|
+
const pv = typeof (prevV == null ? void 0 : prevV.rotate) === "number" ? prevV.rotate : void 0;
|
|
634
|
+
const nv = typeof (nextV == null ? void 0 : nextV.rotate) === "number" ? nextV.rotate : void 0;
|
|
635
|
+
if (pv === void 0 && nv === void 0) return 0;
|
|
636
|
+
const r = interpolatePart(pv, nv, p);
|
|
637
|
+
return typeof r === "number" ? r : 0;
|
|
638
|
+
}
|
|
639
|
+
function derivAngleForFirstKf(kf0, kf1) {
|
|
640
|
+
const p0 = getKfTranslate(kf0);
|
|
641
|
+
const p1 = getKfTranslate(kf1);
|
|
642
|
+
if (!p0 || !p1) return 0;
|
|
643
|
+
const seg = getSegmentCache(kf0, kf1, p0, p1);
|
|
644
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
645
|
+
return Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
646
|
+
}
|
|
647
|
+
function wrappedAngleDelta(a, b) {
|
|
648
|
+
let d = a - b;
|
|
649
|
+
while (d > 180) d -= 360;
|
|
650
|
+
while (d < -180) d += 360;
|
|
651
|
+
return d;
|
|
652
|
+
}
|
|
653
|
+
function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
|
|
654
|
+
var _a;
|
|
655
|
+
const lastKf = out[out.length - 1];
|
|
656
|
+
const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
|
|
657
|
+
const prevExit = lastV == null ? void 0 : lastV.rotate;
|
|
658
|
+
if (typeof prevExit !== "number") return;
|
|
659
|
+
const boundaryV = getKfValueParts(prevKf);
|
|
660
|
+
const prevExitTangent = prevExit - explicitRotateAt(boundaryV, boundaryV, 0);
|
|
661
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
662
|
+
const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
663
|
+
const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;
|
|
664
|
+
const delta = wrappedAngleDelta(nextEntry, prevExitTangent);
|
|
665
|
+
if (Math.abs(delta) <= rotationTol) return;
|
|
666
|
+
const prevTime = getKfTime(prevKf);
|
|
667
|
+
const stepTime = Math.min(prevTime + CORNER_STEP_AFTER_BOUNDARY_MS, (prevTime + getKfTime(nextKf)) / 2);
|
|
668
|
+
const dupValue = buildOutKfValue(
|
|
669
|
+
getKfValueParts(prevKf),
|
|
670
|
+
getKfValueParts(prevKf),
|
|
671
|
+
0,
|
|
672
|
+
prevPos,
|
|
673
|
+
nextEntry,
|
|
674
|
+
true
|
|
675
|
+
);
|
|
676
|
+
out.push(makeOutKf(stepTime, dupValue));
|
|
677
|
+
}
|
|
678
|
+
var CORNER_STEP_AFTER_BOUNDARY_MS = 0.05;
|
|
679
|
+
function materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
|
|
680
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
681
|
+
const prevTime = getKfTime(prevKf);
|
|
682
|
+
const nextTime = getKfTime(nextKf);
|
|
683
|
+
const prevEasing = getKfEasing(prevKf);
|
|
684
|
+
const invertFn = invertEasing(prevEasing);
|
|
685
|
+
const prevV = getKfValueParts(prevKf);
|
|
686
|
+
const nextV = getKfValueParts(nextKf);
|
|
687
|
+
const interiorTs = computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples);
|
|
688
|
+
const samples = [];
|
|
689
|
+
for (const t of interiorTs) {
|
|
690
|
+
const arc = bezier2D_arcAtT(seg.lut, t);
|
|
691
|
+
const p = clamp(seg.totalArc > 0 ? arc / seg.totalArc : t, 0, 1);
|
|
692
|
+
const u = clamp(invertFn(p), 0, 1);
|
|
693
|
+
const pos = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
694
|
+
const sample = { u, p, pos };
|
|
695
|
+
if (autoOrient) {
|
|
696
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
697
|
+
sample.rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
698
|
+
}
|
|
699
|
+
samples.push(sample);
|
|
700
|
+
}
|
|
701
|
+
let remaining = prevEasing;
|
|
702
|
+
let prevU = 0;
|
|
703
|
+
const startIdx = out.length - 1;
|
|
704
|
+
for (let i = 0; i < samples.length; i++) {
|
|
705
|
+
const s = samples[i];
|
|
706
|
+
const xFrac = prevU < 1 ? clamp((s.u - prevU) / (1 - prevU), 0, 1) : 1;
|
|
707
|
+
const { left, right } = splitEasing(remaining, xFrac);
|
|
708
|
+
const ownerIdx = i === 0 ? startIdx : out.length - 1;
|
|
709
|
+
if (left) out[ownerIdx].e = left;
|
|
710
|
+
else delete out[ownerIdx].e;
|
|
711
|
+
const tGlobal = prevTime + s.u * (nextTime - prevTime);
|
|
712
|
+
const value = buildOutKfValue(prevV, nextV, s.p, s.pos, s.rotateDeg, autoOrient);
|
|
713
|
+
out.push(makeOutKf(tGlobal, value));
|
|
714
|
+
remaining = right;
|
|
715
|
+
prevU = s.u;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
function computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples) {
|
|
719
|
+
const extremes = [];
|
|
720
|
+
addAxisExtremes(seg.P0[0], seg.P1[0], seg.P2[0], seg.P3[0], extremes);
|
|
721
|
+
addAxisExtremes(seg.P0[1], seg.P1[1], seg.P2[1], seg.P3[1], extremes);
|
|
722
|
+
extremes.sort((a, b) => a - b);
|
|
723
|
+
const critical = [0];
|
|
724
|
+
for (const t of extremes) {
|
|
725
|
+
if (t > critical[critical.length - 1] + 1e-6 && t < 1 - 1e-6) {
|
|
726
|
+
critical.push(t);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
critical.push(1);
|
|
730
|
+
const out = [];
|
|
731
|
+
const budget = { remaining: maxSamples - critical.length };
|
|
732
|
+
for (let i = 0; i < critical.length - 1; i++) {
|
|
733
|
+
bisect(critical[i], critical[i + 1], out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
734
|
+
}
|
|
735
|
+
return out;
|
|
736
|
+
}
|
|
737
|
+
function addAxisExtremes(p0, p1, p2, p3, out) {
|
|
738
|
+
const a = p1 - p0;
|
|
739
|
+
const b = p2 - p1;
|
|
740
|
+
const c = p3 - p2;
|
|
741
|
+
const A = a - 2 * b + c;
|
|
742
|
+
const B = 2 * (b - a);
|
|
743
|
+
const C = a;
|
|
744
|
+
if (Math.abs(A) < 1e-10) {
|
|
745
|
+
if (Math.abs(B) > 1e-10) {
|
|
746
|
+
const t = -C / B;
|
|
747
|
+
if (t > 1e-6 && t < 1 - 1e-6) out.push(t);
|
|
748
|
+
}
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
const disc = B * B - 4 * A * C;
|
|
752
|
+
if (disc < 0) return;
|
|
753
|
+
const sq = Math.sqrt(disc);
|
|
754
|
+
const t1 = (-B - sq) / (2 * A);
|
|
755
|
+
const t2 = (-B + sq) / (2 * A);
|
|
756
|
+
if (t1 > 1e-6 && t1 < 1 - 1e-6) out.push(t1);
|
|
757
|
+
if (t2 > 1e-6 && t2 < 1 - 1e-6) out.push(t2);
|
|
758
|
+
}
|
|
759
|
+
function bisect(tA, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget) {
|
|
760
|
+
const tMid = (tA + tB) / 2;
|
|
761
|
+
const pA = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
|
|
762
|
+
const pB = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
|
|
763
|
+
const span = tB - tA;
|
|
764
|
+
const p25 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.25);
|
|
765
|
+
const p50 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tMid);
|
|
766
|
+
const p75 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.75);
|
|
767
|
+
const dev = Math.max(
|
|
768
|
+
perpDist(p25, pA, pB),
|
|
769
|
+
perpDist(p50, pA, pB),
|
|
770
|
+
perpDist(p75, pA, pB)
|
|
771
|
+
);
|
|
772
|
+
let rotOk = true;
|
|
773
|
+
if (autoOrient) {
|
|
774
|
+
const tanA = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
|
|
775
|
+
const tanB = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
|
|
776
|
+
const angA = Math.atan2(tanA[1], tanA[0]) * 180 / Math.PI;
|
|
777
|
+
const angB = Math.atan2(tanB[1], tanB[0]) * 180 / Math.PI;
|
|
778
|
+
let delta = Math.abs(angA - angB);
|
|
779
|
+
if (delta > 180) delta = 360 - delta;
|
|
780
|
+
if (delta > rotationTol) rotOk = false;
|
|
781
|
+
}
|
|
782
|
+
if (dev <= flatnessTol && rotOk || budget.remaining <= 0 || span < 1e-6) {
|
|
783
|
+
out.push(tB);
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
budget.remaining -= 1;
|
|
787
|
+
bisect(tA, tMid, out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
788
|
+
bisect(tMid, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
789
|
+
}
|
|
790
|
+
function perpDist(q, pA, pB) {
|
|
791
|
+
const dx = pB[0] - pA[0];
|
|
792
|
+
const dy = pB[1] - pA[1];
|
|
793
|
+
const len2 = dx * dx + dy * dy;
|
|
794
|
+
if (len2 < 1e-20) {
|
|
795
|
+
const qdx = q[0] - pA[0];
|
|
796
|
+
const qdy = q[1] - pA[1];
|
|
797
|
+
return Math.sqrt(qdx * qdx + qdy * qdy);
|
|
798
|
+
}
|
|
799
|
+
const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
|
|
800
|
+
return Math.abs(cross) / Math.sqrt(len2);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// ../svg-animator-core/src/PxDefinitions.ts
|
|
804
|
+
var LOOP_JUMP_SHIFT_MS = 10;
|
|
805
|
+
function deepEqualValue(a, b) {
|
|
806
|
+
if (a === b) return true;
|
|
807
|
+
if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
|
|
808
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
809
|
+
const ka = Object.keys(a);
|
|
810
|
+
const kb = Object.keys(b);
|
|
811
|
+
if (ka.length !== kb.length) return false;
|
|
812
|
+
return ka.every((k) => deepEqualValue(a[k], b[k]));
|
|
813
|
+
}
|
|
814
|
+
function parsePathCommands(d) {
|
|
815
|
+
const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
|
|
816
|
+
const commands = [];
|
|
817
|
+
let currentCommand = null;
|
|
818
|
+
for (const token of tokens) {
|
|
819
|
+
if (/[MLCZmlcz]/.test(token)) {
|
|
820
|
+
currentCommand = { type: token, values: [] };
|
|
821
|
+
commands.push(currentCommand);
|
|
822
|
+
} else if (currentCommand) {
|
|
823
|
+
const value = +token;
|
|
824
|
+
currentCommand.values.push(Number.isNaN(value) ? 0 : value);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
return commands;
|
|
828
|
+
}
|
|
829
|
+
function parseSvgPathToBezier(d) {
|
|
830
|
+
const res = [];
|
|
831
|
+
let currentPath;
|
|
832
|
+
const commands = parsePathCommands(d);
|
|
833
|
+
for (const command of commands) {
|
|
834
|
+
const type = command.type;
|
|
835
|
+
const values = command.values;
|
|
836
|
+
if (type === "M" || type === "m") {
|
|
837
|
+
const x = values[0] || 0;
|
|
838
|
+
const y = values[1] || 0;
|
|
839
|
+
currentPath = {
|
|
840
|
+
v: [[x, y]],
|
|
841
|
+
i: [[x, y]],
|
|
842
|
+
o: [[x, y]],
|
|
843
|
+
c: false
|
|
844
|
+
};
|
|
845
|
+
res.push(currentPath);
|
|
846
|
+
continue;
|
|
847
|
+
}
|
|
848
|
+
if (!currentPath) {
|
|
849
|
+
currentPath = {
|
|
850
|
+
v: [[0, 0]],
|
|
851
|
+
i: [[0, 0]],
|
|
852
|
+
o: [[0, 0]],
|
|
853
|
+
c: false
|
|
854
|
+
};
|
|
855
|
+
res.push(currentPath);
|
|
856
|
+
}
|
|
857
|
+
if (type === "L") {
|
|
858
|
+
const x = values[0] || 0;
|
|
859
|
+
const y = values[1] || 0;
|
|
860
|
+
currentPath.v.push([x, y]);
|
|
861
|
+
currentPath.i.push([x, y]);
|
|
862
|
+
currentPath.o.push([x, y]);
|
|
863
|
+
} else if (type === "C") {
|
|
864
|
+
const outX = values[0] || 0;
|
|
865
|
+
const outY = values[1] || 0;
|
|
866
|
+
const inX2 = values[2] || 0;
|
|
867
|
+
const inY2 = values[3] || 0;
|
|
868
|
+
const x2 = values[4] || 0;
|
|
869
|
+
const y2 = values[5] || 0;
|
|
870
|
+
currentPath.o[currentPath.o.length - 1] = [outX, outY];
|
|
871
|
+
currentPath.v.push([x2, y2]);
|
|
872
|
+
currentPath.i.push([inX2, inY2]);
|
|
873
|
+
currentPath.o.push([x2, y2]);
|
|
874
|
+
} else if (type === "Z" || type === "z") {
|
|
875
|
+
currentPath.c = true;
|
|
876
|
+
} else {
|
|
877
|
+
console.warn('Unsupported path command "' + type + '"');
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
return res;
|
|
881
|
+
}
|
|
882
|
+
function extractPathData(str) {
|
|
883
|
+
if (str.startsWith("path(") && str.endsWith(")")) {
|
|
884
|
+
return str.slice(5, -1);
|
|
885
|
+
}
|
|
886
|
+
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str)) {
|
|
887
|
+
return str;
|
|
888
|
+
}
|
|
889
|
+
return void 0;
|
|
890
|
+
}
|
|
891
|
+
function isPathString(value) {
|
|
892
|
+
return typeof value === "string" && extractPathData(value) !== void 0;
|
|
893
|
+
}
|
|
894
|
+
function normalizePathValue(value) {
|
|
895
|
+
if (value && typeof value === "object" && typeof value.path === "string") {
|
|
896
|
+
const d = extractPathData(value.path);
|
|
897
|
+
return d ? { paths: parseSvgPathToBezier(d) } : value;
|
|
898
|
+
}
|
|
899
|
+
if (value && typeof value === "object" && "paths" in value) {
|
|
900
|
+
const pathsArray = value.paths;
|
|
901
|
+
if (Array.isArray(pathsArray) && pathsArray.length > 0) {
|
|
902
|
+
if (isPathString(pathsArray[0])) {
|
|
903
|
+
const paths = [];
|
|
904
|
+
for (const pathStr of pathsArray) {
|
|
905
|
+
const d = extractPathData(pathStr);
|
|
906
|
+
if (d) {
|
|
907
|
+
paths.push(...parseSvgPathToBezier(d));
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
return { paths };
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
return value;
|
|
914
|
+
}
|
|
915
|
+
if (Array.isArray(value)) {
|
|
916
|
+
if (value.length > 0 && isPathString(value[0])) {
|
|
917
|
+
const paths = [];
|
|
918
|
+
for (const pathStr of value) {
|
|
919
|
+
const d = extractPathData(pathStr);
|
|
920
|
+
if (d) {
|
|
921
|
+
paths.push(...parseSvgPathToBezier(d));
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
return { paths };
|
|
925
|
+
}
|
|
926
|
+
return { paths: value };
|
|
927
|
+
}
|
|
928
|
+
if (isPathString(value)) {
|
|
929
|
+
const d = extractPathData(value);
|
|
930
|
+
return { paths: parseSvgPathToBezier(d) };
|
|
931
|
+
}
|
|
932
|
+
return value;
|
|
933
|
+
}
|
|
934
|
+
function resolveEasing(easing, defs) {
|
|
935
|
+
var _a;
|
|
936
|
+
if (!easing) return void 0;
|
|
937
|
+
if (Array.isArray(easing)) {
|
|
938
|
+
return easing;
|
|
939
|
+
}
|
|
940
|
+
if ((_a = defs == null ? void 0 : defs.easings) == null ? void 0 : _a[easing]) {
|
|
941
|
+
return defs.easings[easing];
|
|
942
|
+
}
|
|
943
|
+
console.warn("Unknown easing name: " + easing);
|
|
944
|
+
return void 0;
|
|
945
|
+
}
|
|
946
|
+
function resolveAnimation(animRef, defs) {
|
|
947
|
+
var _a;
|
|
948
|
+
if (typeof animRef === "string") {
|
|
949
|
+
const resolved = (_a = defs == null ? void 0 : defs.animations) == null ? void 0 : _a[animRef];
|
|
950
|
+
if (!resolved) {
|
|
951
|
+
console.warn("Unknown animation name: " + animRef);
|
|
952
|
+
}
|
|
953
|
+
return resolved;
|
|
954
|
+
}
|
|
955
|
+
return animRef;
|
|
956
|
+
}
|
|
957
|
+
function resolveElementAnimation(animate, defs) {
|
|
958
|
+
if (!animate) return [];
|
|
959
|
+
const results = [];
|
|
960
|
+
if (typeof animate === "string") {
|
|
961
|
+
const resolved = resolveAnimation(animate, defs);
|
|
962
|
+
if (resolved) results.push(resolved);
|
|
963
|
+
} else if (Array.isArray(animate)) {
|
|
964
|
+
for (const item of animate) {
|
|
965
|
+
const resolved = resolveAnimation(item, defs);
|
|
966
|
+
if (resolved) results.push(resolved);
|
|
967
|
+
}
|
|
968
|
+
} else {
|
|
969
|
+
results.push(animate);
|
|
970
|
+
}
|
|
971
|
+
return results;
|
|
972
|
+
}
|
|
973
|
+
function interpolateValue(propName, a, b, t) {
|
|
974
|
+
var _a, _b;
|
|
975
|
+
if (propName === "d") {
|
|
976
|
+
const aPaths = (_a = a == null ? void 0 : a.paths) != null ? _a : Array.isArray(a) ? a : [];
|
|
977
|
+
const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
|
|
978
|
+
return { paths: interpolateBeziers(aPaths, bPaths, t) };
|
|
979
|
+
}
|
|
980
|
+
if (COLOUR_ATTR_NAMES.has(propName)) {
|
|
981
|
+
return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
|
|
982
|
+
}
|
|
983
|
+
if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
|
|
984
|
+
return interpolateTransformParts(a, b, t);
|
|
985
|
+
}
|
|
986
|
+
if (propName === "rotate" && typeof a === "number" && typeof b === "number") {
|
|
987
|
+
return interpolateNum(a, b, t);
|
|
988
|
+
}
|
|
989
|
+
if (TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
|
|
990
|
+
return interpolateVec(a || [], b || [], t);
|
|
991
|
+
}
|
|
992
|
+
return interpolateNum(+(a || 0), +(b || 0), t);
|
|
993
|
+
}
|
|
994
|
+
function interpolateTransformParts(a, b, t) {
|
|
995
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(a != null ? a : {}), ...Object.keys(b != null ? b : {})]);
|
|
996
|
+
const out = {};
|
|
997
|
+
for (const k of keys) {
|
|
998
|
+
const av = a == null ? void 0 : a[k];
|
|
999
|
+
const bv = b == null ? void 0 : b[k];
|
|
1000
|
+
if (k === "rotate" || k === "skew") {
|
|
1001
|
+
out[k] = interpolateNum(+(av != null ? av : 0), +(bv != null ? bv : 0), t);
|
|
1002
|
+
} else if (k === "translate" || k === "scale" || k === "origin") {
|
|
1003
|
+
const fallback = k === "scale" ? [1, 1] : [0, 0];
|
|
1004
|
+
out[k] = interpolateVec(av || fallback, bv || fallback, t);
|
|
1005
|
+
} else {
|
|
1006
|
+
out[k] = bv != null ? bv : av;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
return out;
|
|
1010
|
+
}
|
|
1011
|
+
function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
1012
|
+
var _a, _b, _c, _d, _e;
|
|
1013
|
+
const totalIntervals = keyframes.length - 1;
|
|
1014
|
+
const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
|
|
1015
|
+
let segKfs;
|
|
1016
|
+
if (loop.extend === PxLoopExtend.before) {
|
|
1017
|
+
segKfs = keyframes.slice(0, segCount + 1);
|
|
1018
|
+
} else {
|
|
1019
|
+
segKfs = keyframes.slice(totalIntervals - segCount);
|
|
1020
|
+
}
|
|
1021
|
+
const firstT = (_b = keyframes[0].t) != null ? _b : 0;
|
|
1022
|
+
const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
|
|
1023
|
+
let fillStart, fillEnd;
|
|
1024
|
+
if (loop.extend === PxLoopExtend.before) {
|
|
1025
|
+
fillStart = 0;
|
|
1026
|
+
fillEnd = firstT;
|
|
1027
|
+
} else {
|
|
1028
|
+
fillStart = lastT;
|
|
1029
|
+
fillEnd = duration;
|
|
1030
|
+
}
|
|
1031
|
+
const fillDuration = fillEnd - fillStart;
|
|
1032
|
+
if (fillDuration <= 0) return keyframes;
|
|
1033
|
+
const segStartT = (_d = segKfs[0].t) != null ? _d : 0;
|
|
1034
|
+
const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
|
|
1035
|
+
const segDuration = segEndT - segStartT;
|
|
1036
|
+
if (segDuration <= 0) return keyframes;
|
|
1037
|
+
const template = segKfs.map((kf) => {
|
|
1038
|
+
var _a2, _b2;
|
|
1039
|
+
return {
|
|
1040
|
+
relT: (kf.t - segStartT) / segDuration,
|
|
1041
|
+
v: kf.v,
|
|
1042
|
+
e: kf.e,
|
|
1043
|
+
tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
|
|
1044
|
+
tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
|
|
1045
|
+
};
|
|
1046
|
+
});
|
|
1047
|
+
const fullReps = Math.floor(fillDuration / segDuration);
|
|
1048
|
+
const remainder = fillDuration - fullReps * segDuration;
|
|
1049
|
+
const partialFraction = remainder / segDuration;
|
|
1050
|
+
const looped = [];
|
|
1051
|
+
const separateBoundary = loop.extend !== PxLoopExtend.before;
|
|
1052
|
+
const originalTerminalKf = keyframes[keyframes.length - 1];
|
|
1053
|
+
function appendRep(repStart, isReversed, partial) {
|
|
1054
|
+
var _a2;
|
|
1055
|
+
let entries;
|
|
1056
|
+
if (isReversed) {
|
|
1057
|
+
entries = [];
|
|
1058
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
1059
|
+
entries.push({
|
|
1060
|
+
relT: 1 - template[i].relT,
|
|
1061
|
+
v: template[i].v,
|
|
1062
|
+
// Easing for reversed transition: use reversed easing from the forward "from" keyframe
|
|
1063
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
1064
|
+
// Reversed traversal swaps each vertex's in/out spatial tangents
|
|
1065
|
+
// (geometry is identical, walked backwards), so curvature and
|
|
1066
|
+
// auto-orientation survive the reversed rep.
|
|
1067
|
+
tangentIn: template[i].tangentOut,
|
|
1068
|
+
tangentOut: template[i].tangentIn
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
} else {
|
|
1072
|
+
entries = template;
|
|
1073
|
+
}
|
|
1074
|
+
const cutRelT = partial !== void 0 ? partial : 1;
|
|
1075
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1076
|
+
const entry = entries[i];
|
|
1077
|
+
if (entry.relT > cutRelT + 1e-9) {
|
|
1078
|
+
const prev = entries[i - 1];
|
|
1079
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
1080
|
+
const localFrac = (cutRelT - prev.relT) / intervalSpan;
|
|
1081
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
1082
|
+
const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
1083
|
+
const { left: leftEasing } = splitEasing(prev.e, localFrac);
|
|
1084
|
+
if (looped.length > 0 && prev.relT <= cutRelT) {
|
|
1085
|
+
looped[looped.length - 1].e = leftEasing;
|
|
1086
|
+
}
|
|
1087
|
+
looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
|
|
1091
|
+
const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
|
|
1092
|
+
if (isBoundary) {
|
|
1093
|
+
if (deepEqualValue(prevKf.v, entry.v)) continue;
|
|
1094
|
+
if (looped.length > 0) {
|
|
1095
|
+
delete prevKf.tangentIn;
|
|
1096
|
+
delete prevKf.tangentOut;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
const pushed = {
|
|
1100
|
+
t: repStart + entry.relT * segDuration + (isBoundary ? LOOP_JUMP_SHIFT_MS : 0),
|
|
1101
|
+
v: entry.v,
|
|
1102
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
1103
|
+
};
|
|
1104
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
1105
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
1106
|
+
looped.push(pushed);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
function appendRepTail(repStart, isReversed, tailFraction) {
|
|
1110
|
+
let entries;
|
|
1111
|
+
if (isReversed) {
|
|
1112
|
+
entries = [];
|
|
1113
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
1114
|
+
entries.push({
|
|
1115
|
+
relT: 1 - template[i].relT,
|
|
1116
|
+
v: template[i].v,
|
|
1117
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
1118
|
+
tangentIn: template[i].tangentOut,
|
|
1119
|
+
tangentOut: template[i].tangentIn
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
} else {
|
|
1123
|
+
entries = template;
|
|
1124
|
+
}
|
|
1125
|
+
const startRelT = 1 - tailFraction;
|
|
1126
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1127
|
+
const entry = entries[i];
|
|
1128
|
+
if (entry.relT < startRelT - 1e-9) continue;
|
|
1129
|
+
const prev = entries[i - 1];
|
|
1130
|
+
if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {
|
|
1131
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
1132
|
+
const localFrac = (startRelT - prev.relT) / intervalSpan;
|
|
1133
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
1134
|
+
const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
1135
|
+
const { right: rightEasing } = splitEasing(prev.e, localFrac);
|
|
1136
|
+
looped.push({ t: repStart, v: startValue, e: rightEasing });
|
|
1137
|
+
}
|
|
1138
|
+
const pushed = {
|
|
1139
|
+
t: repStart + (entry.relT - startRelT) * segDuration,
|
|
1140
|
+
v: entry.v,
|
|
1141
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
1142
|
+
};
|
|
1143
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
1144
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
1145
|
+
looped.push(pushed);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
if (loop.extend === PxLoopExtend.before) {
|
|
1149
|
+
if (partialFraction > 1e-9) {
|
|
1150
|
+
const isReversed = !!loop.alternate && fullReps % 2 === 0;
|
|
1151
|
+
appendRepTail(fillStart, isReversed, partialFraction);
|
|
1152
|
+
}
|
|
1153
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
1154
|
+
const distFromBoundary = fullReps - 1 - rep;
|
|
1155
|
+
const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
|
|
1156
|
+
const repStart = fillStart + remainder + rep * segDuration;
|
|
1157
|
+
appendRep(repStart, isReversed);
|
|
1158
|
+
}
|
|
1159
|
+
} else {
|
|
1160
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
1161
|
+
const isReversed = !!loop.alternate && rep % 2 === 0;
|
|
1162
|
+
const repStart = fillStart + rep * segDuration;
|
|
1163
|
+
appendRep(repStart, isReversed);
|
|
1164
|
+
}
|
|
1165
|
+
if (partialFraction > 1e-9) {
|
|
1166
|
+
const isReversed = !!loop.alternate && fullReps % 2 === 0;
|
|
1167
|
+
const repStart = fillStart + fullReps * segDuration;
|
|
1168
|
+
appendRep(repStart, isReversed, partialFraction);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
if (loop.extend === PxLoopExtend.before) {
|
|
1172
|
+
return [...looped, ...keyframes];
|
|
1173
|
+
} else {
|
|
1174
|
+
return [...keyframes, ...looped];
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
function normalizeKeyframes(propName, propAnim, duration, defs) {
|
|
1178
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1179
|
+
const keyframes = propAnim.keyframes || propAnim.kfs || [];
|
|
1180
|
+
const normalized = [];
|
|
1181
|
+
for (const kf of keyframes) {
|
|
1182
|
+
const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
|
|
1183
|
+
let value = (_c = kf.value) != null ? _c : kf.v;
|
|
1184
|
+
const easing = (_d = kf.easing) != null ? _d : kf.e;
|
|
1185
|
+
if (propName === "d") {
|
|
1186
|
+
value = normalizePathValue(value);
|
|
1187
|
+
}
|
|
1188
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
1189
|
+
if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
|
|
1190
|
+
value = (_e = parseColor(value)) != null ? _e : value;
|
|
1191
|
+
}
|
|
1192
|
+
const normKf = {
|
|
1193
|
+
t: timePct,
|
|
1194
|
+
v: value,
|
|
1195
|
+
e: resolveEasing(easing, defs)
|
|
1196
|
+
};
|
|
1197
|
+
const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
|
|
1198
|
+
const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
|
|
1199
|
+
if (tIn) normKf.tangentIn = tIn;
|
|
1200
|
+
if (tOut) normKf.tangentOut = tOut;
|
|
1201
|
+
normalized.push(normKf);
|
|
1202
|
+
}
|
|
1203
|
+
normalized.sort((a, b) => {
|
|
1204
|
+
var _a2, _b2;
|
|
1205
|
+
return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
|
|
1206
|
+
});
|
|
1207
|
+
const loopRaw = propAnim.loop;
|
|
1208
|
+
const loop = loopRaw === true ? {} : loopRaw || void 0;
|
|
1209
|
+
if (loop && normalized.length >= 2) {
|
|
1210
|
+
return expandLoopKeyframes(propName, normalized, loop, duration);
|
|
1211
|
+
}
|
|
1212
|
+
return normalized;
|
|
1213
|
+
}
|
|
1214
|
+
function mergeAnimationDefinitions(animations) {
|
|
1215
|
+
const merged = {};
|
|
1216
|
+
for (const anim of animations) {
|
|
1217
|
+
for (const [prop, propAnim] of Object.entries(anim)) {
|
|
1218
|
+
merged[prop] = propAnim;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
return merged;
|
|
1222
|
+
}
|
|
1223
|
+
var _elementIdCounter = 0;
|
|
1224
|
+
function generateElementId() {
|
|
1225
|
+
return "_px_el_" + ++_elementIdCounter;
|
|
1226
|
+
}
|
|
1227
|
+
function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
|
|
1228
|
+
const normalized = {};
|
|
1229
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
1230
|
+
const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
|
|
1231
|
+
if (normalizedKfs.length > 0) {
|
|
1232
|
+
const out = { kfs: normalizedKfs };
|
|
1233
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
1234
|
+
if (propAnim.loop !== void 0) out.loop = propAnim.loop;
|
|
1235
|
+
normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
return normalized;
|
|
1239
|
+
}
|
|
1240
|
+
function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
|
|
1241
|
+
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
1242
|
+
const defs = getDefs(doc);
|
|
1243
|
+
const duration = animatorConfig.duration || 1e3;
|
|
1244
|
+
const bindings = [];
|
|
1245
|
+
const processAnimation = (id, animate) => {
|
|
1246
|
+
if (!animate) return null;
|
|
1247
|
+
const animDefs = resolveElementAnimation(animate, defs);
|
|
1248
|
+
if (animDefs.length === 0) return null;
|
|
1249
|
+
const merged = mergeAnimationDefinitions(animDefs);
|
|
1250
|
+
const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
|
|
1251
|
+
if (Object.keys(normalizedAnim).length === 0) return null;
|
|
1252
|
+
return {
|
|
1253
|
+
id,
|
|
1254
|
+
animate: normalizedAnim
|
|
1255
|
+
};
|
|
1256
|
+
};
|
|
1257
|
+
const docBindings = getBindings(doc);
|
|
1258
|
+
if (docBindings) {
|
|
1259
|
+
for (const binding of docBindings) {
|
|
1260
|
+
const normalized = processAnimation(binding.id, binding.animate);
|
|
1261
|
+
if (normalized) bindings.push(normalized);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
const processNode = (node) => {
|
|
1265
|
+
const inlineAnim = node.animate;
|
|
1266
|
+
if (inlineAnim && Object.keys(inlineAnim).length > 0) {
|
|
1267
|
+
const nodeId = node.id || generateElementId();
|
|
1268
|
+
node.id = nodeId;
|
|
1269
|
+
const normalized = processAnimation(nodeId, inlineAnim);
|
|
1270
|
+
if (normalized) bindings.push(normalized);
|
|
1271
|
+
}
|
|
1272
|
+
if (node.children) {
|
|
1273
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
1274
|
+
processNode(node.children[i]);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
if (doc.children) {
|
|
1279
|
+
for (let i = 0; i < doc.children.length; i++) {
|
|
1280
|
+
processNode(doc.children[i]);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
return bindings;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// src/PxAnimatorTriggers.ts
|
|
1287
|
+
function setupAnimationTriggers(api, config) {
|
|
1288
|
+
const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
|
|
1289
|
+
const root = api.getRootElement();
|
|
1290
|
+
if (!root) {
|
|
1291
|
+
console.warn("setupAnimationTriggers: No root element found for animation.");
|
|
1292
|
+
return api;
|
|
1293
|
+
}
|
|
1294
|
+
let reversed = false;
|
|
1295
|
+
const start = () => {
|
|
1296
|
+
if (reversed) {
|
|
1297
|
+
reversed = false;
|
|
1298
|
+
api.setPlaybackRate(1);
|
|
1299
|
+
}
|
|
1300
|
+
api.play();
|
|
1301
|
+
};
|
|
1302
|
+
const handleEndAction = () => {
|
|
1303
|
+
switch (outAction) {
|
|
1304
|
+
case "pause":
|
|
1305
|
+
api.pause();
|
|
1306
|
+
break;
|
|
1307
|
+
case "reset":
|
|
1308
|
+
api.cancel();
|
|
1309
|
+
break;
|
|
1310
|
+
case "reverse":
|
|
1311
|
+
reversed = true;
|
|
1312
|
+
api.setPlaybackRate(-1);
|
|
1313
|
+
api.play();
|
|
1314
|
+
break;
|
|
1315
|
+
case "continue":
|
|
1316
|
+
default:
|
|
1317
|
+
break;
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
switch (startOn) {
|
|
1321
|
+
case "load": {
|
|
1322
|
+
const startHandler = () => start();
|
|
1323
|
+
if (document.readyState === "complete") {
|
|
1324
|
+
startHandler();
|
|
1325
|
+
} else {
|
|
1326
|
+
window.addEventListener("load", startHandler, { once: true });
|
|
1327
|
+
}
|
|
1328
|
+
break;
|
|
1329
|
+
}
|
|
1330
|
+
case "mouseOver": {
|
|
1331
|
+
let enteredOnce = false;
|
|
1332
|
+
const mouseOverHandler = () => {
|
|
1333
|
+
enteredOnce = true;
|
|
1334
|
+
start();
|
|
1335
|
+
};
|
|
1336
|
+
const mouseOutHandler = () => {
|
|
1337
|
+
if (enteredOnce) handleEndAction();
|
|
1338
|
+
};
|
|
1339
|
+
root.addEventListener("mouseenter", mouseOverHandler);
|
|
1340
|
+
root.addEventListener("mouseleave", mouseOutHandler);
|
|
1341
|
+
break;
|
|
1342
|
+
}
|
|
1343
|
+
case "click": {
|
|
1344
|
+
const clickHandler = () => {
|
|
1345
|
+
if (api.isPlaying()) {
|
|
1346
|
+
handleEndAction();
|
|
1347
|
+
} else {
|
|
1348
|
+
start();
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
root.addEventListener("click", clickHandler);
|
|
1352
|
+
break;
|
|
1353
|
+
}
|
|
1354
|
+
case "scrollIntoView": {
|
|
1355
|
+
const effectiveRatio = (entry) => {
|
|
1356
|
+
var _a, _b;
|
|
1357
|
+
const target = entry.boundingClientRect;
|
|
1358
|
+
const visible = entry.intersectionRect;
|
|
1359
|
+
if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
|
|
1360
|
+
const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
|
|
1361
|
+
const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
|
|
1362
|
+
const viewport = Math.min(live, declared);
|
|
1363
|
+
const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
|
|
1364
|
+
return denom > 0 ? visible.height / denom : entry.intersectionRatio;
|
|
1365
|
+
};
|
|
1366
|
+
const thresholdSteps = Array.from({ length: 21 }, (_, i) => i / 20);
|
|
1367
|
+
let wasIntersecting = false;
|
|
1368
|
+
const observer = new IntersectionObserver(
|
|
1369
|
+
(entries) => {
|
|
1370
|
+
entries.forEach((entry) => {
|
|
1371
|
+
if (entry.isIntersecting && effectiveRatio(entry) >= scrollIntoViewThreshold) {
|
|
1372
|
+
wasIntersecting = true;
|
|
1373
|
+
start();
|
|
1374
|
+
} else if (wasIntersecting) {
|
|
1375
|
+
wasIntersecting = false;
|
|
1376
|
+
handleEndAction();
|
|
1377
|
+
}
|
|
1378
|
+
});
|
|
1379
|
+
},
|
|
1380
|
+
{ threshold: thresholdSteps }
|
|
1381
|
+
);
|
|
1382
|
+
observer.observe(root);
|
|
1383
|
+
break;
|
|
1384
|
+
}
|
|
1385
|
+
case "programmatic":
|
|
1386
|
+
break;
|
|
1387
|
+
}
|
|
1388
|
+
return api;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// src/PxAnimatorFrameLoop.ts
|
|
1392
|
+
function getSelector(id) {
|
|
1393
|
+
return "#" + id;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
// src/PxAnimatorWebApi.ts
|
|
1397
|
+
function createCssKf(kf, t, propName, unsupportedSet) {
|
|
1398
|
+
var _a, _b;
|
|
1399
|
+
let value = (_a = kf.v) != null ? _a : kf.value;
|
|
1400
|
+
const e = (_b = kf.e) != null ? _b : kf.easing;
|
|
1401
|
+
const cssKf = {
|
|
1402
|
+
offset: t,
|
|
1403
|
+
easing: e && Array.isArray(e) ? "cubic-bezier(" + e.join(",") + ")" : void 0
|
|
1404
|
+
};
|
|
1405
|
+
let cssValue;
|
|
1406
|
+
let cssKey = propName;
|
|
1407
|
+
if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {
|
|
1408
|
+
cssValue = toRGBA(value);
|
|
1409
|
+
} else if (propName === "transform" && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
1410
|
+
cssValue = composeTransformParts(value, { withUnits: true });
|
|
1411
|
+
cssKey = "transform";
|
|
1412
|
+
} else if (TRANSFORM_FN_NAMES.has(propName)) {
|
|
1413
|
+
if (Array.isArray(value)) {
|
|
1414
|
+
if (propName === "translate") value = value.map((v) => v + "px");
|
|
1415
|
+
value = value.join(",");
|
|
1416
|
+
}
|
|
1417
|
+
if (propName === "rotate") value = value + "deg";
|
|
1418
|
+
cssValue = propName + "(" + value + ")";
|
|
1419
|
+
cssKey = "transform";
|
|
1420
|
+
} else if (propName === "d") {
|
|
1421
|
+
const paths = value && typeof value === "object" && Array.isArray(value.paths) ? value.paths : [];
|
|
1422
|
+
cssValue = 'path("' + paths.map((bz) => bezierToSvgPath(bz, true)).join("") + '")';
|
|
1423
|
+
} else {
|
|
1424
|
+
cssValue = "" + value;
|
|
1425
|
+
}
|
|
1426
|
+
if (!CSS.supports(camelCaseToKebabWordIfNeeded(cssKey), cssValue)) unsupportedSet.add(cssKey);
|
|
1427
|
+
cssKey = kebabToCamelCaseWord(cssKey);
|
|
1428
|
+
cssKf[cssKey] = cssValue;
|
|
1429
|
+
return cssKf;
|
|
1430
|
+
}
|
|
1431
|
+
function clipKeyframesToDuration(propName, keyframes, duration) {
|
|
1432
|
+
var _a, _b, _c, _d, _e;
|
|
1433
|
+
const result = [];
|
|
1434
|
+
for (let i = 0; i < keyframes.length; i++) {
|
|
1435
|
+
const kf = keyframes[i];
|
|
1436
|
+
const t = (_a = kf.t) != null ? _a : 0;
|
|
1437
|
+
if (t < 0) {
|
|
1438
|
+
const next = keyframes[i + 1];
|
|
1439
|
+
if (next && ((_b = next.t) != null ? _b : 0) >= 0) {
|
|
1440
|
+
const nextT = (_c = next.t) != null ? _c : 0;
|
|
1441
|
+
const localFrac = (0 - t) / (nextT - t);
|
|
1442
|
+
const easedFrac = kf.e ? cubicBezier(kf.e)(localFrac) : localFrac;
|
|
1443
|
+
const { right: rightEasing } = splitEasing(kf.e, localFrac);
|
|
1444
|
+
result.push({ t: 0, v: interpolateValue(propName, kf.v, next.v, easedFrac), e: rightEasing });
|
|
1445
|
+
}
|
|
1446
|
+
continue;
|
|
1447
|
+
}
|
|
1448
|
+
if (t > duration) {
|
|
1449
|
+
const prev = keyframes[i - 1];
|
|
1450
|
+
if (prev && ((_d = prev.t) != null ? _d : 0) <= duration) {
|
|
1451
|
+
const prevT = (_e = prev.t) != null ? _e : 0;
|
|
1452
|
+
const localFrac = (duration - prevT) / (t - prevT);
|
|
1453
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
1454
|
+
const { left: leftEasing } = splitEasing(prev.e, localFrac);
|
|
1455
|
+
if (result.length > 0) result[result.length - 1] = __spreadProps(__spreadValues({}, result[result.length - 1]), { e: leftEasing });
|
|
1456
|
+
result.push({ t: duration, v: interpolateValue(propName, prev.v, kf.v, easedFrac), e: void 0 });
|
|
1457
|
+
}
|
|
1458
|
+
break;
|
|
1459
|
+
}
|
|
1460
|
+
result.push(kf);
|
|
1461
|
+
}
|
|
1462
|
+
return result;
|
|
1463
|
+
}
|
|
1464
|
+
function convertToWebApiKeyframes(animDef, unsupportedSet, config) {
|
|
1465
|
+
var _a;
|
|
1466
|
+
const result = /* @__PURE__ */ new Map();
|
|
1467
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
1468
|
+
const duration = config.duration || 1;
|
|
1469
|
+
const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.kfs || propAnim.keyframes || [], duration);
|
|
1470
|
+
const cssKeyframes = [];
|
|
1471
|
+
for (let i = 0; i < clippedKeyframes.length; i++) {
|
|
1472
|
+
const kf = clippedKeyframes[i];
|
|
1473
|
+
const t = clamp(((_a = kf.t) != null ? _a : 0) / duration, 0, 1);
|
|
1474
|
+
const cssKf = createCssKf(kf, t, propName, unsupportedSet);
|
|
1475
|
+
if (i === 0 && (cssKf.offset || 0) > 0) {
|
|
1476
|
+
cssKeyframes.push(__spreadProps(__spreadValues({}, cssKf), { offset: 0 }));
|
|
1477
|
+
}
|
|
1478
|
+
cssKeyframes.push(cssKf);
|
|
1479
|
+
}
|
|
1480
|
+
if (cssKeyframes.length > 0 && (cssKeyframes[cssKeyframes.length - 1].offset || 0) < 1) {
|
|
1481
|
+
cssKeyframes.push(__spreadProps(__spreadValues({}, cssKeyframes[cssKeyframes.length - 1]), {
|
|
1482
|
+
offset: 1
|
|
1483
|
+
}));
|
|
1484
|
+
}
|
|
1485
|
+
if (cssKeyframes.length > 0) {
|
|
1486
|
+
result.set(propName, cssKeyframes);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
return result;
|
|
1490
|
+
}
|
|
1491
|
+
function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsupportedAttrs) {
|
|
1492
|
+
var _a;
|
|
1493
|
+
const config = getAnimatorConfig(doc) || {};
|
|
1494
|
+
if (!rootElement) {
|
|
1495
|
+
if (doc.id) {
|
|
1496
|
+
const rootSelector = getSelector(doc.id);
|
|
1497
|
+
rootElement = document.querySelector(rootSelector);
|
|
1498
|
+
if (!rootElement) console.warn("createFrameLoopAnimator: No root element found for selector: ", rootSelector);
|
|
1499
|
+
} else {
|
|
1500
|
+
console.warn("createFrameLoopAnimator: No root element provided");
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
|
|
1504
|
+
const animations = [];
|
|
1505
|
+
const _iterations = config.iterations;
|
|
1506
|
+
let iterations;
|
|
1507
|
+
if (typeof _iterations === "number") iterations = _iterations;
|
|
1508
|
+
if (_iterations === "infinite") iterations = Infinity;
|
|
1509
|
+
const unsupportedSet = /* @__PURE__ */ new Set();
|
|
1510
|
+
let finishNotified = false;
|
|
1511
|
+
let removeCalled = false;
|
|
1512
|
+
if (!(bindings == null ? void 0 : bindings.length)) {
|
|
1513
|
+
console.warn("createWebApiAnimator: No animation bindings defined");
|
|
1514
|
+
}
|
|
1515
|
+
for (const binding of bindings || []) {
|
|
1516
|
+
const animDef = binding.animate;
|
|
1517
|
+
if (!animDef || typeof animDef !== "object" || Array.isArray(animDef)) {
|
|
1518
|
+
console.warn("createWebApiAnimator: Empty or unresolved binding", binding);
|
|
1519
|
+
continue;
|
|
1520
|
+
}
|
|
1521
|
+
const selector = getSelector(binding.id);
|
|
1522
|
+
const elements = (rootElement == null ? void 0 : rootElement.querySelectorAll(selector)) || document.querySelectorAll(selector);
|
|
1523
|
+
if (elements.length === 0) {
|
|
1524
|
+
console.warn('createWebApiAnimator: No elements found for selector "' + selector + '"');
|
|
1525
|
+
}
|
|
1526
|
+
const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);
|
|
1527
|
+
const positiveDelay = config.delay && config.delay > 0 ? config.delay : void 0;
|
|
1528
|
+
let seekPosition;
|
|
1529
|
+
if (config.delay && config.delay < 0 && config.duration) {
|
|
1530
|
+
const rawSeek = -config.delay;
|
|
1531
|
+
seekPosition = iterations === Infinity ? rawSeek % config.duration : Math.min(rawSeek, config.duration * (iterations != null ? iterations : 1));
|
|
1532
|
+
}
|
|
1533
|
+
const effectOptions = {
|
|
1534
|
+
duration: config.duration,
|
|
1535
|
+
delay: positiveDelay,
|
|
1536
|
+
// Default to 'forwards' so elements hold their final state after the
|
|
1537
|
+
// animation ends — consistent with Lottie and other animation runtimes.
|
|
1538
|
+
// Without this, seeking to the last frame reverts elements to their
|
|
1539
|
+
// pre-animation state (the Web Animations API "after" phase with fill:'none').
|
|
1540
|
+
fill: (_a = config.fill) != null ? _a : "forwards",
|
|
1541
|
+
direction: config.direction,
|
|
1542
|
+
iterations
|
|
1543
|
+
};
|
|
1544
|
+
for (let i = 0; i < elements.length; i++) {
|
|
1545
|
+
const element = elements[i];
|
|
1546
|
+
for (const [, keyframes] of keyframesMap) {
|
|
1547
|
+
if (keyframes.length > 0) {
|
|
1548
|
+
try {
|
|
1549
|
+
const effect = new KeyframeEffect(element, keyframes, effectOptions);
|
|
1550
|
+
const anim = new Animation(effect, document.timeline);
|
|
1551
|
+
if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
|
|
1552
|
+
var _a2;
|
|
1553
|
+
if (finishNotified) return;
|
|
1554
|
+
finishNotified = true;
|
|
1555
|
+
(_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
|
|
1556
|
+
};
|
|
1557
|
+
if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
|
|
1558
|
+
var _a2;
|
|
1559
|
+
if (removeCalled) return;
|
|
1560
|
+
removeCalled = true;
|
|
1561
|
+
(_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
|
|
1562
|
+
};
|
|
1563
|
+
if (seekPosition !== void 0) {
|
|
1564
|
+
anim.currentTime = seekPosition;
|
|
1565
|
+
}
|
|
1566
|
+
animations.push(anim);
|
|
1567
|
+
} catch (e) {
|
|
1568
|
+
console.warn(e);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
if (!forceEvenIfHasUnsupportedAttrs && unsupportedSet.size) {
|
|
1575
|
+
console.warn("Unsupported CSS attrs: " + [...unsupportedSet].join(", "));
|
|
1576
|
+
return null;
|
|
1577
|
+
}
|
|
1578
|
+
const api = {
|
|
1579
|
+
"isReady": () => true,
|
|
1580
|
+
"getRootElement": () => rootElement || null,
|
|
1581
|
+
"isPlaying": () => {
|
|
1582
|
+
var _a2;
|
|
1583
|
+
return ((_a2 = animations[0]) == null ? void 0 : _a2.playState) === "running";
|
|
1584
|
+
},
|
|
1585
|
+
"play": () => {
|
|
1586
|
+
var _a2;
|
|
1587
|
+
finishNotified = false;
|
|
1588
|
+
animations.forEach((a) => a.play());
|
|
1589
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
|
|
1590
|
+
},
|
|
1591
|
+
"pause": () => {
|
|
1592
|
+
var _a2;
|
|
1593
|
+
animations.forEach((a) => a.pause());
|
|
1594
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
|
|
1595
|
+
},
|
|
1596
|
+
"cancel": () => {
|
|
1597
|
+
var _a2;
|
|
1598
|
+
finishNotified = false;
|
|
1599
|
+
animations.forEach((a) => a.cancel());
|
|
1600
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
|
|
1601
|
+
},
|
|
1602
|
+
"finish": () => {
|
|
1603
|
+
var _a2;
|
|
1604
|
+
for (const a of animations) {
|
|
1605
|
+
try {
|
|
1606
|
+
if (((_a2 = a.effect) == null ? void 0 : _a2.getTiming().iterations) === Infinity) {
|
|
1607
|
+
a.effect.updateTiming({ iterations: 1 });
|
|
1608
|
+
a.finish();
|
|
1609
|
+
a.effect.updateTiming({ iterations: Infinity });
|
|
1610
|
+
} else {
|
|
1611
|
+
a.finish();
|
|
1612
|
+
}
|
|
1613
|
+
} catch (e) {
|
|
1614
|
+
a.cancel();
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
},
|
|
1618
|
+
"setPlaybackRate": (rate) => {
|
|
1619
|
+
animations.forEach((a) => a.playbackRate = rate);
|
|
1620
|
+
return api;
|
|
1621
|
+
},
|
|
1622
|
+
"getCurrentTime": () => {
|
|
1623
|
+
var _a2, _b;
|
|
1624
|
+
const res = (_b = (_a2 = animations[0]) == null ? void 0 : _a2.currentTime) != null ? _b : null;
|
|
1625
|
+
return res !== null ? +res : null;
|
|
1626
|
+
},
|
|
1627
|
+
"setCurrentTime": (time) => {
|
|
1628
|
+
finishNotified = false;
|
|
1629
|
+
animations.forEach((a) => {
|
|
1630
|
+
a.currentTime = time;
|
|
1631
|
+
});
|
|
1632
|
+
},
|
|
1633
|
+
"destroy": () => {
|
|
1634
|
+
var _a2;
|
|
1635
|
+
api.cancel();
|
|
1636
|
+
animations.splice(0, animations.length);
|
|
1637
|
+
if (!removeCalled) {
|
|
1638
|
+
removeCalled = true;
|
|
1639
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
};
|
|
1643
|
+
if (config.trigger) {
|
|
1644
|
+
setupAnimationTriggers(api, config.trigger);
|
|
1645
|
+
}
|
|
1646
|
+
return api;
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
// src/PxAnimatorBind.ts
|
|
1650
|
+
function finaliseAnimator(animatorConfig, callbacks, make) {
|
|
1651
|
+
let apiRef;
|
|
1652
|
+
let effectiveCallbacks = callbacks;
|
|
1653
|
+
if (animatorConfig.resetOnFinish) {
|
|
1654
|
+
effectiveCallbacks = __spreadProps(__spreadValues({}, callbacks), {
|
|
1655
|
+
onFinish: () => {
|
|
1656
|
+
var _a;
|
|
1657
|
+
(_a = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a.call(callbacks);
|
|
1658
|
+
apiRef == null ? void 0 : apiRef.cancel();
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1662
|
+
const res = make(effectiveCallbacks);
|
|
1663
|
+
apiRef = res;
|
|
1664
|
+
if (animatorConfig.debugInstName) {
|
|
1665
|
+
window[animatorConfig.debugInstName] = res;
|
|
1666
|
+
}
|
|
1667
|
+
return res;
|
|
1668
|
+
}
|
|
1669
|
+
function requireData(options) {
|
|
1670
|
+
if (!(options == null ? void 0 : options.data)) throw new Error("createAnimator: `data` is required");
|
|
1671
|
+
return options.data;
|
|
1672
|
+
}
|
|
1673
|
+
function createPrerenderedWaapiAnimator(options) {
|
|
1674
|
+
const doc = requireData(options);
|
|
1675
|
+
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
1676
|
+
return finaliseAnimator(
|
|
1677
|
+
animatorConfig,
|
|
1678
|
+
options.callbacks,
|
|
1679
|
+
(cb) => createWebApiAnimator(doc, cb, null, true)
|
|
1680
|
+
);
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
// src/PxAnimatorKeys.ts
|
|
1684
|
+
var PX_ANIMATOR_DATA_KEY = "data";
|
|
1685
|
+
return __toCommonJS(index_prerendered_waapi_exports);
|
|
1686
|
+
})();
|
|
1687
|
+
//# sourceMappingURL=index.prerendered-waapi.umd.js.map
|