@pixodesk/svg-animator-web 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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PxAnimatorAPI as PxAnimatorAPI$1, PxBasicAnimatorAPI as PxBasicAnimatorAPI$1, PxAnimatedSvgDocument, PxPlatformAdapter, PxAnimatorCallbacksConfig, PxTrigger, PxNode, PxDefs } from '@pixodesk/svg-animator-core';
2
- export { ApplyResult, COLOUR_ATTR_NAMES, ExtendPathOpts, ExtendedPath, FillMode, GlyphCharBox, GlyphCharBoxAlongPath, GlyphMaterialiseOpts, JsMode, KeysMatch, MaterialiseAllOptions, MotionPathMaterialisationOptions, MotionPathSample, OutAction, PX_ANIM_ATTR_NAME, PX_ANIM_SRC_ATTR_NAME, PX_TRANSFORM_PART_KEYS, PathPoint, PathSampler, PlaybackDirection, PxAnimatable, PxAnimatedSvgDocument, PxAnimatedSvgDocumentSchema, PxAnimationDefinition, PxAnimationDefinitionSchema, PxAnimatorCallbacksConfig, PxAnimatorConfig, PxAnimatorConfigSchema, PxAnimatorEngine, PxAnimatorMode, PxAttrValue, PxAttrValueSchema, PxBezierPath, PxBezierPathSchema, PxBinding, PxBindingSchema, PxCloneEffect, PxCloneEffectSchema, PxCreateElement, PxDefs, PxDefsSchema, PxEasingOrRefSchema, PxEffects, PxEffectsSchema, PxElementAnimation, PxElementAnimationSchema, PxFillGradientEffect, PxFillGradientEffectSchema, PxGlyph, PxGlyphFont, PxGradientSpreadMethod, PxGradientStop, PxGradientStopSchema, PxGradientType, PxGradientUnits, PxInfer, PxKeyframe, PxKeyframeSchema, PxKeyframeValueSchema, PxLoop, PxLoopSchema, PxMaskedByEffect, PxMaskedByEffectSchema, PxNode, PxNodeBase, PxNodeSchema, PxPlatformAdapter, PxPropertyAnimation, PxPropertyAnimationSchema, PxRepeaterEffect, PxRepeaterEffectSchema, PxRetimeEffect, PxRetimeEffectSchema, PxSchema, PxSchemaDesc, PxStrokeGradientEffect, PxStrokeGradientEffectSchema, PxSvgNode, PxSvgNodeExtra, PxTextEffectSchema, PxTextPathEffect, PxTextPathEffectSchema, PxTransformByEffect, PxTransformByEffectSchema, PxTransformPartKey, PxTransformParts, PxTransformPartsSchema, PxTransformValue, PxTransformValueSchema, PxTrigger, PxTriggerSchema, PxTrimPathEffect, PxTrimPathEffectSchema, PxValidationContext, PxValidationResult, RemoveIndex, STYLE_ATTR_NAMES, StartOn, TRANSFORM_FN_NAMES, Vec2, applyPlayerEffects, calcAnimationValues, camelCaseToKebabWordIfNeeded, collectSampleTimes, createBasicFrameLoopAnimator, createPathSampler, describeSchema, diffInEffect, evaluateMotionPathSegment, extendedPathForBrowser, generateNewIds, getAnimatorConfig, getBindings, getChildren, getDefs, getNormalizedProps, isPxElementFileFormat, isPxElementFileFormatDeep, jsonElementFactory, layoutGlyphTextChars, materialiseAllInTree, materialiseAnimatedUseInstances, materialiseGlyphText, materialiseGlyphTextAlongPath, materialiseGlyphTextHorizontal, materialiseInternalLoopsInPropAnim, materialiseInternalLoopsInTree, materialiseMotionPathInPropAnim, materialiseMotionPathsInTree, getNormalisedBindings as normalizeDocument, propAnimIsMotionPath, px, schemaKeys, shiftAnimatable, toRGBA, validateNodeEffects, visualModelAt } from '@pixodesk/svg-animator-core';
2
+ export { ApplyResult, COLOUR_ATTR_NAMES, ExtendPathOpts, ExtendedPath, FillMode, GlyphCharBox, GlyphCharBoxAlongPath, GlyphMaterialiseOpts, JsMode, KeysMatch, MISSING_GLYPH_CLASS_NAME, MaterialiseAllOptions, MotionPathMaterialisationOptions, MotionPathSample, OutAction, PX_ANIM_ATTR_NAME, PX_ANIM_SRC_ATTR_NAME, PX_TRANSFORM_PART_KEYS, PathPoint, PathSampler, PlaybackDirection, PxAnimatable, PxAnimatedSvgDocument, PxAnimatedSvgDocumentSchema, PxAnimationDefinition, PxAnimationDefinitionSchema, PxAnimatorCallbacksConfig, PxAnimatorConfig, PxAnimatorConfigSchema, PxAnimatorEngine, PxAnimatorMode, PxAttrValue, PxAttrValueSchema, PxBezierPath, PxBezierPathSchema, PxBinding, PxBindingSchema, PxCloneEffect, PxCloneEffectSchema, PxCreateElement, PxDefs, PxDefsSchema, PxEasingOrRefSchema, PxEffects, PxEffectsSchema, PxElementAnimation, PxElementAnimationSchema, PxFillGradientEffect, PxFillGradientEffectSchema, PxGlyph, PxGlyphFont, PxGradientSpreadMethod, PxGradientStop, PxGradientStopSchema, PxGradientType, PxGradientUnits, PxInfer, PxKeyframe, PxKeyframeSchema, PxKeyframeValueSchema, PxLoop, PxLoopSchema, PxMaskedByEffect, PxMaskedByEffectSchema, PxNode, PxNodeBase, PxNodeSchema, PxPlatformAdapter, PxPropertyAnimation, PxPropertyAnimationSchema, PxRepeaterEffect, PxRepeaterEffectSchema, PxRetimeEffect, PxRetimeEffectSchema, PxSchema, PxSchemaDesc, PxStrokeGradientEffect, PxStrokeGradientEffectSchema, PxSvgNode, PxSvgNodeExtra, PxTextEffectSchema, PxTextPathEffect, PxTextPathEffectSchema, PxTransformByEffect, PxTransformByEffectSchema, PxTransformPartKey, PxTransformParts, PxTransformPartsSchema, PxTransformValue, PxTransformValueSchema, PxTrigger, PxTriggerSchema, PxTrimPathEffect, PxTrimPathEffectSchema, PxValidationContext, PxValidationResult, RemoveIndex, STYLE_ATTR_NAMES, StartOn, TRANSFORM_FN_NAMES, Vec2, applyPlayerEffects, calcAnimationValues, camelCaseToKebabWordIfNeeded, collectSampleTimes, createBasicFrameLoopAnimator, createPathSampler, describeSchema, diffInEffect, evaluateMotionPathSegment, extendedPathForBrowser, generateNewIds, getAnimatorConfig, getBindings, getChildren, getDefs, getNormalizedProps, isPxElementFileFormat, isPxElementFileFormatDeep, jsonElementFactory, layoutGlyphTextChars, materialiseAllInTree, materialiseAnimatedUseInstances, materialiseGlyphText, materialiseGlyphTextAlongPath, materialiseGlyphTextHorizontal, materialiseInternalLoopsInPropAnim, materialiseInternalLoopsInTree, materialiseMotionPathInPropAnim, materialiseMotionPathsInTree, getNormalisedBindings as normalizeDocument, propAnimIsMotionPath, px, schemaKeys, shiftAnimatable, toRGBA, validateNodeEffects, visualModelAt } from '@pixodesk/svg-animator-core';
3
3
 
