@pixodesk/svg-animator-react 1.0.28 → 1.0.30

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
@@ -2790,7 +2790,7 @@ var PixodeskAnimatorReact = (() => {
2790
2790
  auto: "auto",
2791
2791
  exact: "exact"
2792
2792
  };
2793
- var PxTrimSubPaths = {
2793
+ var PxStrokeTrimSubPaths = {
2794
2794
  separate: "separate",
2795
2795
  combined: "combined"
2796
2796
  };
@@ -2945,6 +2945,7 @@ var PixodeskAnimatorReact = (() => {
2945
2945
  subject: px.string().optional(),
2946
2946
  smoothing: px.number().optional(),
2947
2947
  pin: px.boolean().optional(),
2948
+ pinAlign: px.enum(["top", "center", "bottom"]).optional(),
2948
2949
  pinTop: px.number().optional(),
2949
2950
  pinDistance: px.number().optional(),
2950
2951
  range: PxScrollRangeSchema.optional()
@@ -3027,10 +3028,10 @@ var PixodeskAnimatorReact = (() => {
3027
3028
  d: PxAnimatableStringSchema.optional(),
3028
3029
  animate: PxPropertyAnimationSchema.optional()
3029
3030
  }));
3030
- var PxTrimPathEffectSchema = implementsInterface()(px.object({
3031
+ var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
3031
3032
  offset: PxAnimatableNumberSchema.optional(),
3032
3033
  range: PxAnimatableVec2Schema.optional(),
3033
- subPaths: px.enum([PxTrimSubPaths.separate, PxTrimSubPaths.combined]).optional()
3034
+ subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined]).optional()
3034
3035
  }));
3035
3036
  var PxRetimeEffectSchema = implementsInterface()(px.object({
3036
3037
  sourceId: px.string().optional(),
@@ -3084,7 +3085,7 @@ var PixodeskAnimatorReact = (() => {
3084
3085
  repeater: PxRepeaterEffectSchema.optional(),
3085
3086
  maskedBy: PxMaskedByEffectSchema.optional(),
3086
3087
  clipPath: PxClipPathEffectSchema.optional(),
3087
- trimPath: PxTrimPathEffectSchema.optional(),
3088
+ strokeTrim: PxStrokeTrimEffectSchema.optional(),
3088
3089
  clone: PxCloneEffectSchema.optional(),
3089
3090
  fillGradient: PxFillGradientEffectSchema.optional(),
3090
3091
  strokeGradient: PxStrokeGradientEffectSchema.optional(),
@@ -6175,6 +6176,19 @@ var PixodeskAnimatorReact = (() => {
6175
6176
  TEXT_CONTENT_ATTR,
6176
6177
  "xml:space"
6177
6178
  ];
6179
+ var PAINT_STATIC_KEYS = [
6180
+ "fillOpacity",
6181
+ "fillRule",
6182
+ "strokeOpacity",
6183
+ "strokeDasharray",
6184
+ "strokeDashoffset",
6185
+ "strokeLinecap",
6186
+ "strokeLinejoin",
6187
+ "strokeMiterlimit",
6188
+ "mixBlendMode",
6189
+ "filter"
6190
+ ];
6191
+ var PAINT_ANIMATE_KEYS = ["fill", "stroke", "strokeWidth", "opacity", "fillOpacity", "strokeOpacity", "strokeDasharray", "strokeDashoffset"];
6178
6192
  function parseLen(v) {
6179
6193
  if (typeof v === "number") return v;
6180
6194
  if (typeof v === "string") {
@@ -6186,17 +6200,39 @@ var PixodeskAnimatorReact = (() => {
6186
6200
  function str(v) {
6187
6201
  return typeof v === "string" ? v : void 0;
6188
6202
  }
6203
+ function paintAnimateOf(node) {
6204
+ const bag = node.animate;
6205
+ if (!bag || typeof bag !== "object") return void 0;
6206
+ let out;
6207
+ for (const k of PAINT_ANIMATE_KEYS) {
6208
+ if (bag[k] !== void 0) (out != null ? out : out = {})[k] = bag[k];
6209
+ }
6210
+ return out;
6211
+ }
6189
6212
  function resolveStyle2(node, parent) {
6190
- var _a, _b, _c, _d, _e, _f, _g;
6191
- return {
6213
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
6214
+ const isTextRoot = node.type === "text";
6215
+ const nodeStyle = node.style;
6216
+ const own = (key) => {
6217
+ var _a2;
6218
+ return isTextRoot ? void 0 : (_a2 = node[key]) != null ? _a2 : nodeStyle == null ? void 0 : nodeStyle[key];
6219
+ };
6220
+ const res = {
6192
6221
  fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
6193
6222
  fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
6194
6223
  fill: (_c = node.fill) != null ? _c : parent.fill,
6195
6224
  stroke: (_d = node.stroke) != null ? _d : parent.stroke,
6196
6225
  strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
6197
6226
  letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
6198
- wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing
6227
+ wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing,
6228
+ opacity: (_h = parseLen(own("opacity"))) != null ? _h : parent.opacity,
6229
+ animate: (_i = isTextRoot ? void 0 : paintAnimateOf(node)) != null ? _i : parent.animate
6199
6230
  };
6231
+ for (const key of PAINT_STATIC_KEYS) {
6232
+ const v = (_j = own(key)) != null ? _j : parent[key];
6233
+ if (v !== void 0) res[key] = v;
6234
+ }
6235
+ return res;
6200
6236
  }
6201
6237
  function rootStyleOf(node) {
6202
6238
  var _a, _b, _c;
@@ -6215,6 +6251,11 @@ var PixodeskAnimatorReact = (() => {
6215
6251
  if (s.fill !== void 0) p.fill = s.fill;
6216
6252
  if (s.stroke !== void 0) p.stroke = s.stroke;
6217
6253
  if (s.strokeWidth !== void 0) p.strokeWidth = s.strokeWidth;
6254
+ if (s.opacity !== void 0 && s.opacity !== 1) p.opacity = s.opacity;
6255
+ for (const key of PAINT_STATIC_KEYS) {
6256
+ if (s[key] !== void 0) p[key] = s[key];
6257
+ }
6258
+ if (s.animate !== void 0) p.animate = s.animate;
6218
6259
  return p;
6219
6260
  }
6220
6261
  function glyphFontFor(s, glyphs, soleFont, warnings) {
@@ -6228,6 +6269,7 @@ var PixodeskAnimatorReact = (() => {
6228
6269
  return names.length === 1 ? glyphs[names[0]] : void 0;
6229
6270
  }
6230
6271
  var MISSING_GLYPH_ADVANCE_EM = 0.6;
6272
+ var MISSING_GLYPH_CLASS_NAME = "px-missing-glyph";
6231
6273
  function missingGlyphBoxEm(advanceEm, ascentEm) {
6232
6274
  if (advanceEm <= 0 || ascentEm <= 0) return "";
6233
6275
  const inset = 0.08;
@@ -6263,7 +6305,7 @@ var PixodeskAnimatorReact = (() => {
6263
6305
  pen.x += g.width * scale;
6264
6306
  } else if (/\S/.test(ch)) {
6265
6307
  const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
6266
- placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
6308
+ 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 });
6267
6309
  pen.x += advEm * scale;
6268
6310
  } else {
6269
6311
  pen.x += (g ? g.width : 0) * scale;
@@ -6326,7 +6368,7 @@ var PixodeskAnimatorReact = (() => {
6326
6368
  } else if (/\S/.test(ch)) {
6327
6369
  const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
6328
6370
  const boxAdv = wEm * scale;
6329
- cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, midBase: adv + boxAdv / 2 });
6371
+ cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, isMissing: true, midBase: adv + boxAdv / 2 });
6330
6372
  adv += boxAdv;
6331
6373
  } else {
6332
6374
  adv += (g ? g.width : 0) * scale;
@@ -6382,6 +6424,7 @@ var PixodeskAnimatorReact = (() => {
6382
6424
  const placements = placeCells.map((c) => ({
6383
6425
  glyphD: c.glyphD,
6384
6426
  paint: c.paint,
6427
+ isMissing: c.isMissing,
6385
6428
  m: alongAffine(sampler, base + c.midBase * k, c.scale, c.widthEm, perp)
6386
6429
  }));
6387
6430
  return toGroup(node, buildPaths(placements, create, warnings), create);
@@ -6470,12 +6513,13 @@ var PixodeskAnimatorReact = (() => {
6470
6513
  const transform = { keyframes: kfs };
6471
6514
  if (loop !== void 0) transform.loop = loop;
6472
6515
  const animate = { transform };
6516
+ if (c.paint.animate) Object.assign(animate, c.paint.animate);
6473
6517
  if (isClip && opKfs.some((k) => k.value === 0)) {
6474
6518
  const op = { keyframes: opKfs };
6475
6519
  if (loop !== void 0) op.loop = loop;
6476
6520
  animate.opacity = op;
6477
6521
  }
6478
- out.push(create("path", __spreadProps2(__spreadValues2({ d }, paintProps(c.paint)), { animate }), []));
6522
+ out.push(create("path", __spreadProps2(__spreadValues2(__spreadValues2({ d }, paintProps(c.paint)), missingGlyphProps(c.isMissing)), { animate }), []));
6479
6523
  }
6480
6524
  return out;
6481
6525
  }
@@ -6484,24 +6528,34 @@ var PixodeskAnimatorReact = (() => {
6484
6528
  if (paint.fill !== void 0) p.fill = paint.fill;
6485
6529
  if (paint.stroke !== void 0) p.stroke = paint.stroke;
6486
6530
  if (paint.strokeWidth !== void 0) p.strokeWidth = paint.strokeWidth;
6531
+ if (paint.opacity !== void 0) p.opacity = paint.opacity;
6532
+ for (const key of PAINT_STATIC_KEYS) {
6533
+ if (paint[key] !== void 0) p[key] = paint[key];
6534
+ }
6487
6535
  return p;
6488
6536
  }
6537
+ function missingGlyphProps(isMissing) {
6538
+ return isMissing ? { class: MISSING_GLYPH_CLASS_NAME } : {};
6539
+ }
6489
6540
  function buildPaths(placements, create, warnings) {
6490
- var _a, _b, _c;
6491
6541
  if (!placements.length) {
6492
6542
  warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
6493
6543
  return [];
6494
6544
  }
6495
6545
  const byPaint = /* @__PURE__ */ new Map();
6496
6546
  for (const p of placements) {
6497
- 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]);
6547
+ const key = JSON.stringify([p.paint, !!p.isMissing]);
6498
6548
  const baked = transformPathData(p.glyphD, p.m);
6499
6549
  const entry = byPaint.get(key);
6500
6550
  if (entry) entry.d += baked;
6501
- else byPaint.set(key, { paint: p.paint, d: baked });
6551
+ else byPaint.set(key, { paint: p.paint, d: baked, isMissing: p.isMissing });
6502
6552
  }
6503
6553
  const out = [];
6504
- for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues2({ d }, paintProps(paint)), []));
6554
+ for (const { paint, d, isMissing } of byPaint.values()) {
6555
+ out.push(create("path", __spreadValues2(__spreadValues2(__spreadValues2({
6556
+ d
6557
+ }, paintProps(paint)), missingGlyphProps(isMissing)), paint.animate !== void 0 ? { animate: __spreadValues2({}, paint.animate) } : {}), []));
6558
+ }
6505
6559
  return out;
6506
6560
  }
6507
6561
  function toGroup(node, children, create) {
@@ -6533,9 +6587,9 @@ var PixodeskAnimatorReact = (() => {
6533
6587
  }
6534
6588
  return materialiseGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
6535
6589
  }
6536
- function applyTrimPathEffect(node, trimPath, ctx) {
6537
- if (!trimPath) return node;
6538
- const combined = trimPath.subPaths === PxTrimSubPaths.combined;
6590
+ function applyStrokeTrimEffect(node, strokeTrim, ctx) {
6591
+ if (!strokeTrim) return node;
6592
+ const combined = strokeTrim.subPaths === PxStrokeTrimSubPaths.combined;
6539
6593
  const leafEntries = [];
6540
6594
  const measure = (n) => {
6541
6595
  if (Array.isArray(n.children) && n.children.length > 0) {
@@ -6566,9 +6620,9 @@ var PixodeskAnimatorReact = (() => {
6566
6620
  }
6567
6621
  const chainLengthPx = acc;
6568
6622
  if (combined && chainLengthPx < 1e-3) return node;
6569
- const offsetReadRaw = readAnimatable(trimPath.offset);
6623
+ const offsetReadRaw = readAnimatable(strokeTrim.offset);
6570
6624
  const offsetRead = offsetReadRaw.kind === "absent" ? { kind: "static", value: 0 } : offsetReadRaw;
6571
- const rangeReadRaw = readRangeWithCrossings(trimPath.range);
6625
+ const rangeReadRaw = readRangeWithCrossings(strokeTrim.range);
6572
6626
  const rangeRead = rangeReadRaw.kind === "absent" ? { kind: "static", value: [0, 1] } : rangeReadRaw;
6573
6627
  const offsetValues = readScalarValues(offsetRead);
6574
6628
  const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;
@@ -6898,7 +6952,7 @@ var PixodeskAnimatorReact = (() => {
6898
6952
  const originalId = typeof node.id === "string" ? node.id : void 0;
6899
6953
  const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
6900
6954
  if (!fx && !innerIdForContentRef) return node;
6901
- const { transformBy, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
6955
+ const { transformBy, repeater, maskedBy, clipPath, strokeTrim, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
6902
6956
  if (fx) delete node.effects;
6903
6957
  let n = node;
6904
6958
  let consumedByGlyphs = false;
@@ -6918,7 +6972,7 @@ var PixodeskAnimatorReact = (() => {
6918
6972
  if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
6919
6973
  n = applyFillGradientEffect(n, fillGradient, ctx);
6920
6974
  n = applyStrokeGradientEffect(n, strokeGradient, ctx);
6921
- n = applyTrimPathEffect(n, trimPath, ctx);
6975
+ n = applyStrokeTrimEffect(n, strokeTrim, ctx);
6922
6976
  n = applyRepeaterEffect(n, repeater, ctx);
6923
6977
  n = applyMaskedByEffect(n, maskedBy, transformBy, ctx);
6924
6978
  n = applyClipPathEffect(n, clipPath, ctx);
@@ -8002,8 +8056,11 @@ var PixodeskAnimatorReact = (() => {
8002
8056
  driver.refresh();
8003
8057
  return driver;
8004
8058
  }
8059
+ function pinScrollportHeight(svgRoot) {
8060
+ const scroller = findNearestScroller(svgRoot, "y");
8061
+ return scroller ? scroller.clientHeight : document.documentElement.clientHeight;
8062
+ }
8005
8063
  function applyScrollPin(svgRoot, scroll) {
8006
- var _a;
8007
8064
  const styled = svgRoot;
8008
8065
  if (!(scroll == null ? void 0 : scroll.pin) || !styled.style) return () => {
8009
8066
  };
@@ -8011,7 +8068,28 @@ var PixodeskAnimatorReact = (() => {
8011
8068
  const prevPosition = style.position;
8012
8069
  const prevTop = style.top;
8013
8070
  style.position = "sticky";
8014
- style.top = ((_a = scroll.pinTop) != null ? _a : 0) + "px";
8071
+ const alignFactor = scroll.pinAlign === "center" ? 0.5 : scroll.pinAlign === "bottom" ? 1 : 0;
8072
+ const applyTop = () => {
8073
+ var _a;
8074
+ const extra = (_a = scroll.pinTop) != null ? _a : 0;
8075
+ if (!alignFactor) {
8076
+ style.top = extra + "px";
8077
+ return;
8078
+ }
8079
+ const portSize = pinScrollportHeight(svgRoot);
8080
+ const ownSize = svgRoot.getBoundingClientRect().height;
8081
+ style.top = Math.round((portSize - ownSize) * alignFactor + extra) + "px";
8082
+ };
8083
+ applyTop();
8084
+ let resizeObserver = null;
8085
+ const onWindowResize = alignFactor ? applyTop : null;
8086
+ if (alignFactor) {
8087
+ if (onWindowResize) window.addEventListener("resize", onWindowResize);
8088
+ if (typeof ResizeObserver !== "undefined") {
8089
+ resizeObserver = new ResizeObserver(applyTop);
8090
+ resizeObserver.observe(svgRoot);
8091
+ }
8092
+ }
8015
8093
  let wrapper = null;
8016
8094
  const parent = svgRoot.parentElement;
8017
8095
  if (scroll.pinDistance && scroll.pinDistance > 0 && parent) {
@@ -8022,6 +8100,8 @@ var PixodeskAnimatorReact = (() => {
8022
8100
  wrapper.appendChild(svgRoot);
8023
8101
  }
8024
8102
  return () => {
8103
+ if (onWindowResize) window.removeEventListener("resize", onWindowResize);
8104
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
8025
8105
  style.position = prevPosition;
8026
8106
  style.top = prevTop;
8027
8107
  if (wrapper == null ? void 0 : wrapper.parentElement) {