@pixodesk/svg-animator-vue 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.umd.js CHANGED
@@ -57768,8 +57768,9 @@ ${codeFrame}` : message);
57768
57768
  gradientTransform: px.string().optional()
57769
57769
  }));
57770
57770
  var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
57771
- var PxTextAlongPathEffectSchema = implementsInterface()(px.object({
57772
- href: px.string(),
57771
+ var PxTextPathEffectSchema = implementsInterface()(px.object({
57772
+ path: px.string(),
57773
+ pathOverflow: px.string().optional(),
57773
57774
  lengthAdjust: px.string().optional(),
57774
57775
  method: px.string().optional(),
57775
57776
  spacing: px.string().optional(),
@@ -57788,7 +57789,7 @@ ${codeFrame}` : message);
57788
57789
  isCombinedShape: px.boolean().optional(),
57789
57790
  fillGradient: PxFillGradientEffectSchema.optional(),
57790
57791
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
57791
- textAlongPath: PxTextAlongPathEffectSchema.optional(),
57792
+ textPath: PxTextPathEffectSchema.optional(),
57792
57793
  text: PxTextEffectSchema.optional()
57793
57794
  }));
57794
57795
  function validateNodeEffects(root, opts) {
@@ -58639,97 +58640,6 @@ ${codeFrame}` : message);
58639
58640
  }
58640
58641
  }
58641
58642
  }
58642
- function applyTextAlongPathEffect(node, fx, _ctx) {
58643
- var _a;
58644
- if (!fx) return node;
58645
- const href = typeof fx.href === "string" && !fx.href.startsWith("#") ? "#" + fx.href : fx.href;
58646
- const textPath = {
58647
- type: "textPath",
58648
- href,
58649
- children: (_a = node.children) != null ? _a : []
58650
- };
58651
- if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
58652
- if (fx.method !== void 0) textPath.method = fx.method;
58653
- if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
58654
- applyAnimatableNumber(textPath, "startOffset", fx.startOffset);
58655
- applyAnimatableNumber(textPath, "textLength", fx.textLength);
58656
- node.children = [textPath];
58657
- return node;
58658
- }
58659
- function applyAnimatableNumber(node, attrName, raw) {
58660
- if (raw === void 0 || raw === null) return;
58661
- if (typeof raw === "number") {
58662
- node[attrName] = String(raw);
58663
- return;
58664
- }
58665
- if (typeof raw === "object" && raw !== null) {
58666
- const obj = raw;
58667
- if (Array.isArray(obj.keyframes)) {
58668
- const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
58669
- const animate = __spreadValues({}, prevAnimate || {});
58670
- const block = { keyframes: obj.keyframes };
58671
- if (obj.loop !== void 0) block.loop = obj.loop;
58672
- animate[attrName] = block;
58673
- node.animate = animate;
58674
- return;
58675
- }
58676
- if (typeof obj.value === "number") {
58677
- node[attrName] = String(obj.value);
58678
- return;
58679
- }
58680
- }
58681
- }
58682
- var jsonElementFactory = (type, props, children) => {
58683
- const node = { type };
58684
- for (const k in props) if (props[k] !== void 0) node[k] = props[k];
58685
- const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
58686
- if (arr.length) node.children = arr;
58687
- return node;
58688
- };
58689
- function fmt(v, decimals) {
58690
- return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
58691
- }
58692
- function pack(nums, decimals) {
58693
- let s = "";
58694
- for (let i = 0; i < nums.length; i++) {
58695
- const str2 = fmt(nums[i], decimals);
58696
- if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
58697
- s += str2;
58698
- }
58699
- return s;
58700
- }
58701
- function apply(m, x, y) {
58702
- return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
58703
- }
58704
- var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
58705
- function transformPathData(d, m, decimals = 2) {
58706
- const tokens = [];
58707
- let match;
58708
- TOKEN_RE.lastIndex = 0;
58709
- while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
58710
- let out = "";
58711
- let i = 0;
58712
- const num2 = () => parseFloat(tokens[i++]);
58713
- while (i < tokens.length) {
58714
- const cmd = tokens[i++];
58715
- if (cmd === "M" || cmd === "L") {
58716
- const [x, y] = apply(m, num2(), num2());
58717
- out += cmd + pack([x, y], decimals);
58718
- } else if (cmd === "C") {
58719
- const [x1, y1] = apply(m, num2(), num2());
58720
- const [x2, y2] = apply(m, num2(), num2());
58721
- const [x, y] = apply(m, num2(), num2());
58722
- out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
58723
- } else if (cmd === "Q") {
58724
- const [x1, y1] = apply(m, num2(), num2());
58725
- const [x, y] = apply(m, num2(), num2());
58726
- out += "Q" + pack([x1, y1, x, y], decimals);
58727
- } else if (cmd === "Z" || cmd === "z") {
58728
- out += "Z";
58729
- }
58730
- }
58731
- return out;
58732
- }
58733
58643
  function bezierToSvgPath(path) {
58734
58644
  var _a, _b, _c, _d;
58735
58645
  const v = path.v;
@@ -59271,6 +59181,7 @@ ${codeFrame}` : message);
59271
59181
  };
