@pixodesk/svg-animator-web 1.0.18 → 1.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -83,8 +83,8 @@ __export(index_exports, {
83
83
  PxRetimeEffectSchema: () => PxRetimeEffectSchema,
84
84
  PxStrokeGradientEffectSchema: () => PxStrokeGradientEffectSchema,
85
85
  PxSvgNodeExtra: () => PxSvgNodeExtra,
86
- PxTextAlongPathEffectSchema: () => PxTextAlongPathEffectSchema,
87
86
  PxTextEffectSchema: () => PxTextEffectSchema,
87
+ PxTextPathEffectSchema: () => PxTextPathEffectSchema,
88
88
  PxTransformPartsSchema: () => PxTransformPartsSchema,
89
89
  PxTransformValueSchema: () => PxTransformValueSchema,
90
90
  PxTransformationEffectSchema: () => PxTransformationEffectSchema,
@@ -104,6 +104,7 @@ __export(index_exports, {
104
104
  describeSchema: () => describeSchema,
105
105
  diffInEffect: () => diffInEffect,
106
106
  evaluateMotionPathSegment: () => evaluateMotionPathSegment,
107
+ extendedPathForBrowser: () => extendedPathForBrowser,
107
108
  generateNewIds: () => generateNewIds,
108
109
  getAnimatorConfig: () => getAnimatorConfig,
109
110
  getBindings: () => getBindings,
@@ -129,6 +130,7 @@ __export(index_exports, {
129
130
  renderNode: () => renderNode,
130
131
  schemaKeys: () => schemaKeys,
131
132
  setupAnimationTriggers: () => setupAnimationTriggers,
133
+ shiftAnimatable: () => shiftAnimatable,
132
134
  toRGBA: () => toRGBA,
133
135
  validateNodeEffects: () => validateNodeEffects,
134
136
  visualModelAt: () => visualModelAt
@@ -1139,8 +1141,9 @@ var PxFillGradientEffectSchema = implementsInterface()(px.object({
1139
1141
  gradientTransform: px.string().optional()
1140
1142
  }));
1141
1143
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
1142
- var PxTextAlongPathEffectSchema = implementsInterface()(px.object({
1143
- href: px.string(),
1144
+ var PxTextPathEffectSchema = implementsInterface()(px.object({
1145
+ path: px.string(),
1146
+ pathOverflow: px.string().optional(),
1144
1147
  lengthAdjust: px.string().optional(),
1145
1148
  method: px.string().optional(),
1146
1149
  spacing: px.string().optional(),
@@ -1159,7 +1162,7 @@ var PxEffectsSchema = implementsInterface()(px.object({
1159
1162
  isCombinedShape: px.boolean().optional(),
1160
1163
  fillGradient: PxFillGradientEffectSchema.optional(),
1161
1164
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
1162
- textAlongPath: PxTextAlongPathEffectSchema.optional(),
1165
+ textPath: PxTextPathEffectSchema.optional(),
1163
1166
  text: PxTextEffectSchema.optional()
1164
1167
  }));
1165
1168
  function validateNodeEffects(root, opts) {
@@ -2032,103 +2035,6 @@ function remapKeyframeTimesOnly(node, start, stretch) {
2032
2035
  }
2033
2036
  }
2034
2037
 
2035
- // src/effects/textAlongPathEffect.ts
2036
- function applyTextAlongPathEffect(node, fx, _ctx) {
2037
- var _a;
2038
- if (!fx) return node;
2039
- const href = typeof fx.href === "string" && !fx.href.startsWith("#") ? "#" + fx.href : fx.href;
2040
- const textPath = {
2041
- type: "textPath",
2042
- href,
2043
- children: (_a = node.children) != null ? _a : []
2044
- };
2045
- if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
2046
- if (fx.method !== void 0) textPath.method = fx.method;
2047
- if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
2048
- applyAnimatableNumber(textPath, "startOffset", fx.startOffset);
2049
- applyAnimatableNumber(textPath, "textLength", fx.textLength);
2050
- node.children = [textPath];
2051
- return node;
2052
- }
2053
- function applyAnimatableNumber(node, attrName, raw) {
2054
- if (raw === void 0 || raw === null) return;
2055
- if (typeof raw === "number") {
2056
- node[attrName] = String(raw);
2057
- return;
2058
- }
2059
- if (typeof raw === "object" && raw !== null) {
2060
- const obj = raw;
2061
- if (Array.isArray(obj.keyframes)) {
2062
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
2063
- const animate = __spreadValues({}, prevAnimate || {});
2064
- const block = { keyframes: obj.keyframes };
2065
- if (obj.loop !== void 0) block.loop = obj.loop;
2066
- animate[attrName] = block;
2067
- node.animate = animate;
2068
- return;
2069
- }
2070
- if (typeof obj.value === "number") {
2071
- node[attrName] = String(obj.value);
2072
- return;
2073
- }
2074
- }
2075
- }
2076
-
2077
- // src/effects/elementFactory.ts
2078
- var jsonElementFactory = (type, props, children) => {
2079
- const node = { type };
2080
- for (const k in props) if (props[k] !== void 0) node[k] = props[k];
2081
- const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
2082
- if (arr.length) node.children = arr;
2083
- return node;
2084
- };
2085
-
2086
- // src/effects/glyphPathBake.ts
2087
- function fmt(v, decimals) {
2088
- return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
2089
- }
2090
- function pack(nums, decimals) {
2091
- let s = "";
2092
- for (let i = 0; i < nums.length; i++) {
2093
- const str2 = fmt(nums[i], decimals);
2094
- if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
2095
- s += str2;
2096
- }
2097
- return s;
2098
- }
2099
- function apply(m, x, y) {
2100
- return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
2101
- }
2102
- var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
2103
- function transformPathData(d, m, decimals = 2) {
2104
- const tokens = [];
2105
- let match;
2106
- TOKEN_RE.lastIndex = 0;
2107
- while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
2108
- let out = "";
2109
- let i = 0;
2110
- const num2 = () => parseFloat(tokens[i++]);
2111
- while (i < tokens.length) {
2112
- const cmd = tokens[i++];
2113
- if (cmd === "M" || cmd === "L") {
2114
- const [x, y] = apply(m, num2(), num2());
2115
- out += cmd + pack([x, y], decimals);
2116
- } else if (cmd === "C") {
2117
- const [x1, y1] = apply(m, num2(), num2());
2118
- const [x2, y2] = apply(m, num2(), num2());
2119
- const [x, y] = apply(m, num2(), num2());
2120
- out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
2121
- } else if (cmd === "Q") {
2122
- const [x1, y1] = apply(m, num2(), num2());
2123
- const [x, y] = apply(m, num2(), num2());
2124
- out += "Q" + pack([x1, y1, x, y], decimals);
2125
- } else if (cmd === "Z" || cmd === "z") {
2126
- out += "Z";
2127
- }
2128
- }
2129
- return out;
2130
- }
2131
-
2132
2038
  // src/PxAnimatorUtil.ts
2133
2039
  function bezierToSvgPath(path) {
2134
2040
  var _a, _b, _c, _d;
@@ -2673,6 +2579,7 @@ function createPathSampler(d) {
2673
2579
  };
2674
2580
  return {
2675
2581
  totalLength,
2582
+ closed,
2676
2583
  sampleAtDistance(dist) {
2677
2584
  if (!closed && (dist < 0 || dist > totalLength)) {
2678
2585
  const edge = dist < 0 ? 0 : totalLength;
@@ -2685,6 +2592,173 @@ function createPathSampler(d) {
2685
2592
  };
2686
2593
  }
2687
2594
 
2595
+ // src/effects/textPathEffect.ts
2596
+ var EXTEND_MARGIN_FRAC = 0.15;
2597
+ function numRange(v) {
2598
+ if (typeof v === "number") return { min: v, max: v };
2599
+ if (v && typeof v === "object") {
2600
+ const o = v;
2601
+ if (typeof o.value === "number") return { min: o.value, max: o.value };
2602
+ if (Array.isArray(o.keyframes) && o.keyframes.length) {
2603
+ const vals = o.keyframes.map((k) => Number(k.value) || 0);
2604
+ return { min: Math.min(...vals), max: Math.max(...vals) };
2605
+ }
2606
+ }
2607
+ return { min: 0, max: 0 };
2608
+ }
2609
+ function estimateTextAdvance(node) {
2610
+ let chars = 0, maxFont = 16;
2611
+ const walk = (el) => {
2612
+ var _a, _b;
2613
+ const fs = parseFloat(String((_a = el.fontSize) != null ? _a : "")) || 0;
2614
+ if (fs) maxFont = Math.max(maxFont, fs);
2615
+ const t = (_b = el.text) != null ? _b : el.textContent;
2616
+ if (typeof t === "string") chars += t.length;
2617
+ if (el.children) for (const c of el.children) walk(c);
2618
+ };
2619
+ walk(node);
2620
+ return chars * maxFont;
2621
+ }
2622
+ var r3 = (n) => Math.round(n * 1e3) / 1e3;
2623
+ function shiftAnimatable(v, by) {
2624
+ if (!by || v === void 0 || v === null) return v;
2625
+ if (typeof v === "number") return v + by;
2626
+ const o = v;
2627
+ if (typeof o.value === "number") return __spreadProps(__spreadValues({}, o), { value: o.value + by });
2628
+ if (Array.isArray(o.keyframes)) return __spreadProps(__spreadValues({}, o), { keyframes: o.keyframes.map((k) => __spreadProps(__spreadValues({}, k), { value: (Number(k.value) || 0) + by })) });
2629
+ return v;
2630
+ }
2631
+ function extendedPathForBrowser(pathD, opts) {
2632
+ var _a;
2633
+ if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
2634
+ const sampler = createPathSampler(pathD);
2635
+ if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
2636
+ const L = sampler.totalLength;
2637
+ const margin = EXTEND_MARGIN_FRAC * L;
2638
+ const so = numRange(opts.startOffset);
2639
+ const runWidth = numRange(opts.textLength).max || ((_a = opts.advance) != null ? _a : 0);
2640
+ const startOverflow = Math.max(0, -so.min);
2641
+ const endOverflow = Math.max(0, so.max + runWidth - L);
2642
+ const startExt = startOverflow > 0 ? startOverflow + margin : 0;
2643
+ const endExt = endOverflow > 0 ? endOverflow + margin : 0;
2644
+ if (endExt <= 0 && startExt <= 0) return { d: pathD, startShift: 0 };
2645
+ const s = sampler.sampleAtDistance(0);
2646
+ const e = sampler.sampleAtDistance(L);
2647
+ let d = pathD;
2648
+ if (startExt > 0) {
2649
+ const sx = s.x - Math.cos(s.angle) * startExt, sy = s.y - Math.sin(s.angle) * startExt;
2650
+ const rest = pathD.replace(/^\s*[Mm]\s*-?[\d.]+[\s,]+-?[\d.]+/, "");
2651
+ d = "M" + r3(sx) + "," + r3(sy) + "L" + r3(s.x) + "," + r3(s.y) + rest;
2652
+ }
2653
+ if (endExt > 0) {
2654
+ const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;
2655
+ d += "L" + r3(ex) + "," + r3(ey);
2656
+ }
2657
+ return { d, startShift: startExt };
2658
+ }
2659
+ function applyTextPathEffect(node, fx, ctx) {
2660
+ var _a;
2661
+ if (!fx || typeof fx.path !== "string" || !fx.path) return node;
2662
+ const pathId = genId(ctx, "tpath");
2663
+ const { d, startShift } = extendedPathForBrowser(fx.path, {
2664
+ pathOverflow: fx.pathOverflow,
2665
+ startOffset: fx.startOffset,
2666
+ textLength: fx.textLength,
2667
+ advance: estimateTextAdvance(node)
2668
+ });
2669
+ ctx.defs.push({ type: "path", id: pathId, d });
2670
+ const textPath = {
2671
+ type: "textPath",
2672
+ href: "#" + pathId,
2673
+ children: (_a = node.children) != null ? _a : []
2674
+ };
2675
+ if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
2676
+ if (fx.method !== void 0) textPath.method = fx.method;
2677
+ if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
2678
+ applyAnimatableNumber(textPath, "startOffset", shiftAnimatable(fx.startOffset, startShift));
2679
+ applyAnimatableNumber(textPath, "textLength", fx.textLength);
2680
+ node.children = [textPath];
2681
+ return node;
2682
+ }
2683
+ function applyAnimatableNumber(node, attrName, raw) {
2684
+ if (raw === void 0 || raw === null) return;
2685
+ if (typeof raw === "number") {
2686
+ node[attrName] = String(raw);
2687
+ return;
2688
+ }
2689
+ if (typeof raw === "object" && raw !== null) {
2690
+ const obj = raw;
2691
+ if (Array.isArray(obj.keyframes)) {
2692
+ const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
2693
+ const animate = __spreadValues({}, prevAnimate || {});
2694
+ const block = { keyframes: obj.keyframes };
2695
+ if (obj.loop !== void 0) block.loop = obj.loop;
2696
+ animate[attrName] = block;
2697
+ node.animate = animate;
2698
+ return;
2699
+ }
2700
+ if (typeof obj.value === "number") {
2701
+ node[attrName] = String(obj.value);
2702
+ return;
2703
+ }
2704
+ }
2705
+ }
2706
+
2707
+ // src/effects/elementFactory.ts
2708
+ var jsonElementFactory = (type, props, children) => {
2709
+ const node = { type };
2710
+ for (const k in props) if (props[k] !== void 0) node[k] = props[k];
2711
+ const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
2712
+ if (arr.length) node.children = arr;
2713
+ return node;
2714
+ };
2715
+
2716
+ // src/effects/glyphPathBake.ts
2717
+ function fmt(v, decimals) {
2718
+ return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
2719
+ }
2720
+ function pack(nums, decimals) {
2721
+ let s = "";
2722
+ for (let i = 0; i < nums.length; i++) {
2723
+ const str2 = fmt(nums[i], decimals);
2724
+ if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
2725
+ s += str2;
2726
+ }
2727
+ return s;
2728
+ }
2729
+ function apply(m, x, y) {
2730
+ return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
2731
+ }
2732
+ var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
2733
+ function transformPathData(d, m, decimals = 2) {
2734
+ const tokens = [];
2735
+ let match;
2736
+ TOKEN_RE.lastIndex = 0;
2737
+ while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
2738
+ let out = "";
2739
+ let i = 0;
2740
+ const num2 = () => parseFloat(tokens[i++]);
2741
+ while (i < tokens.length) {
2742
+ const cmd = tokens[i++];
2743
+ if (cmd === "M" || cmd === "L") {
2744
+ const [x, y] = apply(m, num2(), num2());
2745
+ out += cmd + pack([x, y], decimals);
2746
+ } else if (cmd === "C") {
2747
+ const [x1, y1] = apply(m, num2(), num2());
2748
+ const [x2, y2] = apply(m, num2(), num2());
2749
+ const [x, y] = apply(m, num2(), num2());
2750
+ out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
2751
+ } else if (cmd === "Q") {
2752
+ const [x1, y1] = apply(m, num2(), num2());
2753
+ const [x, y] = apply(m, num2(), num2());
2754
+ out += "Q" + pack([x1, y1, x, y], decimals);
2755
+ } else if (cmd === "Z" || cmd === "z") {
2756
+ out += "Z";
2757
+ }
2758
+ }
2759
+ return out;
2760
+ }
2761
+
2688
2762
  // src/effects/textGlyphsEffect.ts
2689
2763
  var DEFAULT_FONT_SIZE = 16;
2690
2764
  var TEXT_ATTR_KEYS = [
@@ -2846,7 +2920,7 @@ function alongAffine(sampler, dist, scale, widthEm) {
2846
2920
  const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;
2847
2921
  return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw, y - scale * sin * hw];
2848
2922
  }
2849
- function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength) {
2923
+ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
2850
2924
  var _a;
2851
2925
  const { glyphs, create = jsonElementFactory, warnings } = opts;
2852
2926
  const sampler = pathD ? createPathSampler(pathD) : null;
@@ -2861,12 +2935,17 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
2861
2935
  const k = textLength / width;
2862
2936
  for (const c of cells) c.midBase *= k;
2863
2937
  }
2938
+ const isClip = pathOverflow === "clip" && !sampler.closed;
2864
2939
  const so = readAnimatable(startOffset);
2865
2940
  if (so.kind === "animated" /* Animated */ && so.keyframes.length >= 2) {
2866
- return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create), create);
2941
+ return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create, isClip), create);
2867
2942
  }
2868
2943
  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;
2869
- const placements = cells.map((c) => ({
2944
+ const placeCells = isClip ? cells.filter((c) => {
2945
+ const d = base + c.midBase;
2946
+ return d >= 0 && d <= sampler.totalLength;
2947
+ }) : cells;
2948
+ const placements = placeCells.map((c) => ({
2870
2949
  glyphD: c.glyphD,
2871
2950
  paint: c.paint,
2872
2951
  m: alongAffine(sampler, base + c.midBase, c.scale, c.widthEm)
@@ -2879,10 +2958,11 @@ function roundN(v, n) {
2879
2958
  const f = __pow(10, n);
2880
2959
  return Math.round(v * f) / f;
2881
2960
  }
2882
- function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create) {
2961
+ function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create, isClip) {
2883
2962
  const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);
2884
2963
  const timeOf = (kf) => Number(kf.time) || 0;
2885
2964
  const offOf = (kf) => Number(kf.value) || 0;
2965
+ const onPath = (dist) => dist >= 0 && dist <= sampler.totalLength;
2886
2966
  const out = [];
2887
2967
  for (const c of cells) {
2888
2968
  const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
@@ -2897,19 +2977,31 @@ function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create) {
2897
2977
  }
2898
2978
  };
2899
2979
  };
2900
- const kfs = [sampleKf(offOf(sokfs[0]) + c.midBase, timeOf(sokfs[0]))];
2980
+ const kfs = [];
2981
+ const opKfs = [];
2982
+ const pushKf = (dist, time) => {
2983
+ kfs.push(sampleKf(dist, time));
2984
+ if (isClip) opKfs.push({ time, value: onPath(dist) ? 1 : 0 });
2985
+ };
2986
+ pushKf(offOf(sokfs[0]) + c.midBase, timeOf(sokfs[0]));
2901
2987
  for (let k = 1; k < sokfs.length; k++) {
2902
2988
  const t0 = timeOf(sokfs[k - 1]), t1 = timeOf(sokfs[k]);
2903
2989
  const o0 = offOf(sokfs[k - 1]), o1 = offOf(sokfs[k]);
2904
2990
  const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(o1 - o0) / step)));
2905
2991
  for (let s = 1; s <= n; s++) {
2906
2992
  const f = s / n;
2907
- kfs.push(sampleKf(o0 + f * (o1 - o0) + c.midBase, t0 + f * (t1 - t0)));
2993
+ pushKf(o0 + f * (o1 - o0) + c.midBase, t0 + f * (t1 - t0));
2908
2994
  }
2909
2995
  }
2910
2996
  const transform = { keyframes: kfs };
2911
2997
  if (loop !== void 0) transform.loop = loop;
2912
- out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate: { transform } }), []));
2998
+ const animate = { transform };
2999
+ if (isClip && opKfs.some((k) => k.value === 0)) {
3000
+ const op = { keyframes: opKfs };
3001
+ if (loop !== void 0) op.loop = loop;
3002
+ animate.opacity = op;
3003
+ }
3004
+ out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate }), []));
2913
3005
  }
2914
3006
  return out;
2915
3007
  }