4
4
  /**
5
5
  * DOM specialisations of the platform-neutral animator API types.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PxAnimatorAPI as PxAnimatorAPI$1, PxBasicAnimatorAPI as PxBasicAnimatorAPI$1, PxAnimatedSvgDocument, PxPlatformAdapter, PxAnimatorCallbacksConfig, PxTrigger, PxNode, PxDefs } from '@pixodesk/svg-animator-core';
2
- export { ApplyResult, COLOUR_ATTR_NAMES, ExtendPathOpts, ExtendedPath, FillMode, GlyphCharBox, GlyphCharBoxAlongPath, GlyphMaterialiseOpts, JsMode, KeysMatch, MaterialiseAllOptions, MotionPathMaterialisationOptions, MotionPathSample, OutAction, PX_ANIM_ATTR_NAME, PX_ANIM_SRC_ATTR_NAME, PX_TRANSFORM_PART_KEYS, PathPoint, PathSampler, PlaybackDirection, PxAnimatable, PxAnimatedSvgDocument, PxAnimatedSvgDocumentSchema, PxAnimationDefinition, PxAnimationDefinitionSchema, PxAnimatorCallbacksConfig, PxAnimatorConfig, PxAnimatorConfigSchema, PxAnimatorEngine, PxAnimatorMode, PxAttrValue, PxAttrValueSchema, PxBezierPath, PxBezierPathSchema, PxBinding, PxBindingSchema, PxCloneEffect, PxCloneEffectSchema, PxCreateElement, PxDefs, PxDefsSchema, PxEasingOrRefSchema, PxEffects, PxEffectsSchema, PxElementAnimation, PxElementAnimationSchema, PxFillGradientEffect, PxFillGradientEffectSchema, PxGlyph, PxGlyphFont, PxGradientSpreadMethod, PxGradientStop, PxGradientStopSchema, PxGradientType, PxGradientUnits, PxInfer, PxKeyframe, PxKeyframeSchema, PxKeyframeValueSchema, PxLoop, PxLoopSchema, PxMaskedByEffect, PxMaskedByEffectSchema, PxNode, PxNodeBase, PxNodeSchema, PxPlatformAdapter, PxPropertyAnimation, PxPropertyAnimationSchema, PxRepeaterEffect, PxRepeaterEffectSchema, PxRetimeEffect, PxRetimeEffectSchema, PxSchema, PxSchemaDesc, PxStrokeGradientEffect, PxStrokeGradientEffectSchema, PxSvgNode, PxSvgNodeExtra, PxTextEffectSchema, PxTextPathEffect, PxTextPathEffectSchema, PxTransformByEffect, PxTransformByEffectSchema, PxTransformPartKey, PxTransformParts, PxTransformPartsSchema, PxTransformValue, PxTransformValueSchema, PxTrigger, PxTriggerSchema, PxTrimPathEffect, PxTrimPathEffectSchema, PxValidationContext, PxValidationResult, RemoveIndex, STYLE_ATTR_NAMES, StartOn, TRANSFORM_FN_NAMES, Vec2, applyPlayerEffects, calcAnimationValues, camelCaseToKebabWordIfNeeded, collectSampleTimes, createBasicFrameLoopAnimator, createPathSampler, describeSchema, diffInEffect, evaluateMotionPathSegment, extendedPathForBrowser, generateNewIds, getAnimatorConfig, getBindings, getChildren, getDefs, getNormalizedProps, isPxElementFileFormat, isPxElementFileFormatDeep, jsonElementFactory, layoutGlyphTextChars, materialiseAllInTree, materialiseAnimatedUseInstances, materialiseGlyphText, materialiseGlyphTextAlongPath, materialiseGlyphTextHorizontal, materialiseInternalLoopsInPropAnim, materialiseInternalLoopsInTree, materialiseMotionPathInPropAnim, materialiseMotionPathsInTree, getNormalisedBindings as normalizeDocument, propAnimIsMotionPath, px, schemaKeys, shiftAnimatable, toRGBA, validateNodeEffects, visualModelAt } from '@pixodesk/svg-animator-core';
2
+ export { ApplyResult, COLOUR_ATTR_NAMES, ExtendPathOpts, ExtendedPath, FillMode, GlyphCharBox, GlyphCharBoxAlongPath, GlyphMaterialiseOpts, JsMode, KeysMatch, MISSING_GLYPH_CLASS_NAME, MaterialiseAllOptions, MotionPathMaterialisationOptions, MotionPathSample, OutAction, PX_ANIM_ATTR_NAME, PX_ANIM_SRC_ATTR_NAME, PX_TRANSFORM_PART_KEYS, PathPoint, PathSampler, PlaybackDirection, PxAnimatable, PxAnimatedSvgDocument, PxAnimatedSvgDocumentSchema, PxAnimationDefinition, PxAnimationDefinitionSchema, PxAnimatorCallbacksConfig, PxAnimatorConfig, PxAnimatorConfigSchema, PxAnimatorEngine, PxAnimatorMode, PxAttrValue, PxAttrValueSchema, PxBezierPath, PxBezierPathSchema, PxBinding, PxBindingSchema, PxCloneEffect, PxCloneEffectSchema, PxCreateElement, PxDefs, PxDefsSchema, PxEasingOrRefSchema, PxEffects, PxEffectsSchema, PxElementAnimation, PxElementAnimationSchema, PxFillGradientEffect, PxFillGradientEffectSchema, PxGlyph, PxGlyphFont, PxGradientSpreadMethod, PxGradientStop, PxGradientStopSchema, PxGradientType, PxGradientUnits, PxInfer, PxKeyframe, PxKeyframeSchema, PxKeyframeValueSchema, PxLoop, PxLoopSchema, PxMaskedByEffect, PxMaskedByEffectSchema, PxNode, PxNodeBase, PxNodeSchema, PxPlatformAdapter, PxPropertyAnimation, PxPropertyAnimationSchema, PxRepeaterEffect, PxRepeaterEffectSchema, PxRetimeEffect, PxRetimeEffectSchema, PxSchema, PxSchemaDesc, PxStrokeGradientEffect, PxStrokeGradientEffectSchema, PxSvgNode, PxSvgNodeExtra, PxTextEffectSchema, PxTextPathEffect, PxTextPathEffectSchema, PxTransformByEffect, PxTransformByEffectSchema, PxTransformPartKey, PxTransformParts, PxTransformPartsSchema, PxTransformValue, PxTransformValueSchema, PxTrigger, PxTriggerSchema, PxTrimPathEffect, PxTrimPathEffectSchema, PxValidationContext, PxValidationResult, RemoveIndex, STYLE_ATTR_NAMES, StartOn, TRANSFORM_FN_NAMES, Vec2, applyPlayerEffects, calcAnimationValues, camelCaseToKebabWordIfNeeded, collectSampleTimes, createBasicFrameLoopAnimator, createPathSampler, describeSchema, diffInEffect, evaluateMotionPathSegment, extendedPathForBrowser, generateNewIds, getAnimatorConfig, getBindings, getChildren, getDefs, getNormalizedProps, isPxElementFileFormat, isPxElementFileFormatDeep, jsonElementFactory, layoutGlyphTextChars, materialiseAllInTree, materialiseAnimatedUseInstances, materialiseGlyphText, materialiseGlyphTextAlongPath, materialiseGlyphTextHorizontal, materialiseInternalLoopsInPropAnim, materialiseInternalLoopsInTree, materialiseMotionPathInPropAnim, materialiseMotionPathsInTree, getNormalisedBindings as normalizeDocument, propAnimIsMotionPath, px, schemaKeys, shiftAnimatable, toRGBA, validateNodeEffects, visualModelAt } from '@pixodesk/svg-animator-core';
3
3
 
4
4
  /**
5
5
  * DOM specialisations of the platform-neutral animator API types.
package/dist/index.js CHANGED
@@ -1211,6 +1211,7 @@ var PxScrollSchema = implementsInterface()(px.object({
1211
1211
  subject: px.string().optional(),
1212
1212
  smoothing: px.number().optional(),
1213
1213
  pin: px.boolean().optional(),
1214
+ pinAlign: px.enum(["top", "center", "bottom"]).optional(),
1214
1215
  pinTop: px.number().optional(),
1215
1216
  pinDistance: px.number().optional(),
1216
1217
  range: PxScrollRangeSchema.optional()
@@ -4445,6 +4446,19 @@ var TEXT_ATTR_KEYS = [
4445
4446
  TEXT_CONTENT_ATTR,
4446
4447
  "xml:space"
4447
4448
  ];
4449
+ var PAINT_STATIC_KEYS = [
4450
+ "fillOpacity",
4451
+ "fillRule",
4452
+ "strokeOpacity",
4453
+ "strokeDasharray",
4454
+ "strokeDashoffset",
4455
+ "strokeLinecap",
4456
+ "strokeLinejoin",
4457
+ "strokeMiterlimit",
4458
+ "mixBlendMode",
4459
+ "filter"
4460
+ ];
4461
+ var PAINT_ANIMATE_KEYS = ["fill", "stroke", "strokeWidth", "opacity", "fillOpacity", "strokeOpacity", "strokeDasharray", "strokeDashoffset"];
4448
4462
  function parseLen(v) {
4449
4463
  if (typeof v === "number") return v;
4450
4464
  if (typeof v === "string") {
@@ -4456,17 +4470,39 @@ function parseLen(v) {
4456
4470
  function str(v) {
4457
4471
  return typeof v === "string" ? v : void 0;
4458
4472
  }
4473
+ function paintAnimateOf(node) {
4474
+ const bag = node.animate;
4475
+ if (!bag || typeof bag !== "object") return void 0;
4476
+ let out;
4477
+ for (const k of PAINT_ANIMATE_KEYS) {
4478
+ if (bag[k] !== void 0) (out != null ? out : out = {})[k] = bag[k];
4479
+ }
4480
+ return out;
4481
+ }
4459
4482
  function resolveStyle2(node, parent) {
4460
- var _a, _b, _c, _d, _e, _f, _g;
4461
- return {
4483
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4484
+ const isTextRoot = node.type === "text";
4485
+ const nodeStyle = node.style;
4486
+ const own = (key) => {
4487
+ var _a2;
4488
+ return isTextRoot ? void 0 : (_a2 = node[key]) != null ? _a2 : nodeStyle == null ? void 0 : nodeStyle[key];
4489
+ };
4490
+ const res = {
4462
4491
  fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
4463
4492
  fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
4464
4493
  fill: (_c = node.fill) != null ? _c : parent.fill,
4465
4494
  stroke: (_d = node.stroke) != null ? _d : parent.stroke,
4466
4495
  strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
4467
4496
  letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
4468
- wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing
4497
+ wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing,
4498
+ opacity: (_h = parseLen(own("opacity"))) != null ? _h : parent.opacity,
4499
+ animate: (_i = isTextRoot ? void 0 : paintAnimateOf(node)) != null ? _i : parent.animate
4469
4500
  };
4501
+ for (const key of PAINT_STATIC_KEYS) {
4502
+ const v = (_j = own(key)) != null ? _j : parent[key];
4503
+ if (v !== void 0) res[key] = v;
4504
+ }
4505
+ return res;
4470
4506
  }
4471
4507
  function rootStyleOf(node) {
4472
4508
  var _a, _b, _c;
@@ -4485,6 +4521,11 @@ function paintOf(s) {
4485
4521
  if (s.fill !== void 0) p.fill = s.fill;
4486
4522
  if (s.stroke !== void 0) p.stroke = s.stroke;
4487
4523
  if (s.strokeWidth !== void 0) p.strokeWidth = s.strokeWidth;
4524
+ if (s.opacity !== void 0 && s.opacity !== 1) p.opacity = s.opacity;
4525
+ for (const key of PAINT_STATIC_KEYS) {
4526
+ if (s[key] !== void 0) p[key] = s[key];
4527
+ }
4528
+ if (s.animate !== void 0) p.animate = s.animate;
4488
4529
  return p;
4489
4530
  }
4490
4531
  function glyphFontFor(s, glyphs, soleFont, warnings) {
@@ -4498,6 +4539,7 @@ function soleFontOf(glyphs) {
4498
4539
  return names.length === 1 ? glyphs[names[0]] : void 0;
4499
4540
  }
4500
4541
  var MISSING_GLYPH_ADVANCE_EM = 0.6;
4542
+ var MISSING_GLYPH_CLASS_NAME = "px-missing-glyph";
4501
4543
  function missingGlyphBoxEm(advanceEm, ascentEm) {
4502
4544
  if (advanceEm <= 0 || ascentEm <= 0) return "";
4503
4545
  const inset = 0.08;
@@ -4533,7 +4575,7 @@ function materialiseGlyphTextHorizontal(node, opts) {
4533
4575
  pen.x += g.width * scale;
4534
4576
  } else if (/\S/.test(ch)) {
4535
4577
  const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
4536
- placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
4578
+ 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 });
4537
4579
  pen.x += advEm * scale;
4538
4580
  } else {
4539
4581
  pen.x += (g ? g.width : 0) * scale;
@@ -4724,7 +4766,7 @@ function collectAlongPathCells(node, glyphs, soleFont, warnings) {
4724
4766
  } else if (/\S/.test(ch)) {
4725
4767
  const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
4726
4768
  const boxAdv = wEm * scale;
4727
- cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, midBase: adv + boxAdv / 2 });
4769
+ cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, isMissing: true, midBase: adv + boxAdv / 2 });
4728
4770
  adv += boxAdv;
4729
4771
  } else {
4730
4772
  adv += (g ? g.width : 0) * scale;
@@ -4780,6 +4822,7 @@ function materialiseGlyphTextAlongPath(node, pathD, startOffset, opts, textLengt
4780
4822
  const placements = placeCells.map((c) => ({
4781
4823
  glyphD: c.glyphD,
4782
4824
  paint: c.paint,
4825
+ isMissing: c.isMissing,
4783
4826
  m: alongAffine(sampler, base + c.midBase * k, c.scale, c.widthEm, perp)
4784
4827
  }));
4785
4828
  return toGroup(node, buildPaths(placements, create, warnings), create);
@@ -4868,12 +4911,13 @@ function buildAnimatedAlongPath(cells, sampler, distOf, times, loop, create, isC
4868
4911
  const transform = { keyframes: kfs };
4869
4912
  if (loop !== void 0) transform.loop = loop;
4870
4913
  const animate = { transform };
4914
+ if (c.paint.animate) Object.assign(animate, c.paint.animate);
4871
4915
  if (isClip && opKfs.some((k) => k.value === 0)) {
4872
4916
  const op = { keyframes: opKfs };
4873
4917
  if (loop !== void 0) op.loop = loop;
4874
4918
  animate.opacity = op;
4875
4919
  }
4876
- out.push(create("path", __spreadProps2(__spreadValues2({ d }, paintProps(c.paint)), { animate }), []));
4920
+ out.push(create("path", __spreadProps2(__spreadValues2(__spreadValues2({ d }, paintProps(c.paint)), missingGlyphProps(c.isMissing)), { animate }), []));
4877
4921
  }
4878
4922
  return out;
4879
4923
  }
@@ -4882,24 +4926,34 @@ function paintProps(paint) {
4882
4926
  if (paint.fill !== void 0) p.fill = paint.fill;
4883
4927
  if (paint.stroke !== void 0) p.stroke = paint.stroke;
4884
4928
  if (paint.strokeWidth !== void 0) p.strokeWidth = paint.strokeWidth;
4929
+ if (paint.opacity !== void 0) p.opacity = paint.opacity;
4930
+ for (const key of PAINT_STATIC_KEYS) {
4931
+ if (paint[key] !== void 0) p[key] = paint[key];
4932
+ }
4885
4933
  return p;
4886
4934
  }
4935
+ function missingGlyphProps(isMissing) {
4936
+ return isMissing ? { class: MISSING_GLYPH_CLASS_NAME } : {};
4937
+ }
4887
4938
  function buildPaths(placements, create, warnings) {
4888
- var _a, _b, _c;
4889
4939
  if (!placements.length) {
4890
4940
  warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
4891
4941
  return [];
4892
4942
  }
4893
4943
  const byPaint = /* @__PURE__ */ new Map();