59272
59182
  return {
59273
59183
  totalLength,
59184
+ closed,
59274
59185
  sampleAtDistance(dist) {
59275
59186
  if (!closed && (dist < 0 || dist > totalLength)) {
59276
59187
  const edge = dist < 0 ? 0 : totalLength;
@@ -59282,6 +59193,167 @@ ${codeFrame}` : message);
59282
59193
  }
59283
59194
  };
59284
59195
  }
59196
+ var EXTEND_MARGIN_FRAC = 0.15;
59197
+ function numRange(v) {
59198
+ if (typeof v === "number") return { min: v, max: v };
59199
+ if (v && typeof v === "object") {
59200
+ const o = v;
59201
+ if (typeof o.value === "number") return { min: o.value, max: o.value };
59202
+ if (Array.isArray(o.keyframes) && o.keyframes.length) {
59203
+ const vals = o.keyframes.map((k) => Number(k.value) || 0);
59204
+ return { min: Math.min(...vals), max: Math.max(...vals) };
59205
+ }
59206
+ }
59207
+ return { min: 0, max: 0 };
59208
+ }
59209
+ function estimateTextAdvance(node) {
59210
+ let chars = 0, maxFont = 16;
59211
+ const walk = (el) => {
59212
+ var _a, _b;
59213
+ const fs = parseFloat(String((_a = el.fontSize) != null ? _a : "")) || 0;
59214
+ if (fs) maxFont = Math.max(maxFont, fs);
59215
+ const t = (_b = el.text) != null ? _b : el.textContent;
59216
+ if (typeof t === "string") chars += t.length;
59217
+ if (el.children) for (const c of el.children) walk(c);
59218
+ };
59219
+ walk(node);
59220
+ return chars * maxFont;
59221
+ }
59222
+ var r3 = (n) => Math.round(n * 1e3) / 1e3;
59223
+ function shiftAnimatable(v, by) {
59224
+ if (!by || v === void 0 || v === null) return v;
59225
+ if (typeof v === "number") return v + by;
59226
+ const o = v;
59227
+ if (typeof o.value === "number") return __spreadProps(__spreadValues({}, o), { value: o.value + by });
59228
+ if (Array.isArray(o.keyframes)) return __spreadProps(__spreadValues({}, o), { keyframes: o.keyframes.map((k) => __spreadProps(__spreadValues({}, k), { value: (Number(k.value) || 0) + by })) });
59229
+ return v;
59230
+ }
59231
+ function extendedPathForBrowser(pathD, opts) {
59232
+ var _a;
59233
+ if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
59234
+ const sampler = createPathSampler(pathD);
59235
+ if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
59236
+ const L = sampler.totalLength;
59237
+ const margin = EXTEND_MARGIN_FRAC * L;
59238
+ const so = numRange(opts.startOffset);
59239
+ const runWidth = numRange(opts.textLength).max || ((_a = opts.advance) != null ? _a : 0);
59240
+ const startOverflow = Math.max(0, -so.min);
59241
+ const endOverflow = Math.max(0, so.max + runWidth - L);
59242
+ const startExt = startOverflow > 0 ? startOverflow + margin : 0;
59243
+ const endExt = endOverflow > 0 ? endOverflow + margin : 0;
59244
+ if (endExt <= 0 && startExt <= 0) return { d: pathD, startShift: 0 };
59245
+ const s = sampler.sampleAtDistance(0);
59246
+ const e = sampler.sampleAtDistance(L);
59247
+ let d = pathD;
59248
+ if (startExt > 0) {
59249
+ const sx = s.x - Math.cos(s.angle) * startExt, sy = s.y - Math.sin(s.angle) * startExt;
59250
+ const rest = pathD.replace(/^\s*[Mm]\s*-?[\d.]+[\s,]+-?[\d.]+/, "");
59251
+ d = "M" + r3(sx) + "," + r3(sy) + "L" + r3(s.x) + "," + r3(s.y) + rest;
59252
+ }
59253
+ if (endExt > 0) {
59254
+ const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;
59255
+ d += "L" + r3(ex) + "," + r3(ey);
59256
+ }
59257
+ return { d, startShift: startExt };
59258
+ }
59259
+ function applyTextPathEffect(node, fx, ctx) {
59260
+ var _a;
59261
+ if (!fx || typeof fx.path !== "string" || !fx.path) return node;
59262
+ const pathId = genId(ctx, "tpath");
59263
+ const { d, startShift } = extendedPathForBrowser(fx.path, {
59264
+ pathOverflow: fx.pathOverflow,
59265
+ startOffset: fx.startOffset,
59266
+ textLength: fx.textLength,
59267
+ advance: estimateTextAdvance(node)
59268
+ });
59269
+ ctx.defs.push({ type: "path", id: pathId, d });
59270
+ const textPath = {
59271
+ type: "textPath",
59272
+ href: "#" + pathId,
59273
+ children: (_a = node.children) != null ? _a : []
59274
+ };
59275
+ if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
59276
+ if (fx.method !== void 0) textPath.method = fx.method;
59277
+ if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
59278
+ applyAnimatableNumber(textPath, "startOffset", shiftAnimatable(fx.startOffset, startShift));
59279
+ applyAnimatableNumber(textPath, "textLength", fx.textLength);
59280
+ node.children = [textPath];
59281
+ return node;
59282
+ }
59283
+ function applyAnimatableNumber(node, attrName, raw) {
59284
+ if (raw === void 0 || raw === null) return;
59285
+ if (typeof raw === "number") {
59286
+ node[attrName] = String(raw);
59287
+ return;
59288
+ }
59289
+ if (typeof raw === "object" && raw !== null) {
59290
+ const obj = raw;
59291
+ if (Array.isArray(obj.keyframes)) {
59292
+ const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
59293
+ const animate = __spreadValues({}, prevAnimate || {});
59294
+ const block = { keyframes: obj.keyframes };
59295
+ if (obj.loop !== void 0) block.loop = obj.loop;
59296
+ animate[attrName] = block;
59297
+ node.animate = animate;
59298
+ return;
59299
+ }
59300
+ if (typeof obj.value === "number") {
59301
+ node[attrName] = String(obj.value);
59302
+ return;
59303
+ }
59304
+ }
59305
+ }
59306
+ var jsonElementFactory = (type, props, children) => {
59307
+ const node = { type };
59308
+ for (const k in props) if (props[k] !== void 0) node[k] = props[k];
59309
+ const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
59310
+ if (arr.length) node.children = arr;
59311
+ return node;
59312
+ };
59313
+ function fmt(v, decimals) {
59314
+ return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
59315
+ }
59316
+ function pack(nums, decimals) {
59317
+ let s = "";
59318
+ for (let i = 0; i < nums.length; i++) {
59319
+ const str2 = fmt(nums[i], decimals);
59320
+ if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
59321
+ s += str2;
59322
+ }
59323
+ return s;
59324
+ }
59325
+ function apply(m, x, y) {
59326
+ return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
59327
+ }
59328
+ var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
59329
+ function transformPathData(d, m, decimals = 2) {
59330
+ const tokens = [];
59331
+ let match;
59332
+ TOKEN_RE.lastIndex = 0;
59333
+ while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
59334
+ let out = "";
59335
+ let i = 0;
59336
+ const num2 = () => parseFloat(tokens[i++]);
59337
+ while (i < tokens.length) {
59338
+ const cmd = tokens[i++];
59339
+ if (cmd === "M" || cmd === "L") {
59340
+ const [x, y] = apply(m, num2(), num2());
59341
+ out += cmd + pack([x, y], decimals);
59342
+ } else if (cmd === "C") {
59343
+ const [x1, y1] = apply(m, num2(), num2());
59344
+ const [x2, y2] = apply(m, num2(), num2());
59345
+ const [x, y] = apply(m, num2(), num2());
59346
+ out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
59347
+ } else if (cmd === "Q") {
59348
+ const [x1, y1] = apply(m, num2(), num2());
59349
+ const [x, y] = apply(m, num2(), num2());
59350
+ out += "Q" + pack([x1, y1, x, y], decimals);
59351
+ } else if (cmd === "Z" || cmd === "z") {
59352
+ out += "Z";
59353
+ }
59354
+ }
59355
+ return out;
59356
+ }
59285
59357
  var DEFAULT_FONT_SIZE = 16;
59286
59358
  var TEXT_ATTR_KEYS = [
59287
59359
  "fontFamily",
@@ -59442,7 +59514,7 @@ ${codeFrame}` : message);
59442
59514
  const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;
59443
59515
  return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw, y - scale * sin * hw];
59444
59516
  }