@@ -2953,7 +3045,7 @@ function toGroup(node, children, create) {
2953
3045
  return create("g", gProps, children);
2954
3046
  }
2955
3047
  function materialiseGlyphText(node, opts) {
2956
- if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength);
3048
+ if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
2957
3049
  return materialiseGlyphTextHorizontal(node, opts);
2958
3050
  }
2959
3051
  function applyTextGlyphsEffect(node, fx, ctx) {
@@ -2964,12 +3056,12 @@ function applyTextGlyphsEffect(node, fx, ctx) {
2964
3056
  }
2965
3057
  return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
2966
3058
  }
2967
- function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength) {
3059
+ function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
2968
3060
  if (!ctx.glyphs) {
2969
3061
  ctx.warnings.push("textGlyphs: no definitions.glyphs");
2970
3062
  return null;
2971
3063
  }
2972
- return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength);
3064
+ return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
2973
3065
  }
2974
3066
 
2975
3067
  // src/PxMotionPath.ts
@@ -4375,18 +4467,17 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
4375
4467
  const originalId = typeof node.id === "string" ? node.id : void 0;
4376
4468
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
4377
4469
  if (!fx && !innerIdForContentRef) return node;
4378
- const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textAlongPath, text } = fx != null ? fx : {};
4470
+ const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
4379
4471
  const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
