@pixodesk/svg-animator-react 1.0.17 → 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.umd.js +686 -63
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.umd.js
CHANGED
|
@@ -1770,6 +1770,7 @@ var PixodeskAnimatorReact = (() => {
|
|
|
1770
1770
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
1771
1771
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
1772
1772
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
1773
|
+
var __pow = Math.pow;
|
|
1773
1774
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1774
1775
|
var __spreadValues = (a, b) => {
|
|
1775
1776
|
for (var prop in b || (b = {}))
|
|
@@ -2650,10 +2651,22 @@ var PixodeskAnimatorReact = (() => {
|
|
|
2650
2651
|
outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
|
|
2651
2652
|
scrollIntoViewThreshold: px.number().optional()
|
|
2652
2653
|
}));
|
|
2654
|
+
var PxGlyphSchema = implementsInterface()(px.object({
|
|
2655
|
+
width: px.number(),
|
|
2656
|
+
d: px.string()
|
|
2657
|
+
}));
|
|
2658
|
+
var PxGlyphFontSchema = implementsInterface()(px.object({
|
|
2659
|
+
fFamily: px.string(),
|
|
2660
|
+
style: px.string(),
|
|
2661
|
+
ascent: px.number(),
|
|
2662
|
+
unitsPerEm: px.number(),
|
|
2663
|
+
glyphs: px.record(PxGlyphSchema)
|
|
2664
|
+
}));
|
|
2653
2665
|
var PxDefsSchema = implementsInterface()(px.object({
|
|
2654
2666
|
easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
|
|
2655
2667
|
animations: px.record(PxAnimationDefinitionSchema).optional(),
|
|
2656
|
-
styles: px.record(px.any()).optional()
|
|
2668
|
+
styles: px.record(px.any()).optional(),
|
|
2669
|
+
glyphs: px.record(PxGlyphFontSchema).optional()
|
|
2657
2670
|
}));
|
|
2658
2671
|
var PxAnimatorConfigSchema = implementsInterface()(px.object({
|
|
2659
2672
|
mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames]).optional(),
|
|
@@ -2757,14 +2770,18 @@ var PixodeskAnimatorReact = (() => {
|
|
|
2757
2770
|
gradientTransform: px.string().optional()
|
|
2758
2771
|
}));
|
|
2759
2772
|
var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
|
|
2760
|
-
var
|
|
2761
|
-
|
|
2773
|
+
var PxTextPathEffectSchema = implementsInterface()(px.object({
|
|
2774
|
+
path: px.string(),
|
|
2775
|
+
pathOverflow: px.string().optional(),
|
|
2762
2776
|
lengthAdjust: px.string().optional(),
|
|
2763
2777
|
method: px.string().optional(),
|
|
2764
2778
|
spacing: px.string().optional(),
|
|
2765
2779
|
startOffset: PxAnimatableNumberSchema.optional(),
|
|
2766
2780
|
textLength: PxAnimatableNumberSchema.optional()
|
|
2767
2781
|
}));
|
|
2782
|
+
var PxTextEffectSchema = implementsInterface()(px.object({
|
|
2783
|
+
useGlyphs: px.boolean().optional()
|
|
2784
|
+
}));
|
|
2768
2785
|
var PxEffectsSchema = implementsInterface()(px.object({
|
|
2769
2786
|
transformation: PxTransformationEffectSchema.optional(),
|
|
2770
2787
|
repeater: PxRepeaterEffectSchema.optional(),
|
|
@@ -2774,7 +2791,8 @@ var PixodeskAnimatorReact = (() => {
|
|
|
2774
2791
|
isCombinedShape: px.boolean().optional(),
|
|
2775
2792
|
fillGradient: PxFillGradientEffectSchema.optional(),
|
|
2776
2793
|
strokeGradient: PxStrokeGradientEffectSchema.optional(),
|
|
2777
|
-
|
|
2794
|
+
textPath: PxTextPathEffectSchema.optional(),
|
|
2795
|
+
text: PxTextEffectSchema.optional()
|
|
2778
2796
|
}));
|
|
2779
2797
|
function validateNodeEffects(root, opts) {
|
|
2780
2798
|
const warnings = [];
|
|
@@ -3624,46 +3642,6 @@ var PixodeskAnimatorReact = (() => {
|
|
|
3624
3642
|
}
|
|
3625
3643
|
}
|
|
3626
3644
|
}
|
|
3627
|
-
function applyTextAlongPathEffect(node, fx, _ctx) {
|
|
3628
|
-
var _a;
|
|
3629
|
-
if (!fx) return node;
|
|
3630
|
-
const href = typeof fx.href === "string" && !fx.href.startsWith("#") ? "#" + fx.href : fx.href;
|
|
3631
|
-
const textPath = {
|
|
3632
|
-
type: "textPath",
|
|
3633
|
-
href,
|
|
3634
|
-
children: (_a = node.children) != null ? _a : []
|
|
3635
|
-
};
|
|
3636
|
-
if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
|
|
3637
|
-
if (fx.method !== void 0) textPath.method = fx.method;
|
|
3638
|
-
if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
|
|
3639
|
-
applyAnimatableNumber(textPath, "startOffset", fx.startOffset);
|
|
3640
|
-
applyAnimatableNumber(textPath, "textLength", fx.textLength);
|
|
3641
|
-
node.children = [textPath];
|
|
3642
|
-
return node;
|
|
3643
|
-
}
|
|
3644
|
-
function applyAnimatableNumber(node, attrName, raw) {
|
|
3645
|
-
if (raw === void 0 || raw === null) return;
|
|
3646
|
-
if (typeof raw === "number") {
|
|
3647
|
-
node[attrName] = String(raw);
|
|
3648
|
-
return;
|
|
3649
|
-
}
|
|
3650
|
-
if (typeof raw === "object" && raw !== null) {
|
|
3651
|
-
const obj = raw;
|
|
3652
|
-
if (Array.isArray(obj.keyframes)) {
|
|
3653
|
-
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
3654
|
-
const animate = __spreadValues({}, prevAnimate || {});
|
|
3655
|
-
const block = { keyframes: obj.keyframes };
|
|
3656
|
-
if (obj.loop !== void 0) block.loop = obj.loop;
|
|
3657
|
-
animate[attrName] = block;
|
|
3658
|
-
node.animate = animate;
|
|
3659
|
-
return;
|
|
3660
|
-
}
|
|
3661
|
-
if (typeof obj.value === "number") {
|
|
3662
|
-
node[attrName] = String(obj.value);
|
|
3663
|
-
return;
|
|
3664
|
-
}
|
|
3665
|
-
}
|
|
3666
|
-
}
|
|
3667
3645
|
function bezierToSvgPath(path) {
|
|
3668
3646
|
var _a, _b, _c, _d;
|
|
3669
3647
|
const v = path.v;
|
|
@@ -4035,6 +4013,24 @@ var PixodeskAnimatorReact = (() => {
|
|
|
4035
4013
|
}
|
|
4036
4014
|
return { ts, ds };
|
|
4037
4015
|
}
|
|
4016
|
+
function bezier2D_tForDistance(lut, distance) {
|
|
4017
|
+
const { ts, ds } = lut;
|
|
4018
|
+
const last = ds.length - 1;
|
|
4019
|
+
if (distance <= 0) return ts[0];
|
|
4020
|
+
if (distance >= ds[last]) return ts[last];
|
|
4021
|
+
let lo = 1;
|
|
4022
|
+
let hi = last;
|
|
4023
|
+
while (lo < hi) {
|
|
4024
|
+
const mid = lo + hi >>> 1;
|
|
4025
|
+
if (ds[mid] < distance) lo = mid + 1;
|
|
4026
|
+
else hi = mid;
|
|
4027
|
+
}
|
|
4028
|
+
const dPrev = ds[hi - 1];
|
|
4029
|
+
const dCur = ds[hi];
|
|
4030
|
+
const span = dCur - dPrev;
|
|
4031
|
+
const frac = span > 0 ? (distance - dPrev) / span : 0;
|
|
4032
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
4033
|
+
}
|
|
4038
4034
|
function bezier2D_arcAtT(lut, t) {
|
|
4039
4035
|
const { ts, ds } = lut;
|
|
4040
4036
|
const last = ts.length - 1;
|
|
@@ -4056,6 +4052,615 @@ var PixodeskAnimatorReact = (() => {
|
|
|
4056
4052
|
const flipped = [easing[1], easing[0], easing[3], easing[2]];
|
|
4057
4053
|
return cubicBezier(flipped);
|
|
4058
4054
|
}
|
|
4055
|
+
var LUT_STEPS = 48;
|
|
4056
|
+
var CMD_RE = /[MmLlHhVvCcSsQqTtAaZz]/;
|
|
4057
|
+
function tokenize(d) {
|
|
4058
|
+
const tokens = [];
|
|
4059
|
+
const re = /([MmLlHhVvCcSsQqTtAaZz])|(-?\d*\.?\d+(?:[eE][-+]?\d+)?)/g;
|
|
4060
|
+
let m;
|
|
4061
|
+
while ((m = re.exec(d)) !== null) tokens.push(m[0]);
|
|
4062
|
+
return tokens;
|
|
4063
|
+
}
|
|
4064
|
+
function quadToCubic(P0, Qc, P3) {
|
|
4065
|
+
return {
|
|
4066
|
+
P1: [P0[0] + 2 / 3 * (Qc[0] - P0[0]), P0[1] + 2 / 3 * (Qc[1] - P0[1])],
|
|
4067
|
+
P2: [P3[0] + 2 / 3 * (Qc[0] - P3[0]), P3[1] + 2 / 3 * (Qc[1] - P3[1])]
|
|
4068
|
+
};
|
|
4069
|
+
}
|
|
4070
|
+
function parseCubics(d) {
|
|
4071
|
+
const tokens = tokenize(d);
|
|
4072
|
+
const segs = [];
|
|
4073
|
+
let i = 0;
|
|
4074
|
+
let cx = 0, cy = 0;
|
|
4075
|
+
let sx = 0, sy = 0;
|
|
4076
|
+
let pcx = 0, pcy = 0;
|
|
4077
|
+
let pqx = 0, pqy = 0;
|
|
4078
|
+
let prevCmd = "";
|
|
4079
|
+
const num2 = () => parseFloat(tokens[i++]);
|
|
4080
|
+
const push = (P1, P2, P3) => {
|
|
4081
|
+
const P0 = [cx, cy];
|
|
4082
|
+
const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);
|
|
4083
|
+
segs.push({ P0, P1, P2, P3, lut, len: lut.ds[lut.ds.length - 1] });
|
|
4084
|
+
cx = P3[0];
|
|
4085
|
+
cy = P3[1];
|
|
4086
|
+
};
|
|
4087
|
+
const pushLine = (x, y) => {
|
|
4088
|
+
push(
|
|
4089
|
+
[cx + (x - cx) / 3, cy + (y - cy) / 3],
|
|
4090
|
+
[cx + 2 * (x - cx) / 3, cy + 2 * (y - cy) / 3],
|
|
4091
|
+
[x, y]
|
|
4092
|
+
);
|
|
4093
|
+
};
|
|
4094
|
+
while (i < tokens.length) {
|
|
4095
|
+
let cmd = tokens[i];
|
|
4096
|
+
if (CMD_RE.test(cmd)) i++;
|
|
4097
|
+
else cmd = prevCmd === "M" ? "L" : prevCmd === "m" ? "l" : prevCmd;
|
|
4098
|
+
const rel = cmd >= "a";
|
|
4099
|
+
const U = cmd.toUpperCase();
|
|
4100
|
+
if (U === "Z") {
|
|
4101
|
+
pushLine(sx, sy);
|
|
4102
|
+
cx = sx;
|
|
4103
|
+
cy = sy;
|
|
4104
|
+
prevCmd = cmd;
|
|
4105
|
+
continue;
|
|
4106
|
+
}
|
|
4107
|
+
if (U === "M") {
|
|
4108
|
+
const x = num2() + (rel ? cx : 0), y = num2() + (rel ? cy : 0);
|
|
4109
|
+
cx = x;
|
|
4110
|
+
cy = y;
|
|
4111
|
+
sx = x;
|
|
4112
|
+
sy = y;
|
|
4113
|
+
prevCmd = cmd;
|
|
4114
|
+
continue;
|
|
4115
|
+
}
|
|
4116
|
+
if (U === "L") {
|
|
4117
|
+
pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
|
|
4118
|
+
} else if (U === "H") {
|
|
4119
|
+
pushLine(num2() + (rel ? cx : 0), cy);
|
|
4120
|
+
} else if (U === "V") {
|
|
4121
|
+
pushLine(cx, num2() + (rel ? cy : 0));
|
|
4122
|
+
} else if (U === "C") {
|
|
4123
|
+
const p1 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
4124
|
+
const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
4125
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
4126
|
+
pcx = p2[0];
|
|
4127
|
+
pcy = p2[1];
|
|
4128
|
+
push(p1, p2, p3);
|
|
4129
|
+
} else if (U === "S") {
|
|
4130
|
+
const smooth = prevCmd.toUpperCase() === "C" || prevCmd.toUpperCase() === "S";
|
|
4131
|
+
const p1 = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];
|
|
4132
|
+
const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
4133
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
4134
|
+
pcx = p2[0];
|
|
4135
|
+
pcy = p2[1];
|
|
4136
|
+
push(p1, p2, p3);
|
|
4137
|
+
} else if (U === "Q") {
|
|
4138
|
+
const qc = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
4139
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
4140
|
+
pqx = qc[0];
|
|
4141
|
+
pqy = qc[1];
|
|
4142
|
+
const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
|
|
4143
|
+
push(P1, P2, p3);
|
|
4144
|
+
} else if (U === "T") {
|
|
4145
|
+
const smooth = prevCmd.toUpperCase() === "Q" || prevCmd.toUpperCase() === "T";
|
|
4146
|
+
const qc = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];
|
|
4147
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
4148
|
+
pqx = qc[0];
|
|
4149
|
+
pqy = qc[1];
|
|
4150
|
+
const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
|
|
4151
|
+
push(P1, P2, p3);
|
|
4152
|
+
} else if (U === "A") {
|
|
4153
|
+
i += 5;
|
|
4154
|
+
pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
|
|
4155
|
+
} else {
|
|
4156
|
+
i++;
|
|
4157
|
+
continue;
|
|
4158
|
+
}
|
|
4159
|
+
prevCmd = cmd;
|
|
4160
|
+
}
|
|
4161
|
+
return segs.length ? segs : null;
|
|
4162
|
+
}
|
|
4163
|
+
function clamp2(v, lo, hi) {
|
|
4164
|
+
return v < lo ? lo : v > hi ? hi : v;
|
|
4165
|
+
}
|
|
4166
|
+
function createPathSampler(d) {
|
|
4167
|
+
const segs = parseCubics(d);
|
|
4168
|
+
if (!segs) return null;
|
|
4169
|
+
const cum = new Float64Array(segs.length + 1);
|
|
4170
|
+
for (let k = 0; k < segs.length; k++) cum[k + 1] = cum[k] + segs[k].len;
|
|
4171
|
+
const totalLength = cum[segs.length];
|
|
4172
|
+
const start = segs[0].P0, end = segs[segs.length - 1].P3;
|
|
4173
|
+
const closed = Math.hypot(end[0] - start[0], end[1] - start[1]) < 1e-3;
|
|
4174
|
+
const sampleOn = (dist) => {
|
|
4175
|
+
let k = 0;
|
|
4176
|
+
while (k < segs.length - 1 && dist > cum[k + 1]) k++;
|
|
4177
|
+
const seg = segs[k];
|
|
4178
|
+
const local = dist - cum[k];
|
|
4179
|
+
const t = seg.len > 0 ? bezier2D_tForDistance(seg.lut, local) : 0;
|
|
4180
|
+
const [x, y] = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
4181
|
+
const [dx, dy] = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
4182
|
+
return { x, y, angle: Math.atan2(dy, dx) };
|
|
4183
|
+
};
|
|
4184
|
+
return {
|
|
4185
|
+
totalLength,
|
|
4186
|
+
closed,
|
|
4187
|
+
sampleAtDistance(dist) {
|
|
4188
|
+
if (!closed && (dist < 0 || dist > totalLength)) {
|
|
4189
|
+
const edge = dist < 0 ? 0 : totalLength;
|
|
4190
|
+
const p = sampleOn(edge);
|
|
4191
|
+
const over = dist - edge;
|
|
4192
|
+
return { x: p.x + Math.cos(p.angle) * over, y: p.y + Math.sin(p.angle) * over, angle: p.angle };
|
|
4193
|
+
}
|
|
4194
|
+
return sampleOn(clamp2(dist, 0, totalLength));
|
|
4195
|
+
}
|
|
4196
|
+
};
|
|
4197
|
+
}
|
|
4198
|
+
var EXTEND_MARGIN_FRAC = 0.15;
|
|
4199
|
+
function numRange(v) {
|
|
4200
|
+
if (typeof v === "number") return { min: v, max: v };
|
|
4201
|
+
if (v && typeof v === "object") {
|
|
4202
|
+
const o = v;
|
|
4203
|
+
if (typeof o.value === "number") return { min: o.value, max: o.value };
|
|
4204
|
+
if (Array.isArray(o.keyframes) && o.keyframes.length) {
|
|
4205
|
+
const vals = o.keyframes.map((k) => Number(k.value) || 0);
|
|
4206
|
+
return { min: Math.min(...vals), max: Math.max(...vals) };
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
return { min: 0, max: 0 };
|
|
4210
|
+
}
|
|
4211
|
+
function estimateTextAdvance(node) {
|
|
4212
|
+
let chars = 0, maxFont = 16;
|
|
4213
|
+
const walk = (el) => {
|
|
4214
|
+
var _a, _b;
|
|
4215
|
+
const fs = parseFloat(String((_a = el.fontSize) != null ? _a : "")) || 0;
|
|
4216
|
+
if (fs) maxFont = Math.max(maxFont, fs);
|
|
4217
|
+
const t = (_b = el.text) != null ? _b : el.textContent;
|
|
4218
|
+
if (typeof t === "string") chars += t.length;
|
|
4219
|
+
if (el.children) for (const c of el.children) walk(c);
|
|
4220
|
+
};
|
|
4221
|
+
walk(node);
|
|
4222
|
+
return chars * maxFont;
|
|
4223
|
+
}
|
|
4224
|
+
var r3 = (n) => Math.round(n * 1e3) / 1e3;
|
|
4225
|
+
function shiftAnimatable(v, by) {
|
|
4226
|
+
if (!by || v === void 0 || v === null) return v;
|
|
4227
|
+
if (typeof v === "number") return v + by;
|
|
4228
|
+
const o = v;
|
|
4229
|
+
if (typeof o.value === "number") return __spreadProps(__spreadValues({}, o), { value: o.value + by });
|
|
4230
|
+
if (Array.isArray(o.keyframes)) return __spreadProps(__spreadValues({}, o), { keyframes: o.keyframes.map((k) => __spreadProps(__spreadValues({}, k), { value: (Number(k.value) || 0) + by })) });
|
|
4231
|
+
return v;
|
|
4232
|
+
}
|
|
4233
|
+
function extendedPathForBrowser(pathD, opts) {
|
|
4234
|
+
var _a;
|
|
4235
|
+
if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
|
|
4236
|
+
const sampler = createPathSampler(pathD);
|
|
4237
|
+
if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
|
|
4238
|
+
const L = sampler.totalLength;
|
|
4239
|
+
const margin = EXTEND_MARGIN_FRAC * L;
|
|
4240
|
+
const so = numRange(opts.startOffset);
|
|
4241
|
+
const runWidth = numRange(opts.textLength).max || ((_a = opts.advance) != null ? _a : 0);
|
|
4242
|
+
const startOverflow = Math.max(0, -so.min);
|
|
4243
|
+
const endOverflow = Math.max(0, so.max + runWidth - L);
|
|
4244
|
+
const startExt = startOverflow > 0 ? startOverflow + margin : 0;
|
|
4245
|
+
const endExt = endOverflow > 0 ? endOverflow + margin : 0;
|
|
4246
|
+
if (endExt <= 0 && startExt <= 0) return { d: pathD, startShift: 0 };
|
|
4247
|
+
const s = sampler.sampleAtDistance(0);
|
|
4248
|
+
const e = sampler.sampleAtDistance(L);
|
|
4249
|
+
let d = pathD;
|
|
4250
|
+
if (startExt > 0) {
|
|
4251
|
+
const sx = s.x - Math.cos(s.angle) * startExt, sy = s.y - Math.sin(s.angle) * startExt;
|
|
4252
|
+
const rest = pathD.replace(/^\s*[Mm]\s*-?[\d.]+[\s,]+-?[\d.]+/, "");
|
|
4253
|
+
d = "M" + r3(sx) + "," + r3(sy) + "L" + r3(s.x) + "," + r3(s.y) + rest;
|
|
4254
|
+
}
|
|
4255
|
+
if (endExt > 0) {
|
|
4256
|
+
const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;
|
|
4257
|
+
d += "L" + r3(ex) + "," + r3(ey);
|
|
4258
|
+
}
|
|
4259
|
+
return { d, startShift: startExt };
|
|
4260
|
+
}
|
|
4261
|
+
function applyTextPathEffect(node, fx, ctx) {
|
|
4262
|
+
var _a;
|
|
4263
|
+
if (!fx || typeof fx.path !== "string" || !fx.path) return node;
|
|
4264
|
+
const pathId = genId(ctx, "tpath");
|
|
4265
|
+
const { d, startShift } = extendedPathForBrowser(fx.path, {
|
|
4266
|
+
pathOverflow: fx.pathOverflow,
|
|
4267
|
+
startOffset: fx.startOffset,
|
|
4268
|
+
textLength: fx.textLength,
|
|
4269
|
+
advance: estimateTextAdvance(node)
|
|
4270
|
+
});
|
|
4271
|
+
ctx.defs.push({ type: "path", id: pathId, d });
|
|
4272
|
+
const textPath = {
|
|
4273
|
+
type: "textPath",
|
|
4274
|
+
href: "#" + pathId,
|
|
4275
|
+
children: (_a = node.children) != null ? _a : []
|
|
4276
|
+
};
|
|
4277
|
+
if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
|
|
4278
|
+
if (fx.method !== void 0) textPath.method = fx.method;
|
|
4279
|
+
if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
|
|
4280
|
+
applyAnimatableNumber(textPath, "startOffset", shiftAnimatable(fx.startOffset, startShift));
|
|
4281
|
+
applyAnimatableNumber(textPath, "textLength", fx.textLength);
|
|
4282
|
+
node.children = [textPath];
|
|
4283
|
+
return node;
|
|
4284
|
+
}
|
|
4285
|
+
function applyAnimatableNumber(node, attrName, raw) {
|
|
4286
|
+
if (raw === void 0 || raw === null) return;
|
|
4287
|
+
if (typeof raw === "number") {
|
|
4288
|
+
node[attrName] = String(raw);
|
|
4289
|
+
return;
|
|
4290
|
+
}
|
|
4291
|
+
if (typeof raw === "object" && raw !== null) {
|
|
4292
|
+
const obj = raw;
|
|
4293
|
+
if (Array.isArray(obj.keyframes)) {
|
|
4294
|
+
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
4295
|
+
const animate = __spreadValues({}, prevAnimate || {});
|
|
4296
|
+
const block = { keyframes: obj.keyframes };
|
|
4297
|
+
if (obj.loop !== void 0) block.loop = obj.loop;
|
|
4298
|
+
animate[attrName] = block;
|
|
4299
|
+
node.animate = animate;
|
|
4300
|
+
return;
|
|
4301
|
+
}
|
|
4302
|
+
if (typeof obj.value === "number") {
|
|
4303
|
+
node[attrName] = String(obj.value);
|
|
4304
|
+
return;
|
|
4305
|
+
}
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4308
|
+
var jsonElementFactory = (type, props, children) => {
|
|
4309
|
+
const node = { type };
|
|
4310
|
+
for (const k in props) if (props[k] !== void 0) node[k] = props[k];
|
|
4311
|
+
const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
|
|
4312
|
+
if (arr.length) node.children = arr;
|
|
4313
|
+
return node;
|
|
4314
|
+
};
|
|
4315
|
+
function fmt(v, decimals) {
|
|
4316
|
+
return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
|
|
4317
|
+
}
|
|
4318
|
+
function pack(nums, decimals) {
|
|
4319
|
+
let s = "";
|
|
4320
|
+
for (let i = 0; i < nums.length; i++) {
|
|
4321
|
+
const str2 = fmt(nums[i], decimals);
|
|
4322
|
+
if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
|
|
4323
|
+
s += str2;
|
|
4324
|
+
}
|
|
4325
|
+
return s;
|
|
4326
|
+
}
|
|
4327
|
+
function apply(m, x, y) {
|
|
4328
|
+
return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
|
|
4329
|
+
}
|
|
4330
|
+
var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
|
|
4331
|
+
function transformPathData(d, m, decimals = 2) {
|
|
4332
|
+
const tokens = [];
|
|
4333
|
+
let match;
|
|
4334
|
+
TOKEN_RE.lastIndex = 0;
|
|
4335
|
+
while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
|
|
4336
|
+
let out = "";
|
|
4337
|
+
let i = 0;
|
|
4338
|
+
const num2 = () => parseFloat(tokens[i++]);
|
|
4339
|
+
while (i < tokens.length) {
|
|
4340
|
+
const cmd = tokens[i++];
|
|
4341
|
+
if (cmd === "M" || cmd === "L") {
|
|
4342
|
+
const [x, y] = apply(m, num2(), num2());
|
|
4343
|
+
out += cmd + pack([x, y], decimals);
|
|
4344
|
+
} else if (cmd === "C") {
|
|
4345
|
+
const [x1, y1] = apply(m, num2(), num2());
|
|
4346
|
+
const [x2, y2] = apply(m, num2(), num2());
|
|
4347
|
+
const [x, y] = apply(m, num2(), num2());
|
|
4348
|
+
out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
|
|
4349
|
+
} else if (cmd === "Q") {
|
|
4350
|
+
const [x1, y1] = apply(m, num2(), num2());
|
|
4351
|
+
const [x, y] = apply(m, num2(), num2());
|
|
4352
|
+
out += "Q" + pack([x1, y1, x, y], decimals);
|
|
4353
|
+
} else if (cmd === "Z" || cmd === "z") {
|
|
4354
|
+
out += "Z";
|
|
4355
|
+
}
|
|
4356
|
+
}
|
|
4357
|
+
return out;
|
|
4358
|
+
}
|
|
4359
|
+
var DEFAULT_FONT_SIZE = 16;
|
|
4360
|
+
var TEXT_ATTR_KEYS = [
|
|
4361
|
+
"fontFamily",
|
|
4362
|
+
"fontSize",
|
|
4363
|
+
"fontWeight",
|
|
4364
|
+
"fontStyle",
|
|
4365
|
+
"textAnchor",
|
|
4366
|
+
"letterSpacing",
|
|
4367
|
+
"wordSpacing",
|
|
4368
|
+
"textDecoration",
|
|
4369
|
+
"textTransform",
|
|
4370
|
+
"whiteSpace",
|
|
4371
|
+
"x",
|
|
4372
|
+
"y",
|
|
4373
|
+
"dx",
|
|
4374
|
+
"dy",
|
|
4375
|
+
"lengthAdjust",
|
|
4376
|
+
"fill",
|
|
4377
|
+
"stroke",
|
|
4378
|
+
"strokeWidth",
|
|
4379
|
+
"effects",
|
|
4380
|
+
TEXT_ATTR,
|
|
4381
|
+
TEXT_CONTENT_ATTR,
|
|
4382
|
+
"xml:space"
|
|
4383
|
+
];
|
|
4384
|
+
function parseLen(v) {
|
|
4385
|
+
if (typeof v === "number") return v;
|
|
4386
|
+
if (typeof v === "string") {
|
|
4387
|
+
const n = parseFloat(v);
|
|
4388
|
+
return isNaN(n) ? void 0 : n;
|
|
4389
|
+
}
|
|
4390
|
+
return void 0;
|
|
4391
|
+
}
|
|
4392
|
+
function str(v) {
|
|
4393
|
+
return typeof v === "string" ? v : void 0;
|
|
4394
|
+
}
|
|
4395
|
+
function resolveStyle(node, parent) {
|
|
4396
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
4397
|
+
return {
|
|
4398
|
+
fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
|
|
4399
|
+
fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
|
|
4400
|
+
fill: (_c = node.fill) != null ? _c : parent.fill,
|
|
4401
|
+
stroke: (_d = node.stroke) != null ? _d : parent.stroke,
|
|
4402
|
+
strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
|
|
4403
|
+
letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
|
|
4404
|
+
wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing
|
|
4405
|
+
};
|
|
4406
|
+
}
|
|
4407
|
+
function rootStyleOf(node) {
|
|
4408
|
+
var _a, _b, _c;
|
|
4409
|
+
return {
|
|
4410
|
+
fontFamily: str(node.fontFamily),
|
|
4411
|
+
fontSize: (_a = parseLen(node.fontSize)) != null ? _a : DEFAULT_FONT_SIZE,
|
|
4412
|
+
fill: node.fill,
|
|
4413
|
+
stroke: node.stroke,
|
|
4414
|
+
strokeWidth: node.strokeWidth,
|
|
4415
|
+
letterSpacing: (_b = parseLen(node.letterSpacing)) != null ? _b : 0,
|
|
4416
|
+
wordSpacing: (_c = parseLen(node.wordSpacing)) != null ? _c : 0
|
|
4417
|
+
};
|
|
4418
|
+
}
|
|
4419
|
+
function paintOf(s) {
|
|
4420
|
+
const p = {};
|
|
4421
|
+
if (s.fill !== void 0) p.fill = s.fill;
|
|
4422
|
+
if (s.stroke !== void 0) p.stroke = s.stroke;
|
|
4423
|
+
if (s.strokeWidth !== void 0) p.strokeWidth = s.strokeWidth;
|
|
4424
|
+
return p;
|
|
4425
|
+
}
|
|
4426
|
+
function glyphFontFor(s, glyphs, soleFont, warnings) {
|
|
4427
|
+
var _a;
|
|
4428
|
+
const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
|
|
4429
|
+
if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a = s.fontFamily) != null ? _a : "") + '"');
|
|
4430
|
+
return gf;
|
|
4431
|
+
}
|
|
4432
|
+
function soleFontOf(glyphs) {
|
|
4433
|
+
const names = Object.keys(glyphs);
|
|
4434
|
+
return names.length === 1 ? glyphs[names[0]] : void 0;
|
|
4435
|
+
}
|
|
4436
|
+
function materialiseGlyphTextHorizontal(node, opts) {
|
|
4437
|
+
var _a, _b, _c, _d;
|
|
4438
|
+
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
4439
|
+
const soleFont = soleFontOf(glyphs);
|
|
4440
|
+
const pen = { x: (_a = parseLen(node.x)) != null ? _a : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
|
|
4441
|
+
const placements = [];
|
|
4442
|
+
const lines = [{ start: pen.x, end: pen.x }];
|
|
4443
|
+
let line = 0;
|
|
4444
|
+
const renderChars = (content, s) => {
|
|
4445
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
4446
|
+
if (!gf) return;
|
|
4447
|
+
const scale = s.fontSize / gf.unitsPerEm;
|
|
4448
|
+
const paint = paintOf(s);
|
|
4449
|
+
for (let i = 0; i < content.length; i++) {
|
|
4450
|
+
const ch = content.charAt(i);
|
|
4451
|
+
const g = gf.glyphs[ch];
|
|
4452
|
+
if (g && g.d) placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
|
|
4453
|
+
pen.x += (g ? g.width : 0) * scale + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
4454
|
+
lines[line].end = pen.x;
|
|
4455
|
+
}
|
|
4456
|
+
};
|
|
4457
|
+
const walk = (el, parentStyle) => {
|
|
4458
|
+
var _a2, _b2, _c2, _d2;
|
|
4459
|
+
const s = resolveStyle(el, parentStyle);
|
|
4460
|
+
const x = parseLen(el.x);
|
|
4461
|
+
const y = parseLen(el.y);
|
|
4462
|
+
if (x !== void 0) {
|
|
4463
|
+
pen.x = x;
|
|
4464
|
+
line = lines.length;
|
|
4465
|
+
lines.push({ start: pen.x, end: pen.x });
|
|
4466
|
+
}
|
|
4467
|
+
if (y !== void 0) pen.y = y;
|
|
4468
|
+
pen.x += (_a2 = parseLen(el.dx)) != null ? _a2 : 0;
|
|
4469
|
+
pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
|
|
4470
|
+
const content = (_c2 = str(el[TEXT_ATTR])) != null ? _c2 : str(el[TEXT_CONTENT_ATTR]);
|
|
4471
|
+
if (content && !((_d2 = el.children) == null ? void 0 : _d2.length)) renderChars(content, s);
|
|
4472
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
4473
|
+
};
|
|
4474
|
+
const rootStyle = rootStyleOf(node);
|
|
4475
|
+
if (node.children) for (const ch of node.children) walk(ch, rootStyle);
|
|
4476
|
+
const rootContent = (_c = str(node[TEXT_ATTR])) != null ? _c : str(node[TEXT_CONTENT_ATTR]);
|
|
4477
|
+
if (rootContent && !((_d = node.children) == null ? void 0 : _d.length)) renderChars(rootContent, rootStyle);
|
|
4478
|
+
const anchor = str(node.textAnchor);
|
|
4479
|
+
if (anchor === "middle" || anchor === "end") {
|
|
4480
|
+
for (const p of placements) {
|
|
4481
|
+
const w = lines[p.line].end - lines[p.line].start;
|
|
4482
|
+
const shift = anchor === "middle" ? -w / 2 : -w;
|
|
4483
|
+
p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];
|
|
4484
|
+
}
|
|
4485
|
+
}
|
|
4486
|
+
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
4487
|
+
}
|
|
4488
|
+
function collectAlongPathCells(node, glyphs, soleFont, warnings) {
|
|
4489
|
+
const cells = [];
|
|
4490
|
+
let adv = 0;
|
|
4491
|
+
const walk = (el, parentStyle) => {
|
|
4492
|
+
var _a, _b;
|
|
4493
|
+
const s = resolveStyle(el, parentStyle);
|
|
4494
|
+
const content = (_a = str(el[TEXT_ATTR])) != null ? _a : str(el[TEXT_CONTENT_ATTR]);
|
|
4495
|
+
if (content && !((_b = el.children) == null ? void 0 : _b.length)) {
|
|
4496
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
4497
|
+
if (gf) {
|
|
4498
|
+
const scale = s.fontSize / gf.unitsPerEm;
|
|
4499
|
+
const paint = paintOf(s);
|
|
4500
|
+
for (let i = 0; i < content.length; i++) {
|
|
4501
|
+
const ch = content.charAt(i);
|
|
4502
|
+
const g = gf.glyphs[ch];
|
|
4503
|
+
const glyphAdv = (g ? g.width : 0) * scale;
|
|
4504
|
+
if (g && g.d) cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
|
|
4505
|
+
adv += glyphAdv + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
4510
|
+
};
|
|
4511
|
+
walk(node, rootStyleOf(node));
|
|
4512
|
+
return { cells, width: adv };
|
|
4513
|
+
}
|
|
4514
|
+
function alongAffine(sampler, dist, scale, widthEm) {
|
|
4515
|
+
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
4516
|
+
const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;
|
|
4517
|
+
return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw, y - scale * sin * hw];
|
|
4518
|
+
}
|
|
4519
|
+
function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
|
|
4520
|
+
var _a;
|
|
4521
|
+
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
4522
|
+
const sampler = pathD ? createPathSampler(pathD) : null;
|
|
4523
|
+
if (!sampler) {
|
|
4524
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry");
|
|
4525
|
+
return null;
|
|
4526
|
+
}
|
|
4527
|
+
const soleFont = soleFontOf(glyphs);
|
|
4528
|
+
const { cells, width } = collectAlongPathCells(node, glyphs, soleFont, warnings);
|
|
4529
|
+
if (!cells.length) return toGroup(node, [], create);
|
|
4530
|
+
if (textLength && textLength > 0 && width > 0) {
|
|
4531
|
+
const k = textLength / width;
|
|
4532
|
+
for (const c of cells) c.midBase *= k;
|
|
4533
|
+
}
|
|
4534
|
+
const isClip = pathOverflow === "clip" && !sampler.closed;
|
|
4535
|
+
const so = readAnimatable(startOffset);
|
|
4536
|
+
if (so.kind === "animated" && so.keyframes.length >= 2) {
|
|
4537
|
+
return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create, isClip), create);
|
|
4538
|
+
}
|
|
4539
|
+
const base = so.kind === "animated" ? Number((_a = so.keyframes[0]) == null ? void 0 : _a.value) || 0 : so.kind === "static" ? Number(so.value) || 0 : 0;
|
|
4540
|
+
const placeCells = isClip ? cells.filter((c) => {
|
|
4541
|
+
const d = base + c.midBase;
|
|
4542
|
+
return d >= 0 && d <= sampler.totalLength;
|
|
4543
|
+
}) : cells;
|
|
4544
|
+
const placements = placeCells.map((c) => ({
|
|
4545
|
+
glyphD: c.glyphD,
|
|
4546
|
+
paint: c.paint,
|
|
4547
|
+
m: alongAffine(sampler, base + c.midBase, c.scale, c.widthEm)
|
|
4548
|
+
}));
|
|
4549
|
+
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
4550
|
+
}
|
|
4551
|
+
var ALONG_PATH_MAX_STEPS = 48;
|
|
4552
|
+
var ALONG_PATH_MAX_STEPS_PER_SEGMENT = 64;
|
|
4553
|
+
function roundN(v, n) {
|
|
4554
|
+
const f = __pow(10, n);
|
|
4555
|
+
return Math.round(v * f) / f;
|
|
4556
|
+
}
|
|
4557
|
+
function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create, isClip) {
|
|
4558
|
+
const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);
|
|
4559
|
+
const timeOf = (kf) => Number(kf.time) || 0;
|
|
4560
|
+
const offOf = (kf) => Number(kf.value) || 0;
|
|
4561
|
+
const onPath = (dist) => dist >= 0 && dist <= sampler.totalLength;
|
|
4562
|
+
const out = [];
|
|
4563
|
+
for (const c of cells) {
|
|
4564
|
+
const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
|
|
4565
|
+
const d = transformPathData(c.glyphD, centred);
|
|
4566
|
+
const sampleKf = (dist, time) => {
|
|
4567
|
+
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
4568
|
+
return {
|
|
4569
|
+
time,
|
|
4570
|
+
value: {
|
|
4571
|
+
[
|
|
4572
|
+
"translate"
|
|
4573
|
+
/* Translate */
|
|
4574
|
+
]: [roundN(x, 3), roundN(y, 3)],
|
|
4575
|
+
[
|
|
4576
|
+
"rotate"
|
|
4577
|
+
/* Rotate */
|
|
4578
|
+
]: roundN(angle * 180 / Math.PI, 3)
|
|
4579
|
+
}
|
|
4580
|
+
};
|
|
4581
|
+
};
|
|
4582
|
+
const kfs = [];
|
|
4583
|
+
const opKfs = [];
|
|
4584
|
+
const pushKf = (dist, time) => {
|
|
4585
|
+
kfs.push(sampleKf(dist, time));
|
|
4586
|
+
if (isClip) opKfs.push({ time, value: onPath(dist) ? 1 : 0 });
|
|
4587
|
+
};
|
|
4588
|
+
pushKf(offOf(sokfs[0]) + c.midBase, timeOf(sokfs[0]));
|
|
4589
|
+
for (let k = 1; k < sokfs.length; k++) {
|
|
4590
|
+
const t0 = timeOf(sokfs[k - 1]), t1 = timeOf(sokfs[k]);
|
|
4591
|
+
const o0 = offOf(sokfs[k - 1]), o1 = offOf(sokfs[k]);
|
|
4592
|
+
const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(o1 - o0) / step)));
|
|
4593
|
+
for (let s = 1; s <= n; s++) {
|
|
4594
|
+
const f = s / n;
|
|
4595
|
+
pushKf(o0 + f * (o1 - o0) + c.midBase, t0 + f * (t1 - t0));
|
|
4596
|
+
}
|
|
4597
|
+
}
|
|
4598
|
+
const transform = { keyframes: kfs };
|
|
4599
|
+
if (loop !== void 0) transform.loop = loop;
|
|
4600
|
+
const animate = { transform };
|
|
4601
|
+
if (isClip && opKfs.some((k) => k.value === 0)) {
|
|
4602
|
+
const op = { keyframes: opKfs };
|
|
4603
|
+
if (loop !== void 0) op.loop = loop;
|
|
4604
|
+
animate.opacity = op;
|
|
4605
|
+
}
|
|
4606
|
+
out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate }), []));
|
|
4607
|
+
}
|
|
4608
|
+
return out;
|
|
4609
|
+
}
|
|
4610
|
+
function paintProps(paint) {
|
|
4611
|
+
const p = {};
|
|
4612
|
+
if (paint.fill !== void 0) p.fill = paint.fill;
|
|
4613
|
+
if (paint.stroke !== void 0) p.stroke = paint.stroke;
|
|
4614
|
+
if (paint.strokeWidth !== void 0) p.strokeWidth = paint.strokeWidth;
|
|
4615
|
+
return p;
|
|
4616
|
+
}
|
|
4617
|
+
function buildPaths(placements, create, warnings) {
|
|
4618
|
+
var _a, _b, _c;
|
|
4619
|
+
if (!placements.length) {
|
|
4620
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
|
|
4621
|
+
return [];
|
|
4622
|
+
}
|
|
4623
|
+
const byPaint = /* @__PURE__ */ new Map();
|
|
4624
|
+
for (const p of placements) {
|
|
4625
|
+
const key = JSON.stringify([(_a = p.paint.fill) != null ? _a : null, (_b = p.paint.stroke) != null ? _b : null, (_c = p.paint.strokeWidth) != null ? _c : null]);
|
|
4626
|
+
const baked = transformPathData(p.glyphD, p.m);
|
|
4627
|
+
const entry = byPaint.get(key);
|
|
4628
|
+
if (entry) entry.d += baked;
|
|
4629
|
+
else byPaint.set(key, { paint: p.paint, d: baked });
|
|
4630
|
+
}
|
|
4631
|
+
const out = [];
|
|
4632
|
+
for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues({ d }, paintProps(paint)), []));
|
|
4633
|
+
return out;
|
|
4634
|
+
}
|
|
4635
|
+
function toGroup(node, children, create) {
|
|
4636
|
+
const gProps = {};
|
|
4637
|
+
for (const k of Object.keys(node)) {
|
|
4638
|
+
if (k === "type" || k === "children" || TEXT_ATTR_KEYS.indexOf(k) !== -1) continue;
|
|
4639
|
+
gProps[k] = node[k];
|
|
4640
|
+
}
|
|
4641
|
+
if (gProps.style && typeof gProps.style === "object") {
|
|
4642
|
+
const style = __spreadValues({}, gProps.style);
|
|
4643
|
+
delete style["white-space"];
|
|
4644
|
+
if (Object.keys(style).length) gProps.style = style;
|
|
4645
|
+
else delete gProps.style;
|
|
4646
|
+
}
|
|
4647
|
+
return create("g", gProps, children);
|
|
4648
|
+
}
|
|
4649
|
+
function applyTextGlyphsEffect(node, fx, ctx) {
|
|
4650
|
+
if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
|
|
4651
|
+
if (!ctx.glyphs) {
|
|
4652
|
+
ctx.warnings.push("textGlyphs: no definitions.glyphs \u2014 left as native <text>");
|
|
4653
|
+
return node;
|
|
4654
|
+
}
|
|
4655
|
+
return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
|
|
4656
|
+
}
|
|
4657
|
+
function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
|
|
4658
|
+
if (!ctx.glyphs) {
|
|
4659
|
+
ctx.warnings.push("textGlyphs: no definitions.glyphs");
|
|
4660
|
+
return null;
|
|
4661
|
+
}
|
|
4662
|
+
return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
|
|
4663
|
+
}
|
|
4059
4664
|
function getKfTranslate(kf) {
|
|
4060
4665
|
var _a;
|
|
4061
4666
|
const v = (_a = kf.value) != null ? _a : kf.v;
|
|
@@ -4496,12 +5101,12 @@ var PixodeskAnimatorReact = (() => {
|
|
|
4496
5101
|
}
|
|
4497
5102
|
return res;
|
|
4498
5103
|
}
|
|
4499
|
-
function extractPathData(
|
|
4500
|
-
if (
|
|
4501
|
-
return
|
|
5104
|
+
function extractPathData(str2) {
|
|
5105
|
+
if (str2.startsWith("path(") && str2.endsWith(")")) {
|
|
5106
|
+
return str2.slice(5, -1);
|
|
4502
5107
|
}
|
|
4503
|
-
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(
|
|
4504
|
-
return
|
|
5108
|
+
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str2)) {
|
|
5109
|
+
return str2;
|
|
4505
5110
|
}
|
|
4506
5111
|
return void 0;
|
|
4507
5112
|
}
|
|
@@ -5422,7 +6027,7 @@ var PixodeskAnimatorReact = (() => {
|
|
|
5422
6027
|
return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
|
|
5423
6028
|
}
|
|
5424
6029
|
function applyPlayerEffects(root) {
|
|
5425
|
-
var _a;
|
|
6030
|
+
var _a, _b;
|
|
5426
6031
|
const ctx = {
|
|
5427
6032
|
defs: [],
|
|
5428
6033
|
warnings: [],
|
|
@@ -5433,7 +6038,8 @@ var PixodeskAnimatorReact = (() => {
|
|
|
5433
6038
|
maskAncestorChains: /* @__PURE__ */ new Map(),
|
|
5434
6039
|
// Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →
|
|
5435
6040
|
// webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
|
|
5436
|
-
engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi
|
|
6041
|
+
engine: ((_a = getAnimatorConfig(root)) == null ? void 0 : _a.mode) === PxAnimatorMode.frames ? PxAnimatorEngine.frames : PxAnimatorEngine.webapi,
|
|
6042
|
+
glyphs: (_b = getDefs(root)) == null ? void 0 : _b.glyphs
|
|
5437
6043
|
};
|
|
5438
6044
|
const working = clone(root);
|
|
5439
6045
|
indexById(working, ctx.idMap);
|
|
@@ -5445,16 +6051,33 @@ var PixodeskAnimatorReact = (() => {
|
|
|
5445
6051
|
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
5446
6052
|
}
|
|
5447
6053
|
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
6054
|
+
var _a;
|
|
5448
6055
|
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
5449
6056
|
const fx = node.effects;
|
|
5450
6057
|
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
5451
6058
|
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
5452
6059
|
if (!fx && !innerIdForContentRef) return node;
|
|
5453
|
-
const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient,
|
|
6060
|
+
const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
|
|
5454
6061
|
const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
|
|
5455
6062
|
if (fx) delete node.effects;
|
|
5456
6063
|
let n = node;
|
|
5457
|
-
|
|
6064
|
+
let consumedByGlyphs = false;
|
|
6065
|
+
if (text == null ? void 0 : text.useGlyphs) {
|
|
6066
|
+
if (textPath) {
|
|
6067
|
+
const pathD = typeof textPath.path === "string" ? textPath.path : void 0;
|
|
6068
|
+
const rawTL = textPath.textLength;
|
|
6069
|
+
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;
|
|
6070
|
+
const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textLength, textPath.pathOverflow);
|
|
6071
|
+
if (glyphed) {
|
|
6072
|
+
n = glyphed;
|
|
6073
|
+
consumedByGlyphs = true;
|
|
6074
|
+
}
|
|
6075
|
+
} else {
|
|
6076
|
+
n = applyTextGlyphsEffect(n, text, ctx);
|
|
6077
|
+
consumedByGlyphs = true;
|
|
6078
|
+
}
|
|
6079
|
+
}
|
|
6080
|
+
if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
|
|
5458
6081
|
n = applyFillGradientEffect(n, fillGradient, ctx);
|
|
5459
6082
|
n = applyStrokeGradientEffect(n, strokeGradient, ctx);
|
|
5460
6083
|
n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);
|
|
@@ -5691,8 +6314,8 @@ var PixodeskAnimatorReact = (() => {
|
|
|
5691
6314
|
var DATA_SVG_IMAGE_RE = /^data:image\/svg\+xml(?:;[^,]*)?,/i;
|
|
5692
6315
|
var DATA_IMAGE_BASE64_PAYLOAD_RE = /^data:image\/[^;,]*;base64,([A-Za-z0-9+/]{8})/i;
|
|
5693
6316
|
var BASE64_RASTER_MAGICS = ["iVBORw0K", "/9j/", "R0lGOD", "UklGR", "Qk"];
|
|
5694
|
-
function isContentSniffedRasterImage(
|
|
5695
|
-
const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(
|
|
6317
|
+
function isContentSniffedRasterImage(str2) {
|
|
6318
|
+
const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(str2);
|
|
5696
6319
|
return !!m && BASE64_RASTER_MAGICS.some((magic) => m[1].startsWith(magic));
|
|
5697
6320
|
}
|
|
5698
6321
|
function isDangerousAttrName(nameLower) {
|
|
@@ -5706,18 +6329,18 @@ var PixodeskAnimatorReact = (() => {
|
|
|
5706
6329
|
return void 0;
|
|
5707
6330
|
}
|
|
5708
6331
|
if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
|
|
5709
|
-
const
|
|
5710
|
-
if (
|
|
6332
|
+
const str2 = String(value);
|
|
6333
|
+
if (str2.includes("url(") && !/^url\(#[^)]+\)$/.test(str2)) {
|
|
5711
6334
|
console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
|
|
5712
6335
|
return void 0;
|
|
5713
6336
|
}
|
|
5714
6337
|
return value;
|
|
5715
6338
|
}
|
|
5716
6339
|
if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
|
|
5717
|
-
const
|
|
5718
|
-
if (
|
|
5719
|
-
if (/^url\(#[^)]+\)$/.test(
|
|
5720
|
-
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(
|
|
6340
|
+
const str2 = String(value);
|
|
6341
|
+
if (str2.startsWith("#")) return value;
|
|
6342
|
+
if (/^url\(#[^)]+\)$/.test(str2)) return value;
|
|
6343
|
+
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(str2) || DATA_SVG_IMAGE_RE.test(str2) || isContentSniffedRasterImage(str2))) return value;
|
|
5721
6344
|
console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or data:image/\u2026 URI, got:', value);
|
|
5722
6345
|
return void 0;
|
|
5723
6346
|
}
|
|
@@ -5747,7 +6370,7 @@ var PixodeskAnimatorReact = (() => {
|
|
|
5747
6370
|
if (textContent) element.textContent = textContent;
|
|
5748
6371
|
return element;
|
|
5749
6372
|
}
|
|
5750
|
-
function
|
|
6373
|
+
function resolveStyle2(style, defs) {
|
|
5751
6374
|
var _a;
|
|
5752
6375
|
if (!style) return void 0;
|
|
5753
6376
|
if (typeof style === "string") {
|
|
@@ -5783,7 +6406,7 @@ var PixodeskAnimatorReact = (() => {
|
|
|
5783
6406
|
if (!node) return null;
|
|
5784
6407
|
const _a = node, { type, children, style } = _a, props = __objRest(_a, ["type", "children", "style"]);
|
|
5785
6408
|
const nodeDefs = getDefs(node) || defs;
|
|
5786
|
-
const resolvedStyle =
|
|
6409
|
+
const resolvedStyle = resolveStyle2(style, nodeDefs);
|
|
5787
6410
|
let childElements;
|
|
5788
6411
|
if (children) {
|
|
5789
6412
|
for (const ch of children) {
|