59445
- function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength) {
59517
+ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
59446
59518
  var _a;
59447
59519
  const { glyphs, create = jsonElementFactory, warnings } = opts;
59448
59520
  const sampler = pathD ? createPathSampler(pathD) : null;
@@ -59457,12 +59529,17 @@ ${codeFrame}` : message);
59457
59529
  const k = textLength / width;
59458
59530
  for (const c of cells) c.midBase *= k;
59459
59531
  }
59532
+ const isClip = pathOverflow === "clip" && !sampler.closed;
59460
59533
  const so = readAnimatable(startOffset);
59461
59534
  if (so.kind === "animated" && so.keyframes.length >= 2) {
59462
- return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create), create);
59535
+ return toGroup(node, buildAnimatedAlongPath(cells, sampler, so.keyframes, so.loop, create, isClip), create);
59463
59536
  }
59464
59537
  const base = so.kind === "animated" ? Number((_a = so.keyframes[0]) == null ? void 0 : _a.value) || 0 : so.kind === "static" ? Number(so.value) || 0 : 0;
59465
- const placements = cells.map((c) => ({
59538
+ const placeCells = isClip ? cells.filter((c) => {
59539
+ const d = base + c.midBase;
59540
+ return d >= 0 && d <= sampler.totalLength;
59541
+ }) : cells;
59542
+ const placements = placeCells.map((c) => ({
59466
59543
  glyphD: c.glyphD,
59467
59544
  paint: c.paint,
59468
59545
  m: alongAffine(sampler, base + c.midBase, c.scale, c.widthEm)
@@ -59475,10 +59552,11 @@ ${codeFrame}` : message);
59475
59552
  const f = __pow(10, n);