4380
4472
  if (fx) delete node.effects;
4381
4473
  let n = node;
4382
4474
  let consumedByGlyphs = false;
4383
4475
  if (text == null ? void 0 : text.useGlyphs) {
4384
- if (textAlongPath) {
4385
- const pathNode = typeof textAlongPath.href === "string" ? ctx.idMap.get(textAlongPath.href) : void 0;
4386
- const pathD = pathNode && typeof pathNode.d === "string" ? pathNode.d : void 0;
4387
- const rawTL = textAlongPath.textLength;
4476
+ if (textPath) {
4477
+ const pathD = typeof textPath.path === "string" ? textPath.path : void 0;
4478
+ const rawTL = textPath.textLength;
4388
4479
  const textLength = typeof rawTL === "number" ? rawTL : rawTL && typeof rawTL === "object" ? typeof rawTL.value === "number" ? rawTL.value : Array.isArray(rawTL.keyframes) && rawTL.keyframes.length ? Number((_a = rawTL.keyframes[0]) == null ? void 0 : _a.value) : void 0 : void 0;
4389
- const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textAlongPath.startOffset, textLength);
4480
+ const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textLength, textPath.pathOverflow);
4390
4481
  if (glyphed) {
4391
4482
  n = glyphed;
4392
4483
  consumedByGlyphs = true;
@@ -4396,7 +4487,7 @@ function applyPlayerEffects_exceptRetime(node, ctx) {
4396
4487
  consumedByGlyphs = true;
4397
4488
  }
4398
4489
  }
4399
- if (!consumedByGlyphs) n = applyTextAlongPathEffect(n, textAlongPath, ctx);
4490
+ if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
4400
4491
  n = applyFillGradientEffect(n, fillGradient, ctx);
4401
4492
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
4402
4493
  n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
@@ -5784,8 +5875,8 @@ function subtractMultiset(a, b) {
5784
5875
  PxRetimeEffectSchema,
5785
5876
  PxStrokeGradientEffectSchema,
5786
5877
  PxSvgNodeExtra,
5787
- PxTextAlongPathEffectSchema,
5788
5878
  PxTextEffectSchema,
5879
+ PxTextPathEffectSchema,
5789
5880
  PxTransformPartsSchema,
5790
5881
  PxTransformValueSchema,
5791
5882
  PxTransformationEffectSchema,
@@ -5805,6 +5896,7 @@ function subtractMultiset(a, b) {
5805
5896
  describeSchema,
5806
5897
  diffInEffect,
5807
5898
  evaluateMotionPathSegment,
5899
+ extendedPathForBrowser,
5808
5900
  generateNewIds,
5809
5901
  getAnimatorConfig,
5810
5902
  getBindings,
@@ -5830,6 +5922,7 @@ function subtractMultiset(a, b) {
5830
5922
  renderNode,
5831
5923
  schemaKeys,
5832
5924
  setupAnimationTriggers,
5925
+ shiftAnimatable,
5833
5926
  toRGBA,
5834
5927
  validateNodeEffects,
5835
5928
  visualModelAt