@pixodesk/svg-animator-web 1.0.19 → 1.0.20
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 +31 -14
- package/dist/index.cjs +363 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +285 -4
- package/dist/index.d.ts +285 -4
- package/dist/index.js +361 -65
- 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 +361 -65
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -984,6 +984,10 @@ var PxMaskedByEffectSchema = implementsInterface()(px.object({
|
|
|
984
984
|
maskUnits: px.string().optional(),
|
|
985
985
|
maskContentUnits: px.string().optional()
|
|
986
986
|
}));
|
|
987
|
+
var PxClipPathEffectSchema = implementsInterface()(px.object({
|
|
988
|
+
d: px.string().optional(),
|
|
989
|
+
animate: PxPropertyAnimationSchema.optional()
|
|
990
|
+
}));
|
|
987
991
|
var PxTrimPathEffectSchema = implementsInterface()(px.object({
|
|
988
992
|
offset: PxAnimatableNumberSchema.optional(),
|
|
989
993
|
range: PxAnimatableVec2Schema.optional(),
|
|
@@ -1051,6 +1055,7 @@ var PxEffectsSchema = implementsInterface()(px.object({
|
|
|
1051
1055
|
transformation: PxTransformationEffectSchema.optional(),
|
|
1052
1056
|
repeater: PxRepeaterEffectSchema.optional(),
|
|
1053
1057
|
maskedBy: PxMaskedByEffectSchema.optional(),
|
|
1058
|
+
clipPath: PxClipPathEffectSchema.optional(),
|
|
1054
1059
|
trimPath: PxTrimPathEffectSchema.optional(),
|
|
1055
1060
|
clone: PxCloneEffectSchema.optional(),
|
|
1056
1061
|
isCombinedShape: px.boolean().optional(),
|
|
@@ -1357,6 +1362,17 @@ function formatOffset(o) {
|
|
|
1357
1362
|
return pct + "%";
|
|
1358
1363
|
}
|
|
1359
1364
|
|
|
1365
|
+
// src/effects/clipPathEffect.ts
|
|
1366
|
+
function applyClipPathEffect(node, fx, ctx) {
|
|
1367
|
+
if (!fx || !fx.d && !fx.animate) return node;
|
|
1368
|
+
const clipId = genId(ctx, "clip");
|
|
1369
|
+
const pathChild = { type: "path", d: fx.d };
|
|
1370
|
+
if (fx.animate) pathChild.animate = { d: fx.animate };
|
|
1371
|
+
ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
|
|
1372
|
+
node.clipPath = "url(#" + clipId + ")";
|
|
1373
|
+
return node;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1360
1376
|
// src/effects/maskedByEffect.ts
|
|
1361
1377
|
function applyMaskedByEffect(node, fx, transformation, ctx) {
|
|
1362
1378
|
if (!fx) return node;
|
|
@@ -1799,6 +1815,9 @@ function synthesiseScale(raw, i) {
|
|
|
1799
1815
|
var RETIME_MATERIALISATION_MODE_INLINE_G = false;
|
|
1800
1816
|
function asRetime(r) {
|
|
1801
1817
|
var _a, _b;
|
|
1818
|
+
if (r.timeCrop) {
|
|
1819
|
+
console.warn("retime: `timeCrop` is not supported yet and will be ignored");
|
|
1820
|
+
}
|
|
1802
1821
|
return { start: (_a = r.start) != null ? _a : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
|
|
1803
1822
|
}
|
|
1804
1823
|
function concatRetime(child, parent) {
|
|
@@ -2217,6 +2236,8 @@ var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
|
|
|
2217
2236
|
// Filter
|
|
2218
2237
|
"filterUnits",
|
|
2219
2238
|
"primitiveUnits",
|
|
2239
|
+
"tableValues",
|
|
2240
|
+
// feFuncR/G/B/A transfer table (type="table")
|
|
2220
2241
|
"stdDeviation",
|
|
2221
2242
|
"baseFrequency",
|
|
2222
2243
|
"numOctaves",
|
|
@@ -2475,6 +2496,9 @@ function createPathSampler(d) {
|
|
|
2475
2496
|
totalLength,
|
|
2476
2497
|
closed,
|
|
2477
2498
|
sampleAtDistance(dist) {
|
|
2499
|
+
if (closed && totalLength > 0 && (dist < 0 || dist > totalLength)) {
|
|
2500
|
+
return sampleOn((dist % totalLength + totalLength) % totalLength);
|
|
2501
|
+
}
|
|
2478
2502
|
if (!closed && (dist < 0 || dist > totalLength)) {
|
|
2479
2503
|
const edge = dist < 0 ? 0 : totalLength;
|
|
2480
2504
|
const p = sampleOn(edge);
|
|
@@ -2731,6 +2755,19 @@ function soleFontOf(glyphs) {
|
|
|
2731
2755
|
const names = Object.keys(glyphs);
|
|
2732
2756
|
return names.length === 1 ? glyphs[names[0]] : void 0;
|
|
2733
2757
|
}
|
|
2758
|
+
var MISSING_GLYPH_ADVANCE_EM = 0.6;
|
|
2759
|
+
function missingGlyphBoxEm(advanceEm, ascentEm) {
|
|
2760
|
+
if (advanceEm <= 0 || ascentEm <= 0) return "";
|
|
2761
|
+
const inset = 0.08;
|
|
2762
|
+
const x0 = advanceEm * inset, x1 = advanceEm * (1 - inset);
|
|
2763
|
+
const y1 = -ascentEm * (1 - inset);
|
|
2764
|
+
const bw = x1 - x0, bh = -y1;
|
|
2765
|
+
const t = Math.max(1, Math.min(bw, bh) * 0.12);
|
|
2766
|
+
const outer = "M" + x0 + " 0L" + x1 + " 0L" + x1 + " " + y1 + "L" + x0 + " " + y1 + "Z";
|
|
2767
|
+
if (bw <= 2 * t || bh <= 2 * t) return outer;
|
|
2768
|
+
const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;
|
|
2769
|
+
return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
|
|
2770
|
+
}
|
|
2734
2771
|
function materialiseGlyphTextHorizontal(node, opts) {
|
|
2735
2772
|
var _a, _b, _c, _d;
|
|
2736
2773
|
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
@@ -2740,15 +2777,26 @@ function materialiseGlyphTextHorizontal(node, opts) {
|
|
|
2740
2777
|
const lines = [{ start: pen.x, end: pen.x }];
|
|
2741
2778
|
let line = 0;
|
|
2742
2779
|
const renderChars = (content, s) => {
|
|
2780
|
+
var _a2;
|
|
2743
2781
|
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2744
|
-
|
|
2745
|
-
const scale = s.fontSize /
|
|
2782
|
+
const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
|
|
2783
|
+
const scale = s.fontSize / upm;
|
|
2784
|
+
const ascentEm = (_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm;
|
|
2746
2785
|
const paint = paintOf(s);
|
|
2747
2786
|
for (let i = 0; i < content.length; i++) {
|
|
2748
2787
|
const ch = content.charAt(i);
|
|
2749
|
-
const g = gf.glyphs[ch];
|
|
2750
|
-
if (g && g.d)
|
|
2751
|
-
|
|
2788
|
+
const g = gf == null ? void 0 : gf.glyphs[ch];
|
|
2789
|
+
if (g && g.d) {
|
|
2790
|
+
placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
|
|
2791
|
+
pen.x += g.width * scale;
|
|
2792
|
+
} else if (/\S/.test(ch)) {
|
|
2793
|
+
const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
|
|
2794
|
+
placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
|
|
2795
|
+
pen.x += advEm * scale;
|
|
2796
|
+
} else {
|
|
2797
|
+
pen.x += (g ? g.width : 0) * scale;
|
|
2798
|
+
}
|
|
2799
|
+
pen.x += s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2752
2800
|
lines[line].end = pen.x;
|
|
2753
2801
|
}
|
|
2754
2802
|
};
|
|
@@ -2783,24 +2831,152 @@ function materialiseGlyphTextHorizontal(node, opts) {
|
|
|
2783
2831
|
}
|
|
2784
2832
|
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
2785
2833
|
}
|
|
2834
|
+
function layoutGlyphTextChars(node, opts) {
|
|
2835
|
+
var _a, _b, _c, _d, _e;
|
|
2836
|
+
if ((_a = opts.alongPath) == null ? void 0 : _a.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
|
|
2837
|
+
const { glyphs, warnings } = opts;
|
|
2838
|
+
const soleFont = soleFontOf(glyphs);
|
|
2839
|
+
const pen = { x: (_b = parseLen(node.x)) != null ? _b : 0, y: (_c = parseLen(node.y)) != null ? _c : 0 };
|
|
2840
|
+
const boxes = [];
|
|
2841
|
+
const lines = [{ start: pen.x, end: pen.x }];
|
|
2842
|
+
let line = 0;
|
|
2843
|
+
const renderChars = (content, s) => {
|
|
2844
|
+
var _a2;
|
|
2845
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2846
|
+
const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
|
|
2847
|
+
const scale = s.fontSize / upm;
|
|
2848
|
+
const ascent = ((_a2 = gf == null ? void 0 : gf.ascent) != null ? _a2 : 0.9 * upm) * scale;
|
|
2849
|
+
for (let i = 0; i < content.length; i++) {
|
|
2850
|
+
const ch = content.charAt(i);
|
|
2851
|
+
const g = gf == null ? void 0 : gf.glyphs[ch];
|
|
2852
|
+
const advance = (g ? g.width : 0) * scale + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2853
|
+
boxes.push({ x: pen.x, y: pen.y, width: advance, ascent, fontSize: s.fontSize, line });
|
|
2854
|
+
pen.x += advance;
|
|
2855
|
+
lines[line].end = pen.x;
|
|
2856
|
+
}
|
|
2857
|
+
};
|
|
2858
|
+
const walk = (el, parentStyle) => {
|
|
2859
|
+
var _a2, _b2, _c2, _d2;
|
|
2860
|
+
const s = resolveStyle(el, parentStyle);
|
|
2861
|
+
const x = parseLen(el.x);
|
|
2862
|
+
const y = parseLen(el.y);
|
|
2863
|
+
if (x !== void 0) {
|
|
2864
|
+
pen.x = x;
|
|
2865
|
+
line = lines.length;
|
|
2866
|
+
lines.push({ start: pen.x, end: pen.x });
|
|
2867
|
+
}
|
|
2868
|
+
if (y !== void 0) pen.y = y;
|
|
2869
|
+
pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
|
|
2870
|
+
pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
|
|
2871
|
+
const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
|
|
2872
|
+
if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
|
|
2873
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2874
|
+
};
|
|
2875
|
+
const rootStyle = rootStyleOf(node);
|
|
2876
|
+
if (node.children) for (const ch of node.children) walk(ch, rootStyle);
|
|
2877
|
+
const rootContent = (_d = str(node[TEXT_ATTR])) != null ? _d : str(node[TEXT_CONTENT_ATTR]);
|
|
2878
|
+
if (rootContent && !((_e = node.children) == null ? void 0 : _e.length)) renderChars(rootContent, rootStyle);
|
|
2879
|
+
const anchor = str(node.textAnchor);
|
|
2880
|
+
if (anchor === "middle" || anchor === "end") {
|
|
2881
|
+
for (const b of boxes) {
|
|
2882
|
+
const w = lines[b.line].end - lines[b.line].start;
|
|
2883
|
+
b.x += anchor === "middle" ? -w / 2 : -w;
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
return boxes.map((_f) => {
|
|
2887
|
+
var _g = _f, { line: _l } = _g, b = __objRest(_g, ["line"]);
|
|
2888
|
+
return b;
|
|
2889
|
+
});
|
|
2890
|
+
}
|
|
2891
|
+
function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
|
|
2892
|
+
var _a;
|
|
2893
|
+
const { glyphs, warnings, alongPath } = opts;
|
|
2894
|
+
const sampler = createPathSampler(pathD);
|
|
2895
|
+
if (!sampler) {
|
|
2896
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry (caret)");
|
|
2897
|
+
return [];
|
|
2898
|
+
}
|
|
2899
|
+
const soleFont = soleFontOf(glyphs);
|
|
2900
|
+
const chars = [];
|
|
2901
|
+
let adv = 0;
|
|
2902
|
+
const walk = (el, parentStyle) => {
|
|
2903
|
+
var _a2, _b, _c;
|
|
2904
|
+
const s = resolveStyle(el, parentStyle);
|
|
2905
|
+
const content = (_a2 = str(el[TEXT_ATTR])) != null ? _a2 : str(el[TEXT_CONTENT_ATTR]);
|
|
2906
|
+
if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
|
|
2907
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2908
|
+
const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
|
|
2909
|
+
const scale = s.fontSize / upm;
|
|
2910
|
+
const ascent = ((_c = gf == null ? void 0 : gf.ascent) != null ? _c : 0.9 * upm) * scale;
|
|
2911
|
+
for (let i = 0; i < content.length; i++) {
|
|
2912
|
+
const ch = content.charAt(i);
|
|
2913
|
+
const g = gf == null ? void 0 : gf.glyphs[ch];
|
|
2914
|
+
const glyphW = (g ? g.width : 0) * scale;
|
|
2915
|
+
const advance = glyphW + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2916
|
+
chars.push({ advStart: adv, advEnd: adv + advance, glyphW, ascent, fontSize: s.fontSize });
|
|
2917
|
+
adv += advance;
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2921
|
+
};
|
|
2922
|
+
walk(node, rootStyleOf(node));
|
|
2923
|
+
const width = adv;
|
|
2924
|
+
const k = (alongPath == null ? void 0 : alongPath.textLength) && alongPath.textLength > 0 && width > 0 ? alongPath.textLength / width : 1;
|
|
2925
|
+
const so = readAnimatable(alongPath == null ? void 0 : alongPath.startOffset);
|
|
2926
|
+
const { along: alongOffset, perp } = alongPathNodeOffsets(node);
|
|
2927
|
+
const base = alongOffset + (so.kind === "animated" /* Animated */ ? Number((_a = so.keyframes[0]) == null ? void 0 : _a.value) || 0 : so.kind === "static" /* Static */ ? Number(so.value) || 0 : 0);
|
|
2928
|
+
const withPerp = (p) => ({
|
|
2929
|
+
x: p.x - perp * Math.sin(p.angle),
|
|
2930
|
+
y: p.y + perp * Math.cos(p.angle),
|
|
2931
|
+
angle: p.angle
|
|
2932
|
+
});
|
|
2933
|
+
return chars.map((c) => {
|
|
2934
|
+
const dStart = base + c.advStart * k;
|
|
2935
|
+
const dEnd = base + c.advEnd * k;
|
|
2936
|
+
const p0 = withPerp(sampler.sampleAtDistance(dStart));
|
|
2937
|
+
const p1 = withPerp(sampler.sampleAtDistance(dEnd));
|
|
2938
|
+
const glyphMid = sampler.sampleAtDistance(base + (c.advStart + c.glyphW / 2) * k);
|
|
2939
|
+
return {
|
|
2940
|
+
x: p0.x,
|
|
2941
|
+
y: p0.y,
|
|
2942
|
+
width: c.advEnd - c.advStart,
|
|
2943
|
+
ascent: c.ascent,
|
|
2944
|
+
fontSize: c.fontSize,
|
|
2945
|
+
endX: p1.x,
|
|
2946
|
+
endY: p1.y,
|
|
2947
|
+
rotation: glyphMid.angle * 180 / Math.PI
|
|
2948
|
+
};
|
|
2949
|
+
});
|
|
2950
|
+
}
|
|
2786
2951
|
function collectAlongPathCells(node, glyphs, soleFont, warnings) {
|
|
2787
2952
|
const cells = [];
|
|
2788
2953
|
let adv = 0;
|
|
2789
2954
|
const walk = (el, parentStyle) => {
|
|
2790
|
-
var _a, _b;
|
|
2955
|
+
var _a, _b, _c;
|
|
2791
2956
|
const s = resolveStyle(el, parentStyle);
|
|
2792
2957
|
const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
|
|
2793
2958
|
if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
|
|
2794
2959
|
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2795
2960
|
if (gf) {
|
|
2796
2961
|
const scale = s.fontSize / gf.unitsPerEm;
|
|
2962
|
+
const ascentEm = (_c = gf.ascent) != null ? _c : 0.9 * gf.unitsPerEm;
|
|
2797
2963
|
const paint = paintOf(s);
|
|
2798
2964
|
for (let i = 0; i < content.length; i++) {
|
|
2799
2965
|
const ch = content.charAt(i);
|
|
2800
2966
|
const g = gf.glyphs[ch];
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2967
|
+
if (g && g.d) {
|
|
2968
|
+
const glyphAdv = g.width * scale;
|
|
2969
|
+
cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
|
|
2970
|
+
adv += glyphAdv;
|
|
2971
|
+
} else if (/\S/.test(ch)) {
|
|
2972
|
+
const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
|
|
2973
|
+
const boxAdv = wEm * scale;
|
|
2974
|
+
cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, midBase: adv + boxAdv / 2 });
|
|
2975
|
+
adv += boxAdv;
|
|
2976
|
+
} else {
|
|
2977
|
+
adv += (g ? g.width : 0) * scale;
|
|
2978
|
+
}
|
|
2979
|
+
adv += s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2804
2980
|
}
|
|
2805
2981
|
}
|
|
2806
2982
|
}
|
|
@@ -2809,10 +2985,17 @@ function collectAlongPathCells(node, glyphs, soleFont, warnings) {
|
|
|
2809
2985
|
walk(node, rootStyleOf(node));
|
|
2810
2986
|
return { cells, width: adv };
|
|
2811
2987
|
}
|
|
2812
|
-
function alongAffine(sampler, dist, scale, widthEm) {
|
|
2988
|
+
function alongAffine(sampler, dist, scale, widthEm, perp = 0) {
|
|
2813
2989
|
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
2814
2990
|
const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;
|
|
2815
|
-
return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw, y - scale * sin * hw];
|
|
2991
|
+
return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw - perp * sin, y - scale * sin * hw + perp * cos];
|
|
2992
|
+
}
|
|
2993
|
+
function alongPathNodeOffsets(node) {
|
|
2994
|
+
var _a, _b, _c;
|
|
2995
|
+
return {
|
|
2996
|
+
along: ((_a = parseLen(node.x)) != null ? _a : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
|
|
2997
|
+
perp: (_c = parseLen(node.dy)) != null ? _c : 0
|
|
2998
|
+
};
|
|
2816
2999
|
}
|
|
2817
3000
|
function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
|
|
2818
3001
|
var _a;
|
|
@@ -2825,6 +3008,7 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
|
|
|
2825
3008
|
const soleFont = soleFontOf(glyphs);
|
|
2826
3009
|
const { cells, width } = collectAlongPathCells(node, glyphs, soleFont, warnings);
|
|
2827
3010
|
if (!cells.length) return toGroup(node, [], create);
|
|
3011
|
+
const { along: alongOffset, perp } = alongPathNodeOffsets(node);
|
|
2828
3012
|
if (textLength && textLength > 0 && width > 0) {
|
|
2829
3013
|
const k = textLength / width;
|
|
2830
3014
|
for (const c of cells) c.midBase *= k;
|
|
@@ -2832,9 +3016,9 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
|
|
|
2832
3016
|
const isClip = pathOverflow === "clip" && !sampler.closed;
|
|
2833
3017
|
const so = readAnimatable(startOffset);
|
|
2834
3018
|
if (so.kind === "animated" /* Animated */ && so.keyframes.length >= 2) {
|
|
2835
|
-
return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create, isClip), create);
|
|
3019
|
+
return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create, isClip, alongOffset, perp), create);
|
|
2836
3020
|
}
|
|
2837
|
-
const base = so.kind === "animated" /* Animated */ ? Number((_a = so.keyframes[0]) == null ? void 0 : _a.value) || 0 : so.kind === "static" /* Static */ ? Number(so.value) || 0 : 0;
|
|
3021
|
+
const base = alongOffset + (so.kind === "animated" /* Animated */ ? Number((_a = so.keyframes[0]) == null ? void 0 : _a.value) || 0 : so.kind === "static" /* Static */ ? Number(so.value) || 0 : 0);
|
|
2838
3022
|
const placeCells = isClip ? cells.filter((c) => {
|
|
2839
3023
|
const d = base + c.midBase;
|
|
2840
3024
|
return d >= 0 && d <= sampler.totalLength;
|
|
@@ -2842,7 +3026,7 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
|
|
|
2842
3026
|
const placements = placeCells.map((c) => ({
|
|
2843
3027
|
glyphD: c.glyphD,
|
|
2844
3028
|
paint: c.paint,
|
|
2845
|
-
m: alongAffine(sampler, base + c.midBase, c.scale, c.widthEm)
|
|
3029
|
+
m: alongAffine(sampler, base + c.midBase, c.scale, c.widthEm, perp)
|
|
2846
3030
|
}));
|
|
2847
3031
|
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
2848
3032
|
}
|
|
@@ -2852,10 +3036,10 @@ function roundN(v, n) {
|
|
|
2852
3036
|
const f = __pow(10, n);
|
|
2853
3037
|
return Math.round(v * f) / f;
|
|
2854
3038
|
}
|
|
2855
|
-
function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create, isClip) {
|
|
3039
|
+
function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create, isClip, alongOffset = 0, perp = 0) {
|
|
2856
3040
|
const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);
|
|
2857
3041
|
const timeOf = (kf) => Number(kf.time) || 0;
|
|
2858
|
-
const offOf = (kf) => Number(kf.value) || 0;
|
|
3042
|
+
const offOf = (kf) => alongOffset + (Number(kf.value) || 0);
|
|
2859
3043
|
const onPath = (dist) => dist >= 0 && dist <= sampler.totalLength;
|
|
2860
3044
|
const out = [];
|
|
2861
3045
|
for (const c of cells) {
|
|
@@ -2863,10 +3047,11 @@ function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create, isClip) {
|
|
|
2863
3047
|
const d = transformPathData(c.glyphD, centred);
|
|
2864
3048
|
const sampleKf = (dist, time) => {
|
|
2865
3049
|
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
3050
|
+
const cos = Math.cos(angle), sin = Math.sin(angle);
|
|
2866
3051
|
return {
|
|
2867
3052
|
time,
|
|
2868
3053
|
value: {
|
|
2869
|
-
["translate" /* Translate */]: [roundN(x, 3), roundN(y, 3)],
|
|
3054
|
+
["translate" /* Translate */]: [roundN(x - perp * sin, 3), roundN(y + perp * cos, 3)],
|
|
2870
3055
|
["rotate" /* Rotate */]: roundN(angle * 180 / Math.PI, 3)
|
|
2871
3056
|
}
|
|
2872
3057
|
};
|
|
@@ -3136,9 +3321,18 @@ function buildOutKfValue(prevV, nextV, p, translate, rotateDegFromAutoOrient, au
|
|
|
3136
3321
|
if (pv === void 0 && nv === void 0) continue;
|
|
3137
3322
|
value[k] = interpolatePart(pv, nv, p);
|
|
3138
3323
|
}
|
|
3139
|
-
if (rotateDegFromAutoOrient !== void 0)
|
|
3324
|
+
if (rotateDegFromAutoOrient !== void 0) {
|
|
3325
|
+
value.rotate = rotateDegFromAutoOrient + explicitRotateAt(prevV, nextV, p);
|
|
3326
|
+
}
|
|
3140
3327
|
return value;
|
|
3141
3328
|
}
|
|
3329
|
+
function explicitRotateAt(prevV, nextV, p) {
|
|
3330
|
+
const pv = typeof (prevV == null ? void 0 : prevV.rotate) === "number" ? prevV.rotate : void 0;
|
|
3331
|
+
const nv = typeof (nextV == null ? void 0 : nextV.rotate) === "number" ? nextV.rotate : void 0;
|
|
3332
|
+
if (pv === void 0 && nv === void 0) return 0;
|
|
3333
|
+
const r = interpolatePart(pv, nv, p);
|
|
3334
|
+
return typeof r === "number" ? r : 0;
|
|
3335
|
+
}
|
|
3142
3336
|
function derivAngleForFirstKf(kf0, kf1) {
|
|
3143
3337
|
const p0 = getKfTranslate(kf0);
|
|
3144
3338
|
const p1 = getKfTranslate(kf1);
|
|
@@ -3159,10 +3353,12 @@ function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos,
|
|
|
3159
3353
|
const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
|
|
3160
3354
|
const prevExit = lastV == null ? void 0 : lastV.rotate;
|
|
3161
3355
|
if (typeof prevExit !== "number") return;
|
|
3356
|
+
const boundaryV = getKfValueParts(prevKf);
|
|
3357
|
+
const prevExitTangent = prevExit - explicitRotateAt(boundaryV, boundaryV, 0);
|
|
3162
3358
|
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
3163
3359
|
const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
3164
3360
|
const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;
|
|
3165
|
-
const delta = wrappedAngleDelta(nextEntry,
|
|
3361
|
+
const delta = wrappedAngleDelta(nextEntry, prevExitTangent);
|
|
3166
3362
|
if (Math.abs(delta) <= rotationTol) return;
|
|
3167
3363
|
const dupValue = buildOutKfValue(
|
|
3168
3364
|
getKfValueParts(prevKf),
|
|
@@ -4361,7 +4557,7 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
|
4361
4557
|
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
4362
4558
|
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
4363
4559
|
if (!fx && !innerIdForContentRef) return node;
|
|
4364
|
-
const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
|
|
4560
|
+
const { transformation, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
|
|
4365
4561
|
const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
|
|
4366
4562
|
if (fx) delete node.effects;
|
|
4367
4563
|
let n = node;
|
|
@@ -4387,6 +4583,7 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
|
4387
4583
|
n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
|
|
4388
4584
|
n = applyRepeaterEffect(n, repeater, ctx);
|
|
4389
4585
|
n = applyMaskedByEffect(n, maskedBy, transformation, ctx);
|
|
4586
|
+
n = applyClipPathEffect(n, clipPath, ctx);
|
|
4390
4587
|
if (innerIdForContentRef) {
|
|
4391
4588
|
applyRefHref(n, cloneFx, ctx);
|
|
4392
4589
|
n = splitForContentRef(n, transformation, originalId, innerIdForContentRef, ctx);
|
|
@@ -4715,6 +4912,8 @@ function getNormalizedProps(props) {
|
|
|
4715
4912
|
function renderNode(node, defs) {
|
|
4716
4913
|
if (!node) return null;
|
|
4717
4914
|
const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
|
|
4915
|
+
const feFuncType = props.funcType;
|
|
4916
|
+
if (feFuncType !== void 0) delete props.funcType;
|
|
4718
4917
|
const nodeDefs = getDefs(node) || defs;
|
|
4719
4918
|
const resolvedStyle = resolveStyle2(style, nodeDefs);
|
|
4720
4919
|
let childElements;
|
|
@@ -4727,13 +4926,15 @@ function renderNode(node, defs) {
|
|
|
4727
4926
|
}
|
|
4728
4927
|
}
|
|
4729
4928
|
}
|
|
4730
|
-
|
|
4929
|
+
const element = createElement(
|
|
4731
4930
|
type || "g",
|
|
4732
4931
|
getNormalizedProps(props),
|
|
4733
4932
|
resolvedStyle,
|
|
4734
4933
|
childElements,
|
|
4735
4934
|
props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]
|
|
4736
4935
|
);
|
|
4936
|
+
if (element && feFuncType !== void 0) element.setAttribute("type", feFuncType);
|
|
4937
|
+
return element;
|
|
4737
4938
|
}
|
|
4738
4939
|
|
|
4739
4940
|
// src/PxAnimatorTriggers.ts
|
|
@@ -4744,7 +4945,12 @@ function setupAnimationTriggers(api, config) {
|
|
|
4744
4945
|
console.warn("setupAnimationTriggers: No root element found for animation.");
|
|
4745
4946
|
return api;
|
|
4746
4947
|
}
|
|
4948
|
+
let reversed = false;
|
|
4747
4949
|
const start = () => {
|
|
4950
|
+
if (reversed) {
|
|
4951
|
+
reversed = false;
|
|
4952
|
+
api.setPlaybackRate(1);
|
|
4953
|
+
}
|
|
4748
4954
|
api.play();
|
|
4749
4955
|
};
|
|
4750
4956
|
const handleEndAction = () => {
|
|
@@ -4756,6 +4962,8 @@ function setupAnimationTriggers(api, config) {
|
|
|
4756
4962
|
api.cancel();
|
|
4757
4963
|
break;
|
|
4758
4964
|
case "reverse":
|
|
4965
|
+
reversed = true;
|
|
4966
|
+
api.setPlaybackRate(-1);
|
|
4759
4967
|
api.play();
|
|
4760
4968
|
break;
|
|
4761
4969
|
case "continue":
|
|
@@ -4818,6 +5026,7 @@ function getSelector(id) {
|
|
|
4818
5026
|
return "#" + id;
|
|
4819
5027
|
}
|
|
4820
5028
|
function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
5029
|
+
var _a;
|
|
4821
5030
|
const config = getAnimatorConfig(doc) || {};
|
|
4822
5031
|
const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
|
|
4823
5032
|
const _iterations = config.iterations;
|
|
@@ -4828,18 +5037,24 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
4828
5037
|
const duration = +(config.duration || DEFAULT_DURATION_MS);
|
|
4829
5038
|
const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : 1) * duration : 0;
|
|
4830
5039
|
const direction = config.direction || "normal";
|
|
5040
|
+
const fill = (_a = config.fill) != null ? _a : "forwards";
|
|
5041
|
+
const fillsForwards = fill === "forwards" || fill === "both";
|
|
5042
|
+
const fillsBackwards = fill === "backwards" || fill === "both";
|
|
4831
5043
|
let timerId = null;
|
|
4832
5044
|
let playing = false;
|
|
4833
|
-
let timeBeforeLastStartMs = config.delay || 0;
|
|
5045
|
+
let timeBeforeLastStartMs = -(config.delay || 0);
|
|
4834
5046
|
let lastStartedTs = 0;
|
|
4835
5047
|
let playbackRate = 1;
|
|
4836
5048
|
let finishCalled = false;
|
|
4837
5049
|
const frameRate = config.frameRate;
|
|
4838
5050
|
const minFrameIntervalMs = frameRate && frameRate > 0 ? 1e3 / frameRate : 0;
|
|
4839
5051
|
let lastRenderTs = 0;
|
|
4840
|
-
const
|
|
5052
|
+
const getRawAnimTime = () => {
|
|
4841
5053
|
const runningElapsed = lastStartedTs ? (Date.now() - lastStartedTs) * playbackRate : 0;
|
|
4842
|
-
|
|
5054
|
+
return timeBeforeLastStartMs + runningElapsed;
|
|
5055
|
+
};
|
|
5056
|
+
const getAnimCurrentTime = () => {
|
|
5057
|
+
let time = getRawAnimTime();
|
|
4843
5058
|
if (Number.isFinite(totalDuration) && time > totalDuration) time = totalDuration;
|
|
4844
5059
|
if (time < 0) time = 0;
|
|
4845
5060
|
return time;
|
|
@@ -4884,40 +5099,59 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
4884
5099
|
}
|
|
4885
5100
|
}
|
|
4886
5101
|
const tick = () => {
|
|
4887
|
-
var
|
|
5102
|
+
var _a2, _b;
|
|
4888
5103
|
if (!adapter.isConnected()) {
|
|
4889
5104
|
pauseAnim();
|
|
4890
5105
|
return;
|
|
4891
5106
|
}
|
|
4892
5107
|
const currentTime = getAnimCurrentTime();
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
if (
|
|
4896
|
-
|
|
4897
|
-
}
|
|
4898
|
-
lastRenderTs = now;
|
|
4899
|
-
}
|
|
4900
|
-
if (duration <= 0) {
|
|
5108
|
+
const rawTime = getRawAnimTime();
|
|
5109
|
+
if (rawTime < 0 && playbackRate > 0) {
|
|
5110
|
+
if (fillsBackwards) renderFrame(0);
|
|
5111
|
+
return;
|
|
4901
5112
|
}
|
|
4902
|
-
if (
|
|
4903
|
-
|
|
5113
|
+
if (playbackRate < 0 && rawTime <= 0) {
|
|
5114
|
+
pauseAnim();
|
|
5115
|
+
renderFrame(0);
|
|
4904
5116
|
if (!finishCalled) {
|
|
4905
5117
|
finishCalled = true;
|
|
4906
|
-
(
|
|
5118
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
|
|
4907
5119
|
}
|
|
5120
|
+
return;
|
|
5121
|
+
}
|
|
5122
|
+
if (playbackRate > 0 && totalDuration && Number.isFinite(totalDuration) && currentTime >= totalDuration) {
|
|
4908
5123
|
pauseAnim();
|
|
5124
|
+
renderFrame(fillsForwards ? totalDuration : 0);
|
|
5125
|
+
if (!finishCalled) {
|
|
5126
|
+
finishCalled = true;
|
|
5127
|
+
(_b = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _b.call(callbacks);
|
|
5128
|
+
}
|
|
4909
5129
|
return;
|
|
4910
5130
|
}
|
|
5131
|
+
if (minFrameIntervalMs > 0) {
|
|
5132
|
+
const now = Date.now();
|
|
5133
|
+
if (lastRenderTs && now - lastRenderTs < minFrameIntervalMs) {
|
|
5134
|
+
return;
|
|
5135
|
+
}
|
|
5136
|
+
lastRenderTs = now;
|
|
5137
|
+
}
|
|
4911
5138
|
renderFrame(currentTime);
|
|
4912
5139
|
};
|
|
4913
5140
|
if (config.delay) {
|
|
4914
|
-
|
|
5141
|
+
if (config.delay < 0) {
|
|
5142
|
+
renderFrame(getAnimCurrentTime());
|
|
5143
|
+
} else if (fillsBackwards) {
|
|
5144
|
+
renderFrame(0);
|
|
5145
|
+
}
|
|
4915
5146
|
}
|
|
4916
5147
|
const _isPlaying = () => {
|
|
4917
5148
|
if (!playing) return false;
|
|
4918
5149
|
if (!adapter.isConnected()) {
|
|
4919
5150
|
return false;
|
|
4920
5151
|
}
|
|
5152
|
+
if (playbackRate < 0) {
|
|
5153
|
+
return getRawAnimTime() > 0;
|
|
5154
|
+
}
|
|
4921
5155
|
if (Number.isFinite(totalDuration) && getAnimCurrentTime() >= totalDuration) return false;
|
|
4922
5156
|
return true;
|
|
4923
5157
|
};
|
|
@@ -4937,37 +5171,53 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
4937
5171
|
};
|
|
4938
5172
|
const startAnim = () => {
|
|
4939
5173
|
if (playing) return;
|
|
4940
|
-
if (
|
|
4941
|
-
timeBeforeLastStartMs
|
|
4942
|
-
|
|
5174
|
+
if (playbackRate >= 0) {
|
|
5175
|
+
if (Number.isFinite(totalDuration) && timeBeforeLastStartMs >= totalDuration) {
|
|
5176
|
+
timeBeforeLastStartMs = 0;
|
|
5177
|
+
}
|
|
5178
|
+
} else {
|
|
5179
|
+
if (timeBeforeLastStartMs <= 0) {
|
|
5180
|
+
if (!Number.isFinite(totalDuration)) {
|
|
5181
|
+
console.warn("play: cannot start reverse playback of an infinite animation from time 0");
|
|
5182
|
+
return;
|
|
5183
|
+
}
|
|
5184
|
+
timeBeforeLastStartMs = totalDuration;
|
|
5185
|
+
}
|
|
4943
5186
|
}
|
|
5187
|
+
finishCalled = false;
|
|
4944
5188
|
playing = true;
|
|
4945
5189
|
lastStartedTs = Date.now();
|
|
4946
5190
|
loopAnim(true);
|
|
4947
5191
|
};
|
|
4948
5192
|
const pauseAnim = () => {
|
|
4949
5193
|
if (!playing) return;
|
|
4950
|
-
|
|
5194
|
+
let raw = getRawAnimTime();
|
|
5195
|
+
if (Number.isFinite(totalDuration) && raw > totalDuration) raw = totalDuration;
|
|
5196
|
+
timeBeforeLastStartMs = raw;
|
|
4951
5197
|
lastStartedTs = 0;
|
|
4952
5198
|
playing = false;
|
|
4953
5199
|
if (timerId !== null) {
|
|
4954
5200
|
cancelAnimationFrame(timerId);
|
|
4955
5201
|
timerId = null;
|
|
4956
5202
|
}
|
|
4957
|
-
|
|
5203
|
+
if (raw >= 0) {
|
|
5204
|
+
renderFrame(raw);
|
|
5205
|
+
} else if (fillsBackwards) {
|
|
5206
|
+
renderFrame(0);
|
|
5207
|
+
}
|
|
4958
5208
|
};
|
|
4959
5209
|
const cancelAnim = () => {
|
|
4960
|
-
var
|
|
5210
|
+
var _a2;
|
|
4961
5211
|
pauseAnim();
|
|
4962
5212
|
timeBeforeLastStartMs = 0;
|
|
4963
5213
|
lastStartedTs = 0;
|
|
4964
5214
|
playing = false;
|
|
4965
5215
|
finishCalled = false;
|
|
4966
5216
|
renderFrame(timeBeforeLastStartMs);
|
|
4967
|
-
(
|
|
5217
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
|
|
4968
5218
|
};
|
|
4969
5219
|
const finishAnim = (callOnFinish = true) => {
|
|
4970
|
-
var
|
|
5220
|
+
var _a2;
|
|
4971
5221
|
if (Number.isFinite(totalDuration)) {
|
|
4972
5222
|
timeBeforeLastStartMs = totalDuration;
|
|
4973
5223
|
} else {
|
|
@@ -4975,10 +5225,14 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
4975
5225
|
}
|
|
4976
5226
|
lastStartedTs = 0;
|
|
4977
5227
|
playing = false;
|
|
4978
|
-
|
|
5228
|
+
if (timerId !== null) {
|
|
5229
|
+
cancelAnimationFrame(timerId);
|
|
5230
|
+
timerId = null;
|
|
5231
|
+
}
|
|
5232
|
+
renderFrame(fillsForwards ? timeBeforeLastStartMs : 0);
|
|
4979
5233
|
if (callOnFinish && !finishCalled) {
|
|
4980
5234
|
finishCalled = true;
|
|
4981
|
-
(
|
|
5235
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
|
|
4982
5236
|
}
|
|
4983
5237
|
};
|
|
4984
5238
|
const api = {
|
|
@@ -4988,14 +5242,14 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
4988
5242
|
return _isPlaying();
|
|
4989
5243
|
},
|
|
4990
5244
|
"play": () => {
|
|
4991
|
-
var
|
|
5245
|
+
var _a2;
|
|
4992
5246
|
startAnim();
|
|
4993
|
-
(
|
|
5247
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
|
|
4994
5248
|
},
|
|
4995
5249
|
"pause": () => {
|
|
4996
|
-
var
|
|
5250
|
+
var _a2;
|
|
4997
5251
|
pauseAnim();
|
|
4998
|
-
(
|
|
5252
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a2.call(callbacks);
|
|
4999
5253
|
},
|
|
5000
5254
|
"cancel": () => {
|
|
5001
5255
|
cancelAnim();
|
|
@@ -5008,7 +5262,9 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
5008
5262
|
console.warn("setPlaybackRate: rate must be finite and non-zero");
|
|
5009
5263
|
return;
|
|
5010
5264
|
}
|
|
5011
|
-
|
|
5265
|
+
let current = getRawAnimTime();
|
|
5266
|
+
if (Number.isFinite(totalDuration) && current > totalDuration) current = totalDuration;
|
|
5267
|
+
if (rate < 0 !== playbackRate < 0) finishCalled = false;
|
|
5012
5268
|
playbackRate = rate;
|
|
5013
5269
|
timeBeforeLastStartMs = current;
|
|
5014
5270
|
if (playing) lastStartedTs = Date.now();
|
|
@@ -5021,10 +5277,13 @@ function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
|
|
|
5021
5277
|
if (Number.isFinite(totalDuration) && newTime > totalDuration) newTime = totalDuration;
|
|
5022
5278
|
timeBeforeLastStartMs = newTime;
|
|
5023
5279
|
if (playing) lastStartedTs = Date.now();
|
|
5280
|
+
if (!Number.isFinite(totalDuration) || newTime < totalDuration) finishCalled = false;
|
|
5024
5281
|
renderFrame(getAnimCurrentTime());
|
|
5025
5282
|
},
|
|
5026
5283
|
"destroy": () => {
|
|
5284
|
+
var _a2;
|
|
5027
5285
|
api.cancel();
|
|
5286
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
|
|
5028
5287
|
}
|
|
5029
5288
|
};
|
|
5030
5289
|
return api;
|
|
@@ -5189,6 +5448,8 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
5189
5448
|
if (typeof _iterations === "number") iterations = _iterations;
|
|
5190
5449
|
if (_iterations === "infinite") iterations = Infinity;
|
|
5191
5450
|
const unsupportedSet = /* @__PURE__ */ new Set();
|
|
5451
|
+
let finishNotified = false;
|
|
5452
|
+
let removeCalled = false;
|
|
5192
5453
|
if (!(bindings == null ? void 0 : bindings.length)) {
|
|
5193
5454
|
console.warn("createWebApiAnimator: No animation bindings defined");
|
|
5194
5455
|
}
|
|
@@ -5205,7 +5466,11 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
5205
5466
|
}
|
|
5206
5467
|
const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);
|
|
5207
5468
|
const positiveDelay = config.delay && config.delay > 0 ? config.delay : void 0;
|
|
5208
|
-
|
|
5469
|
+
let seekPosition;
|
|
5470
|
+
if (config.delay && config.delay < 0 && config.duration) {
|
|
5471
|
+
const rawSeek = -config.delay;
|
|
5472
|
+
seekPosition = iterations === Infinity ? rawSeek % config.duration : Math.min(rawSeek, config.duration * (iterations != null ? iterations : 1));
|
|
5473
|
+
}
|
|
5209
5474
|
const effectOptions = {
|
|
5210
5475
|
duration: config.duration,
|
|
5211
5476
|
delay: positiveDelay,
|
|
@@ -5226,13 +5491,17 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
5226
5491
|
const anim = new Animation(effect, document.timeline);
|
|
5227
5492
|
if (callbacks == null ? void 0 : callbacks.onFinish) anim.onfinish = () => {
|
|
5228
5493
|
var _a2;
|
|
5229
|
-
|
|
5494
|
+
if (finishNotified) return;
|
|
5495
|
+
finishNotified = true;
|
|
5496
|
+
(_a2 = callbacks.onFinish) == null ? void 0 : _a2.call(callbacks);
|
|
5230
5497
|
};
|
|
5231
5498
|
if (callbacks == null ? void 0 : callbacks.onRemove) anim.onremove = () => {
|
|
5232
5499
|
var _a2;
|
|
5233
|
-
|
|
5500
|
+
if (removeCalled) return;
|
|
5501
|
+
removeCalled = true;
|
|
5502
|
+
(_a2 = callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
|
|
5234
5503
|
};
|
|
5235
|
-
if (seekPosition) {
|
|
5504
|
+
if (seekPosition !== void 0) {
|
|
5236
5505
|
anim.currentTime = seekPosition;
|
|
5237
5506
|
}
|
|
5238
5507
|
animations.push(anim);
|
|
@@ -5256,6 +5525,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
5256
5525
|
},
|
|
5257
5526
|
"play": () => {
|
|
5258
5527
|
var _a2;
|
|
5528
|
+
finishNotified = false;
|
|
5259
5529
|
animations.forEach((a) => a.play());
|
|
5260
5530
|
(_a2 = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a2.call(callbacks);
|
|
5261
5531
|
},
|
|
@@ -5266,6 +5536,7 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
5266
5536
|
},
|
|
5267
5537
|
"cancel": () => {
|
|
5268
5538
|
var _a2;
|
|
5539
|
+
finishNotified = false;
|
|
5269
5540
|
animations.forEach((a) => a.cancel());
|
|
5270
5541
|
(_a2 = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a2.call(callbacks);
|
|
5271
5542
|
},
|
|
@@ -5295,13 +5566,19 @@ function createWebApiAnimator(doc, callbacks, rootElement, forceEvenIfHasUnsuppo
|
|
|
5295
5566
|
return res !== null ? +res : null;
|
|
5296
5567
|
},
|
|
5297
5568
|
"setCurrentTime": (time) => {
|
|
5569
|
+
finishNotified = false;
|
|
5298
5570
|
animations.forEach((a) => {
|
|
5299
5571
|
a.currentTime = time;
|
|
5300
5572
|
});
|
|
5301
5573
|
},
|
|
5302
5574
|
"destroy": () => {
|
|
5575
|
+
var _a2;
|
|
5303
5576
|
api.cancel();
|
|
5304
5577
|
animations.splice(0, animations.length);
|
|
5578
|
+
if (!removeCalled) {
|
|
5579
|
+
removeCalled = true;
|
|
5580
|
+
(_a2 = callbacks == null ? void 0 : callbacks.onRemove) == null ? void 0 : _a2.call(callbacks);
|
|
5581
|
+
}
|
|
5305
5582
|
}
|
|
5306
5583
|
};
|
|
5307
5584
|
if (config.trigger) {
|
|
@@ -5445,7 +5722,6 @@ function createAnimatorImpl(doc, adapter, callbacks, containerElement) {
|
|
|
5445
5722
|
const effectsWarnings = validateNodeEffects(doc);
|
|
5446
5723
|
for (const w of effectsWarnings) console.warn("[PxAnimator] effects shape warning:", w);
|
|
5447
5724
|
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
5448
|
-
animatorConfig.debug = true;
|
|
5449
5725
|
const engine = animatorConfig.mode === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi;
|
|
5450
5726
|
doc = materialiseAllInTree(doc, engine);
|
|
5451
5727
|
let rootElement = null;
|
|
@@ -5474,37 +5750,55 @@ function createAnimator(options) {
|
|
|
5474
5750
|
return createAnimatorImpl(data, adapter, callbacks, container);
|
|
5475
5751
|
}
|
|
5476
5752
|
let animator = null;
|
|
5753
|
+
let pending = [];
|
|
5754
|
+
let destroyed = false;
|
|
5755
|
+
const enqueue = (call) => {
|
|
5756
|
+
if (animator) {
|
|
5757
|
+
call(animator);
|
|
5758
|
+
} else if (pending) {
|
|
5759
|
+
pending.push(call);
|
|
5760
|
+
}
|
|
5761
|
+
};
|
|
5477
5762
|
fetch(src).then((res) => res.json()).then((json) => {
|
|
5763
|
+
if (destroyed) return;
|
|
5478
5764
|
if (isPxElementFileFormat(json)) {
|
|
5479
5765
|
animator = createAnimatorImpl(json, adapter, callbacks, container);
|
|
5766
|
+
const queued = pending;
|
|
5767
|
+
pending = null;
|
|
5768
|
+
queued == null ? void 0 : queued.forEach((call) => call(animator));
|
|
5480
5769
|
} else {
|
|
5481
|
-
console.error(
|
|
5770
|
+
console.error('createAnimator: invalid animation document format at "' + src + '"');
|
|
5482
5771
|
}
|
|
5772
|
+
}).catch((err) => {
|
|
5773
|
+
pending = null;
|
|
5774
|
+
console.error('createAnimator: failed to load "' + src + '"', err);
|
|
5483
5775
|
});
|
|
5484
5776
|
return {
|
|
5485
5777
|
"isReady": () => !!animator,
|
|
5486
5778
|
"getRootElement": () => animator ? animator.getRootElement() : null,
|
|
5487
5779
|
"isPlaying": () => (animator == null ? void 0 : animator.isPlaying()) || false,
|
|
5488
5780
|
"play": () => {
|
|
5489
|
-
|
|
5781
|
+
enqueue((api) => api.play());
|
|
5490
5782
|
},
|
|
5491
5783
|
"pause": () => {
|
|
5492
|
-
|
|
5784
|
+
enqueue((api) => api.pause());
|
|
5493
5785
|
},
|
|
5494
5786
|
"cancel": () => {
|
|
5495
|
-
|
|
5787
|
+
enqueue((api) => api.cancel());
|
|
5496
5788
|
},
|
|
5497
5789
|
"finish": () => {
|
|
5498
|
-
|
|
5790
|
+
enqueue((api) => api.finish());
|
|
5499
5791
|
},
|
|
5500
5792
|
"setPlaybackRate": (rate) => {
|
|
5501
|
-
|
|
5793
|
+
enqueue((api) => api.setPlaybackRate(rate));
|
|
5502
5794
|
},
|
|
5503
|
-
"getCurrentTime": () =>
|
|
5795
|
+
"getCurrentTime": () => animator ? animator.getCurrentTime() : null,
|
|
5504
5796
|
"setCurrentTime": (time) => {
|
|
5505
|
-
|
|
5797
|
+
enqueue((api) => api.setCurrentTime(time));
|
|
5506
5798
|
},
|
|
5507
5799
|
"destroy": () => {
|
|
5800
|
+
destroyed = true;
|
|
5801
|
+
pending = null;
|
|
5508
5802
|
animator == null ? void 0 : animator.destroy();
|
|
5509
5803
|
}
|
|
5510
5804
|
};
|
|
@@ -5785,6 +6079,7 @@ export {
|
|
|
5785
6079
|
createAnimatorImpl,
|
|
5786
6080
|
createBasicFrameLoopAnimator,
|
|
5787
6081
|
createFrameLoopAnimator,
|
|
6082
|
+
createPathSampler,
|
|
5788
6083
|
createWebApiAnimator,
|
|
5789
6084
|
describeSchema,
|
|
5790
6085
|
diffInEffect,
|
|
@@ -5799,6 +6094,7 @@ export {
|
|
|
5799
6094
|
isPxElementFileFormat,
|
|
5800
6095
|
isPxElementFileFormatDeep,
|
|
5801
6096
|
jsonElementFactory,
|
|
6097
|
+
layoutGlyphTextChars,
|
|
5802
6098
|
loadTagAnimators,
|
|
5803
6099
|
materialiseAllInTree,
|
|
5804
6100
|
materialiseAnimatedUseInstances,
|