59476
59553
  return Math.round(v * f) / f;
59477
59554
  }
59478
- function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create) {
59555
+ function buildAnimatedAlongPath(cells, sampler, sokfs, loop, create, isClip) {
59479
59556
  const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);
59480
59557
  const timeOf = (kf) => Number(kf.time) || 0;
59481
59558
  const offOf = (kf) => Number(kf.value) || 0;
59559
+ const onPath = (dist) => dist >= 0 && dist <= sampler.totalLength;
59482
59560
  const out = [];
59483
59561
  for (const c of cells) {
59484
59562
  const centred = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
@@ -59499,19 +59577,31 @@ ${codeFrame}` : message);
59499
59577
  }
59500
59578
  };
59501
59579
  };
59502
- const kfs = [sampleKf(offOf(sokfs[0]) + c.midBase, timeOf(sokfs[0]))];
59580
+ const kfs = [];
59581
+ const opKfs = [];
59582
+ const pushKf = (dist, time) => {
59583
+ kfs.push(sampleKf(dist, time));
59584
+ if (isClip) opKfs.push({ time, value: onPath(dist) ? 1 : 0 });
59585
+ };
59586
+ pushKf(offOf(sokfs[0]) + c.midBase, timeOf(sokfs[0]));
59503
59587
  for (let k = 1; k < sokfs.length; k++) {
59504
59588
  const t0 = timeOf(sokfs[k - 1]), t1 = timeOf(sokfs[k]);
59505
59589
  const o0 = offOf(sokfs[k - 1]), o1 = offOf(sokfs[k]);
59506
59590
  const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(o1 - o0) / step)));
59507
59591
  for (let s = 1; s <= n; s++) {
59508
59592
  const f = s / n;
59509
- kfs.push(sampleKf(o0 + f * (o1 - o0) + c.midBase, t0 + f * (t1 - t0)));
59593
+ pushKf(o0 + f * (o1 - o0) + c.midBase, t0 + f * (t1 - t0));
59510
59594
  }
59511
59595
  }
59512
59596
  const transform = { keyframes: kfs };
59513
59597
  if (loop !== void 0) transform.loop = loop;
59514
- out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate: { transform } }), []));
59598
+ const animate = { transform };
59599
+ if (isClip && opKfs.some((k) => k.value === 0)) {
59600
+ const op = { keyframes: opKfs };
59601
+ if (loop !== void 0) op.loop = loop;
59602
+ animate.opacity = op;
59603
+ }
59604
+ out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate }), []));
59515
59605
  }
59516
59606
  return out;
59517
59607
  }
@@ -59562,12 +59652,12 @@ ${codeFrame}` : message);
59562
59652
  }
