@pixodesk/svg-animator-core 1.0.28 → 1.0.29

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
@@ -56,6 +56,7 @@ __export(index_exports, {
56
56
  DISALLOWED_SVG_TAGS_LOWER: () => DISALLOWED_SVG_TAGS_LOWER,
57
57
  INTERNAL_ATTRS: () => INTERNAL_ATTRS,
58
58
  LOOP_JUMP_SHIFT_MS: () => LOOP_JUMP_SHIFT_MS,
59
+ MISSING_GLYPH_CLASS_NAME: () => MISSING_GLYPH_CLASS_NAME,
59
60
  PCT_BASED_ATTR_NAMES: () => PCT_BASED_ATTR_NAMES,
60
61
  PX_ANIM_ATTR_NAME: () => PX_ANIM_ATTR_NAME,
61
62
  PX_ANIM_SRC_ATTR_NAME: () => PX_ANIM_SRC_ATTR_NAME,
@@ -1322,6 +1323,7 @@ var PxScrollSchema = implementsInterface()(px.object({
1322
1323
  subject: px.string().optional(),
1323
1324
  smoothing: px.number().optional(),
1324
1325
  pin: px.boolean().optional(),
1326
+ pinAlign: px.enum(["top", "center", "bottom"]).optional(),
1325
1327
  pinTop: px.number().optional(),
1326
1328
  pinDistance: px.number().optional(),
1327
1329
  range: PxScrollRangeSchema.optional()
@@ -4595,6 +4597,19 @@ var TEXT_ATTR_KEYS = [
4595
4597
  TEXT_CONTENT_ATTR,
4596
4598
  "xml:space"
4597
4599
  ];
4600
+ var PAINT_STATIC_KEYS = [
4601
+ "fillOpacity",
4602
+ "fillRule",
4603
+ "strokeOpacity",
4604
+ "strokeDasharray",
4605
+ "strokeDashoffset",
4606
+ "strokeLinecap",
4607
+ "strokeLinejoin",
4608
+ "strokeMiterlimit",
4609
+ "mixBlendMode",
4610
+ "filter"
4611
+ ];
4612
+ var PAINT_ANIMATE_KEYS = ["fill", "stroke", "strokeWidth", "opacity", "fillOpacity", "strokeOpacity", "strokeDasharray", "strokeDashoffset"];
4598
4613
  function parseLen(v) {
4599
4614
  if (typeof v === "number") return v;
4600
4615
  if (typeof v === "string") {
@@ -4606,17 +4621,39 @@ function parseLen(v) {
4606
4621
  function str(v) {
4607
4622
  return typeof v === "string" ? v : void 0;
4608
4623
  }
4624
+ function paintAnimateOf(node) {
4625
+ const bag = node.animate;
4626
+ if (!bag || typeof bag !== "object") return void 0;
4627
+ let out;
4628
+ for (const k of PAINT_ANIMATE_KEYS) {
4629
+ if (bag[k] !== void 0) (out != null ? out : out = {})[k] = bag[k];
4630
+ }
4631
+ return out;
4632
+ }
4609
4633
  function resolveStyle2(node, parent) {
4610
- var _a, _b, _c, _d, _e, _f, _g;
4611
- return {
4634
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4635
+ const isTextRoot = node.type === "text";
4636
+ const nodeStyle = node.style;
4637
+ const own = (key) => {
4638
+ var _a2;
4639
+ return isTextRoot ? void 0 : (_a2 = node[key]) != null ? _a2 : nodeStyle == null ? void 0 : nodeStyle[key];
4640
+ };
4641
+ const res = {
4612
4642
  fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
4613
4643
  fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
4614
4644
  fill: (_c = node.fill) != null ? _c : parent.fill,
4615
4645
  stroke: (_d = node.stroke) != null ? _d : parent.stroke,
4616
4646
  strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
4617
4647
  letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
4618
- wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing
4648
+ wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing,
4649
+ opacity: (_h = parseLen(own("opacity"))) != null ? _h : parent.opacity,
4650
+ animate: (_i = isTextRoot ? void 0 : paintAnimateOf(node)) != null ? _i : parent.animate
4619
4651
  };
4652
+ for (const key of PAINT_STATIC_KEYS) {
4653
+ const v = (_j = own(key)) != null ? _j : parent[key];
4654
+ if (v !== void 0) res[key] = v;
4655
+ }
4656
+ return res;
4620
4657
  }
4621
4658
  function rootStyleOf(node) {
4622
4659
  var _a, _b, _c;
@@ -4635,6 +4672,11 @@ function paintOf(s) {
4635
4672
  if (s.fill !== void 0) p.fill = s.fill;
4636
4673
  if (s.stroke !== void 0) p.stroke = s.stroke;
4637
4674
  if (s.strokeWidth !== void 0) p.strokeWidth = s.strokeWidth;
4675
+ if (s.opacity !== void 0 && s.opacity !== 1) p.opacity = s.opacity;
4676
+ for (const key of PAINT_STATIC_KEYS) {
4677
+ if (s[key] !== void 0) p[key] = s[key];
4678
+ }
4679
+ if (s.animate !== void 0) p.animate = s.animate;
4638
4680
  return p;
4639
4681
  }
4640
4682
  function glyphFontFor(s, glyphs, soleFont, warnings) {
@@ -4648,6 +4690,7 @@ function soleFontOf(glyphs) {
4648
4690
  return names.length === 1 ? glyphs[names[0]] : void 0;
4649
4691
  }
4650
4692
  var MISSING_GLYPH_ADVANCE_EM = 0.6;
4693
+ var MISSING_GLYPH_CLASS_NAME = "px-missing-glyph";
4651
4694
  function missingGlyphBoxEm(advanceEm, ascentEm) {
4652
4695
  if (advanceEm <= 0 || ascentEm <= 0) return "";
4653
4696
  const inset = 0.08;
@@ -4683,7 +4726,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4683
4726
  pen.x += g.width * scale;
4684
4727
  } else if (/\S/.test(ch)) {
4685
4728
  const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
4686
- placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
4729
+ placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, isMissing: true, line, x: pen.x, y: pen.y, scale });
4687
4730
  pen.x += advEm * scale;
4688
4731
  } else {
4689
4732
  pen.x += (g ? g.width : 0) * scale;
@@ -4874,7 +4917,7 @@ function collectAlongPathCells(node, glyphs, soleFont, warnings) {
4874
4917
  } else if (/\S/.test(ch)) {
4875
4918
  const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
4876
4919
  const boxAdv = wEm * scale;
4877
- cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, midBase: adv + boxAdv / 2 });
4920
+ cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, isMissing: true, midBase: adv + boxAdv / 2 });
4878
4921
  adv += boxAdv;
4879
4922
  } else {
4880
4923
  adv += (g ? g.width : 0) * scale;
@@ -4930,6 +4973,7 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
4930
4973
  const placements = placeCells.map((c) => ({
4931
4974
  glyphD: c.glyphD,
4932
4975
  paint: c.paint,
4976
+ isMissing: c.isMissing,
4933
4977
  m: alongAffine(sampler, base + c.midBase * k, c.scale, c.widthEm, perp)
4934
4978
  }));
4935
4979
  return toGroup(node, buildPaths(placements, create, warnings), create);
@@ -5012,12 +5056,13 @@ function buildAnimatedAlongPath(cells, sampler, distOf, times, loop, create, isC
5012
5056
  const transform = { keyframes: kfs };
5013
5057
  if (loop !== void 0) transform.loop = loop;
5014
5058
  const animate = { transform };
5059
+ if (c.paint.animate) Object.assign(animate, c.paint.animate);
5015
5060
  if (isClip && opKfs.some((k) => k.value === 0)) {
5016
5061
  const op = { keyframes: opKfs };
5017
5062
  if (loop !== void 0) op.loop = loop;
5018
5063
  animate.opacity = op;
5019
5064
  }
5020
- out.push(create("path", __spreadProps(__spreadValues({ d }, paintProps(c.paint)), { animate }), []));
5065
+ out.push(create("path", __spreadProps(__spreadValues(__spreadValues({ d }, paintProps(c.paint)), missingGlyphProps(c.isMissing)), { animate }), []));
5021
5066
  }
5022
5067
  return out;
5023
5068
  }
@@ -5026,24 +5071,34 @@ function paintProps(paint) {
5026
5071
  if (paint.fill !== void 0) p.fill = paint.fill;
5027
5072
  if (paint.stroke !== void 0) p.stroke = paint.stroke;
5028
5073
  if (paint.strokeWidth !== void 0) p.strokeWidth = paint.strokeWidth;
5074
+ if (paint.opacity !== void 0) p.opacity = paint.opacity;
5075
+ for (const key of PAINT_STATIC_KEYS) {
5076
+ if (paint[key] !== void 0) p[key] = paint[key];
5077
+ }
5029
5078
  return p;
5030
5079
  }
5080
+ function missingGlyphProps(isMissing) {
5081
+ return isMissing ? { class: MISSING_GLYPH_CLASS_NAME } : {};
5082
+ }
5031
5083
  function buildPaths(placements, create, warnings) {
5032
- var _a, _b, _c;
5033
5084
  if (!placements.length) {
5034
5085
  warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
5035
5086
  return [];
5036
5087
  }
5037
5088
  const byPaint = /* @__PURE__ */ new Map();
5038
5089
  for (const p of placements) {
5039
- 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]);
5090
+ const key = JSON.stringify([p.paint, !!p.isMissing]);
5040
5091
  const baked = transformPathData(p.glyphD, p.m);
5041
5092
  const entry = byPaint.get(key);
5042
5093
  if (entry) entry.d += baked;
5043
- else byPaint.set(key, { paint: p.paint, d: baked });
5094
+ else byPaint.set(key, { paint: p.paint, d: baked, isMissing: p.isMissing });
5044
5095
  }
5045
5096
  const out = [];
5046
- for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues({ d }, paintProps(paint)), []));
5097
+ for (const { paint, d, isMissing } of byPaint.values()) {
5098
+ out.push(create("path", __spreadValues(__spreadValues(__spreadValues({
5099
+ d
5100
+ }, paintProps(paint)), missingGlyphProps(isMissing)), paint.animate !== void 0 ? { animate: __spreadValues({}, paint.animate) } : {}), []));
5101
+ }
5047
5102
  return out;
5048
5103
  }
5049
5104
  function toGroup(node, children, create) {
@@ -6155,6 +6210,7 @@ function subtractMultiset(a, b) {
6155
6210
  DISALLOWED_SVG_TAGS_LOWER,
6156
6211
  INTERNAL_ATTRS,
6157
6212
  LOOP_JUMP_SHIFT_MS,
6213
+ MISSING_GLYPH_CLASS_NAME,
6158
6214
  PCT_BASED_ATTR_NAMES,
6159
6215
  PX_ANIM_ATTR_NAME,
6160
6216
  PX_ANIM_SRC_ATTR_NAME,