4894
4944
  for (const p of placements) {
4895
- 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]);
4945
+ const key = JSON.stringify([p.paint, !!p.isMissing]);
4896
4946
  const baked = transformPathData(p.glyphD, p.m);
4897
4947
  const entry = byPaint.get(key);
4898
4948
  if (entry) entry.d += baked;
4899
- else byPaint.set(key, { paint: p.paint, d: baked });
4949
+ else byPaint.set(key, { paint: p.paint, d: baked, isMissing: p.isMissing });
4900
4950
  }
4901
4951
  const out = [];
4902
- for (const { paint, d } of byPaint.values()) out.push(create("path", __spreadValues2({ d }, paintProps(paint)), []));
4952
+ for (const { paint, d, isMissing } of byPaint.values()) {
4953
+ out.push(create("path", __spreadValues2(__spreadValues2(__spreadValues2({
4954
+ d
4955
+ }, paintProps(paint)), missingGlyphProps(isMissing)), paint.animate !== void 0 ? { animate: __spreadValues2({}, paint.animate) } : {}), []));
4956
+ }
4903
4957
  return out;
4904
4958
  }
4905
4959
  function toGroup(node, children, create) {
@@ -6619,8 +6673,11 @@ function createScrollDriver(subject, config, onProgress) {
6619
6673
  driver.refresh();
6620
6674
  return driver;
6621
6675
  }
6676
+ function pinScrollportHeight(svgRoot) {
6677
+ const scroller = findNearestScroller(svgRoot, "y");
6678
+ return scroller ? scroller.clientHeight : document.documentElement.clientHeight;
6679
+ }
6622
6680
  function applyScrollPin(svgRoot, scroll) {
6623
- var _a;
6624
6681
  const styled = svgRoot;
6625
6682
  if (!(scroll == null ? void 0 : scroll.pin) || !styled.style) return () => {
6626
6683
  };
@@ -6628,7 +6685,28 @@ function applyScrollPin(svgRoot, scroll) {
6628
6685
  const prevPosition = style.position;
6629
6686
  const prevTop = style.top;
6630
6687
  style.position = "sticky";
6631
- style.top = ((_a = scroll.pinTop) != null ? _a : 0) + "px";
6688
+ const alignFactor = scroll.pinAlign === "center" ? 0.5 : scroll.pinAlign === "bottom" ? 1 : 0;
6689
+ const applyTop = () => {
6690
+ var _a;
6691
+ const extra = (_a = scroll.pinTop) != null ? _a : 0;
6692
+ if (!alignFactor) {
6693
+ style.top = extra + "px";
6694
+ return;
6695
+ }
6696
+ const portSize = pinScrollportHeight(svgRoot);
6697
+ const ownSize = svgRoot.getBoundingClientRect().height;
6698
+ style.top = Math.round((portSize - ownSize) * alignFactor + extra) + "px";
6699
+ };
6700
+ applyTop();
6701
+ let resizeObserver = null;
6702
+ const onWindowResize = alignFactor ? applyTop : null;
6703
+ if (alignFactor) {
6704
+ if (onWindowResize) window.addEventListener("resize", onWindowResize);
6705
+ if (typeof ResizeObserver !== "undefined") {
6706
+ resizeObserver = new ResizeObserver(applyTop);
6707
+ resizeObserver.observe(svgRoot);
6708
+ }
6709
+ }
6632
6710
  let wrapper = null;
6633
6711
  const parent = svgRoot.parentElement;
6634
6712
  if (scroll.pinDistance && scroll.pinDistance > 0 && parent) {
@@ -6639,6 +6717,8 @@ function applyScrollPin(svgRoot, scroll) {
6639
6717
  wrapper.appendChild(svgRoot);
6640
6718
  }
6641
6719
  return () => {
6720
+ if (onWindowResize) window.removeEventListener("resize", onWindowResize);
6721
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
6642
6722
  style.position = prevPosition;
6643
6723
  style.top = prevTop;
6644
6724
  if (wrapper == null ? void 0 : wrapper.parentElement) {
@@ -6905,6 +6985,7 @@ if (typeof window !== "undefined") {
6905
6985
  }
6906
6986
  export {
6907
6987
  COLOUR_ATTR_NAMES,
6988
+ MISSING_GLYPH_CLASS_NAME,
6908
6989
  PX_ANIMATOR_DATA_KEY,
6909
6990
  PX_ANIM_ATTR_NAME,
6910
6991
  PX_ANIM_SRC_ATTR_NAME,