59563
59653
  return materialiseGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
59564
59654
  }
59565
- function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength) {
59655
+ function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
59566
59656
  if (!ctx.glyphs) {
59567
59657
  ctx.warnings.push("textGlyphs: no definitions.glyphs");
59568
59658
  return null;
59569
59659
  }
59570
- return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength);
59660
+ return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
59571
59661
  }
59572
59662
  function getKfTranslate(kf) {
59573
59663
  var _a;
@@ -60965,18 +61055,17 @@ ${codeFrame}` : message);
60965
61055
  const originalId = typeof node.id === "string" ? node.id : void 0;
60966
61056
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
60967
61057
  if (!fx && !innerIdForContentRef) return node;
60968
- const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textAlongPath, text } = fx != null ? fx : {};
61058
+ const { transformation, repeater, maskedBy, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
60969
61059
  const isCombinedShape = fx == null ? void 0 : fx.isCombinedShape;
60970
61060
  if (fx) delete node.effects;
60971
61061
  let n = node;
60972
61062
  let consumedByGlyphs = false;
60973
61063
  if (text == null ? void 0 : text.useGlyphs) {
60974
- if (textAlongPath) {
60975
- const pathNode = typeof textAlongPath.href === "string" ? ctx.idMap.get(textAlongPath.href) : void 0;
60976
- const pathD = pathNode && typeof pathNode.d === "string" ? pathNode.d : void 0;
60977
- const rawTL = textAlongPath.textLength;
61064
+ if (textPath) {
61065
+ const pathD = typeof textPath.path === "string" ? textPath.path : void 0;
61066
+ const rawTL = textPath.textLength;
60978
61067
  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;
60979
- const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textAlongPath.startOffset, textLength);
61068
+ const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textLength, textPath.pathOverflow);
60980
61069
  if (glyphed) {
60981
61070
  n = glyphed;
60982
61071
  consumedByGlyphs = true;
@@ -60986,7 +61075,7 @@ ${codeFrame}` : message);
60986
61075
  consumedByGlyphs = true;
60987
61076
  }
60988
61077
  }
60989
- if (!consumedByGlyphs) n = applyTextAlongPathEffect(n, textAlongPath, ctx);
61078
+ if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
60990
61079
  n = applyFillGradientEffect(n, fillGradient, ctx);
60991
61080
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
60992
61081
  n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx);