@pixodesk/svg-animator-react 1.0.27 → 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.umd.js CHANGED
@@ -2941,6 +2941,13 @@ var PixodeskAnimatorReact = (() => {
2941
2941
  kind: px.enum(["view", "scroll"]).optional(),
2942
2942
  axis: px.enum(["block", "inline", "x", "y"]).optional(),
2943
2943
  source: px.enum(["nearest", "root"]).optional(),
2944
+ // Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
2945
+ subject: px.string().optional(),
2946
+ smoothing: px.number().optional(),
2947
+ pin: px.boolean().optional(),
2948
+ pinAlign: px.enum(["top", "center", "bottom"]).optional(),
2949
+ pinTop: px.number().optional(),
2950
+ pinDistance: px.number().optional(),
2944
2951
  range: PxScrollRangeSchema.optional()
2945
2952
  }));
2946
2953
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
@@ -6169,6 +6176,19 @@ var PixodeskAnimatorReact = (() => {
6169
6176
  TEXT_CONTENT_ATTR,
6170
6177
  "xml:space"
6171
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"];
6172
6192
  function parseLen(v) {
6173
6193
  if (typeof v === "number") return v;
6174
6194
  if (typeof v === "string") {
@@ -6180,17 +6200,39 @@ var PixodeskAnimatorReact = (() => {
6180
6200
  function str(v) {
6181
6201
  return typeof v === "string" ? v : void 0;
6182
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
+ }
6183
6212
  function resolveStyle2(node, parent) {
6184
- var _a, _b, _c, _d, _e, _f, _g;
6185
- 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 = {
6186
6221
  fontFamily: (_a = str(node.fontFamily)) != null ? _a : parent.fontFamily,
6187
6222
  fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
6188
6223
  fill: (_c = node.fill) != null ? _c : parent.fill,
6189
6224
  stroke: (_d = node.stroke) != null ? _d : parent.stroke,
6190
6225
  strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
6191
6226
  letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
6192
- 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
6193
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;
6194
6236
  }
6195
6237
  function rootStyleOf(node) {
6196
6238
  var _a, _b, _c;
@@ -6209,6 +6251,11 @@ var PixodeskAnimatorReact = (() => {
6209
6251
  if (s.fill !== void 0) p.fill = s.fill;
6210
6252
  if (s.stroke !== void 0) p.stroke = s.stroke;
6211
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;
6212
6259
  return p;
6213
6260
  }
6214
6261
  function glyphFontFor(s, glyphs, soleFont, warnings) {
@@ -6222,6 +6269,7 @@ var PixodeskAnimatorReact = (() => {
6222
6269
  return names.length === 1 ? glyphs[names[0]] : void 0;
6223
6270
  }
6224
6271
  var MISSING_GLYPH_ADVANCE_EM = 0.6;
6272
+ var MISSING_GLYPH_CLASS_NAME = "px-missing-glyph";
6225
6273
  function missingGlyphBoxEm(advanceEm, ascentEm) {
6226
6274
  if (advanceEm <= 0 || ascentEm <= 0) return "";
6227
6275
  const inset = 0.08;
@@ -6257,7 +6305,7 @@ var PixodeskAnimatorReact = (() => {
6257
6305
  pen.x += g.width * scale;
6258
6306
  } else if (/\S/.test(ch)) {
6259
6307
  const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
6260
- 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 });
6261
6309
  pen.x += advEm * scale;
6262
6310
  } else {
6263
6311
  pen.x += (g ? g.width : 0) * scale;
@@ -6320,7 +6368,7 @@ var PixodeskAnimatorReact = (() => {
6320
6368
  } else if (/\S/.test(ch)) {
6321
6369
  const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
6322
6370
  const boxAdv = wEm * scale;
6323
- 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 });
6324
6372
  adv += boxAdv;
6325
6373
  } else {
6326
6374
  adv += (g ? g.width : 0) * scale;
@@ -6376,6 +6424,7 @@ var PixodeskAnimatorReact = (() => {
6376
6424
  const placements = placeCells.map((c) => ({
6377
6425
  glyphD: c.glyphD,
6378
6426
  paint: c.paint,
6427
+ isMissing: c.isMissing,
6379
6428
  m: alongAffine(sampler, base + c.midBase * k, c.scale, c.widthEm, perp)
6380
6429
  }));
6381
6430
  return toGroup(node, buildPaths(placements, create, warnings), create);
@@ -6464,12 +6513,13 @@ var PixodeskAnimatorReact = (() => {
6464
6513
  const transform = { keyframes: kfs };
6465
6514
  if (loop !== void 0) transform.loop = loop;
6466
6515
  const animate = { transform };
6516
+ if (c.paint.animate) Object.assign(animate, c.paint.animate);
6467
6517
  if (isClip && opKfs.some((k) => k.value === 0)) {
6468
6518
  const op = { keyframes: opKfs };
6469
6519
  if (loop !== void 0) op.loop = loop;
6470
6520
  animate.opacity = op;
6471
6521
  }
6472
- 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 }), []));
6473
6523
  }
6474
6524
  return out;
6475
6525
  }
@@ -6478,24 +6528,34 @@ var PixodeskAnimatorReact = (() => {
6478
6528
  if (paint.fill !== void 0) p.fill = paint.fill;
6479
6529
  if (paint.stroke !== void 0) p.stroke = paint.stroke;
6480
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
+ }
6481
6535
  return p;
6482
6536
  }
6537
+ function missingGlyphProps(isMissing) {
6538
+ return isMissing ? { class: MISSING_GLYPH_CLASS_NAME } : {};
6539
+ }
6483
6540
  function buildPaths(placements, create, warnings) {
6484
- var _a, _b, _c;
6485
6541
  if (!placements.length) {
6486
6542
  warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
6487
6543
  return [];
6488
6544
  }
6489
6545
  const byPaint = /* @__PURE__ */ new Map();
6490
6546
  for (const p of placements) {
6491
- 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]);
6492
6548
  const baked = transformPathData(p.glyphD, p.m);
6493
6549
  const entry = byPaint.get(key);
6494
6550
  if (entry) entry.d += baked;
6495
- else byPaint.set(key, { paint: p.paint, d: baked });
6551
+ else byPaint.set(key, { paint: p.paint, d: baked, isMissing: p.isMissing });
6496
6552
  }
6497
6553
  const out = [];
6498
- 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
+ }
6499
6559
  return out;
6500
6560
  }
6501
6561
  function toGroup(node, children, create) {
@@ -7814,6 +7874,10 @@ var PixodeskAnimatorReact = (() => {
7814
7874
  if (!config || !isScrollTimeline(config)) return null;
7815
7875
  const scroll = config.scroll || {};
7816
7876
  const kind = (_a = scroll.kind) != null ? _a : "view";
7877
+ if (scroll.smoothing) {
7878
+ console.warn('scroll timeline: `smoothing` needs the built-in driver \u2014 ignoring `driver: "native"`');
7879
+ return null;
7880
+ }
7817
7881
  const g = globalThis;
7818
7882
  const view = kind === "view";
7819
7883
  const Ctor = view ? g.ViewTimeline : g.ScrollTimeline;
@@ -7822,7 +7886,7 @@ var PixodeskAnimatorReact = (() => {
7822
7886
  let timeline;
7823
7887
  try {
7824
7888
  if (view) {
7825
- timeline = new Ctor({ subject, axis });
7889
+ timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject), axis });
7826
7890
  } else {
7827
7891
  const source = scroll.source === "root" ? documentScroller() : findNearestScroller(subject, "y") || findNearestScroller(subject, "x") || documentScroller();
7828
7892
  timeline = new Ctor({ source, axis });
@@ -7838,7 +7902,10 @@ var PixodeskAnimatorReact = (() => {
7838
7902
  };
7839
7903
  }
7840
7904
  function findNearestScroller(el, axis) {
7905
+ const body = document.body;
7906
+ const root = document.documentElement;
7841
7907
  for (let p = el.parentElement; p; p = p.parentElement) {
7908
+ if (p === body || p === root) return null;
7842
7909
  const style = getComputedStyle(p);
7843
7910
  const overflow = axis === "y" ? style.overflowY : style.overflowX;
7844
7911
  if (overflow === "auto" || overflow === "scroll" || overflow === "hidden" || overflow === "overlay") {
@@ -7850,11 +7917,42 @@ var PixodeskAnimatorReact = (() => {
7850
7917
  function documentScroller() {
7851
7918
  return document.scrollingElement || document.documentElement;
7852
7919
  }
7920
+ var SUBJECT_PARENT = "parent";
7921
+ var SUBJECT_SCROLLER = "scroller";
7922
+ function resolveScrollSubject(svgRoot, subject) {
7923
+ var _a, _b;
7924
+ const spec = subject == null ? void 0 : subject.trim();
7925
+ if (!spec) return svgRoot;
7926
+ if (spec === SUBJECT_PARENT) {
7927
+ let outermostPinned = null;
7928
+ for (let p = svgRoot.parentElement; p && p !== document.body; p = p.parentElement) {
7929
+ const position = getComputedStyle(p).position;
7930
+ if (position === "sticky" || position === "fixed") outermostPinned = p;
7931
+ }
7932
+ return (_b = (_a = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a : svgRoot.parentElement) != null ? _b : svgRoot;
7933
+ }
7934
+ if (spec === SUBJECT_SCROLLER) {
7935
+ return findNearestScroller(svgRoot, "y") || findNearestScroller(svgRoot, "x") || documentScroller();
7936
+ }
7937
+ let found = null;
7938
+ try {
7939
+ found = document.querySelector(spec);
7940
+ } catch (e) {
7941
+ console.warn('scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
7942
+ return svgRoot;
7943
+ }
7944
+ if (!found) {
7945
+ console.warn('scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
7946
+ return svgRoot;
7947
+ }
7948
+ return found;
7949
+ }
7853
7950
  function createScrollDriver(subject, config, onProgress) {
7854
- var _a;
7951
+ var _a, _b;
7855
7952
  if (!config || !isScrollTimeline(config)) return null;
7856
7953
  const scroll = config.scroll || {};
7857
7954
  const kind = (_a = scroll.kind) != null ? _a : "view";
7955
+ const measured = resolveScrollSubject(subject, scroll.subject);
7858
7956
  const nearest = findNearestScroller(subject, "y") || findNearestScroller(subject, "x");
7859
7957
  const scroller = kind === "scroll" && scroll.source === "root" ? documentScroller() : nearest || documentScroller();
7860
7958
  const isRootScroller = scroller === documentScroller();
@@ -7865,7 +7963,7 @@ var PixodeskAnimatorReact = (() => {
7865
7963
  const maxOffset = axis === "y" ? scroller.scrollHeight - scroller.clientHeight : scroller.scrollWidth - scroller.clientWidth;
7866
7964
  return scrollOffsetProgress(offset, maxOffset, scroll.range);
7867
7965
  }
7868
- const subjectRect = subject.getBoundingClientRect();
7966
+ const subjectRect = measured.getBoundingClientRect();
7869
7967
  let portStart, portSize;
7870
7968
  if (isRootScroller) {
7871
7969
  portStart = 0;
@@ -7879,12 +7977,43 @@ var PixodeskAnimatorReact = (() => {
7879
7977
  const subjectSize = axis === "y" ? subjectRect.height : subjectRect.width;
7880
7978
  return scrollViewProgress(subjectStart, subjectSize, portSize, scroll.range);
7881
7979
  };
7882
- let rafId = null;
7980
+ const smoothingSec = Math.max(0, (_b = scroll.smoothing) != null ? _b : 0) / 1e3;
7981
+ const SETTLE_EPSILON = 1e-3;
7883
7982
  let destroyed = false;
7983
+ let smoothed = null;
7984
+ let smoothRaf = null;
7985
+ let lastFrameMs = 0;
7986
+ const emit = (target) => {
7987
+ if (!smoothingSec) {
7988
+ onProgress(target);
7989
+ return;
7990
+ }
7991
+ if (smoothed === null) {
7992
+ smoothed = target;
7993
+ onProgress(target);
7994
+ return;
7995
+ }
7996
+ if (smoothRaf !== null) return;
7997
+ lastFrameMs = 0;
7998
+ const step = (nowMs) => {
7999
+ smoothRaf = null;
8000
+ if (destroyed) return;
8001
+ const dtSec = lastFrameMs ? Math.min(0.1, (nowMs - lastFrameMs) / 1e3) : 1 / 60;
8002
+ lastFrameMs = nowMs;
8003
+ const goal = compute();
8004
+ const k = 1 - Math.exp(-dtSec / smoothingSec);
8005
+ smoothed = smoothed + (goal - smoothed) * k;
8006
+ if (Math.abs(goal - smoothed) < SETTLE_EPSILON) smoothed = goal;
8007
+ onProgress(smoothed);
8008
+ if (smoothed !== goal) smoothRaf = requestAnimationFrame(step);
8009
+ };
8010
+ smoothRaf = requestAnimationFrame(step);
8011
+ };
8012
+ let rafId = null;
7884
8013
  const tick = () => {
7885
8014
  rafId = null;
7886
8015
  if (destroyed) return;
7887
- onProgress(compute());
8016
+ emit(compute());
7888
8017
  };
7889
8018
  const schedule = () => {
7890
8019
  if (destroyed || rafId !== null) return;
@@ -7896,7 +8025,8 @@ var PixodeskAnimatorReact = (() => {
7896
8025
  let resizeObserver;
7897
8026
  if (typeof ResizeObserver !== "undefined") {
7898
8027
  resizeObserver = new ResizeObserver(schedule);
7899
- resizeObserver.observe(subject);
8028
+ resizeObserver.observe(measured);
8029
+ if (measured !== subject) resizeObserver.observe(subject);
7900
8030
  if (!isRootScroller) resizeObserver.observe(scroller);
7901
8031
  }
7902
8032
  const driver = {
@@ -7910,14 +8040,76 @@ var PixodeskAnimatorReact = (() => {
7910
8040
  cancelAnimationFrame(rafId);
7911
8041
  rafId = null;
7912
8042
  }
8043
+ if (smoothRaf !== null) {
8044
+ cancelAnimationFrame(smoothRaf);
8045
+ smoothRaf = null;
8046
+ }
7913
8047
  },
8048
+ // `refresh` is a deliberate JUMP (attach, host relayout) — never eased.
7914
8049
  refresh: () => {
7915
- if (!destroyed) onProgress(compute());
8050
+ if (!destroyed) {
8051
+ smoothed = compute();
8052
+ onProgress(smoothed);
8053
+ }
7916
8054
  }
7917
8055
  };
7918
8056
  driver.refresh();
7919
8057
  return driver;
7920
8058
  }
8059
+ function pinScrollportHeight(svgRoot) {
8060
+ const scroller = findNearestScroller(svgRoot, "y");
8061
+ return scroller ? scroller.clientHeight : document.documentElement.clientHeight;
8062
+ }
8063
+ function applyScrollPin(svgRoot, scroll) {
8064
+ const styled = svgRoot;
8065
+ if (!(scroll == null ? void 0 : scroll.pin) || !styled.style) return () => {
8066
+ };
8067
+ const style = styled.style;
8068
+ const prevPosition = style.position;
8069
+ const prevTop = style.top;
8070
+ style.position = "sticky";
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
+ }
8093
+ let wrapper = null;
8094
+ const parent = svgRoot.parentElement;
8095
+ if (scroll.pinDistance && scroll.pinDistance > 0 && parent) {
8096
+ wrapper = document.createElement("div");
8097
+ wrapper.setAttribute("data-px-pin", "");
8098
+ wrapper.style.height = scroll.pinDistance * 100 + "vh";
8099
+ parent.insertBefore(wrapper, svgRoot);
8100
+ wrapper.appendChild(svgRoot);
8101
+ }
8102
+ return () => {
8103
+ if (onWindowResize) window.removeEventListener("resize", onWindowResize);
8104
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
8105
+ style.position = prevPosition;
8106
+ style.top = prevTop;
8107
+ if (wrapper == null ? void 0 : wrapper.parentElement) {
8108
+ wrapper.parentElement.insertBefore(svgRoot, wrapper);
8109
+ wrapper.remove();
8110
+ }
8111
+ };
8112
+ }
7921
8113
  function finaliseAnimator(animatorConfig, callbacks, make) {
7922
8114
  let apiRef;
7923
8115
  let effectiveCallbacks = callbacks;
@@ -7942,7 +8134,10 @@ var PixodeskAnimatorReact = (() => {
7942
8134
  if (isScrollTimeline(animatorConfig)) {
7943
8135
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
7944
8136
  var _a, _b;
8137
+ let unpin = () => {
8138
+ };
7945
8139
  if (animatorConfig.mode !== PxAnimatorMode.frames && ((_a = animatorConfig.scroll) == null ? void 0 : _a.driver) === "native" && rootElement) {
8140
+ unpin = applyScrollPin(rootElement, animatorConfig.scroll);
7946
8141
  const native = createNativeScrollTimeline(rootElement, animatorConfig);
7947
8142
  if (native) {
7948
8143
  const api2 = createWebApiAnimator(
@@ -7952,12 +8147,23 @@ var PixodeskAnimatorReact = (() => {
7952
8147
  animatorConfig.mode === PxAnimatorMode.waapi,
7953
8148
  native
7954
8149
  );
7955
- if (api2) return api2;
8150
+ if (api2) {
8151
+ const destroyNative = api2.destroy.bind(api2);
8152
+ api2.destroy = () => {
8153
+ unpin();
8154
+ destroyNative();
8155
+ };
8156
+ return api2;
8157
+ }
7956
8158
  }
8159
+ unpin();
8160
+ unpin = () => {
8161
+ };
7957
8162
  }
7958
8163
  const api = (animatorConfig.mode !== PxAnimatorMode.frames ? createWebApiAnimator(doc, cb, rootElement, animatorConfig.mode === PxAnimatorMode.waapi) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
7959
8164
  const subject = ((_b = api.getRootElement) == null ? void 0 : _b.call(api)) || rootElement;
7960
8165
  if (subject) {
8166
+ unpin = applyScrollPin(subject, animatorConfig.scroll);
7961
8167
  const totalMs = scrollTotalDurationMs(animatorConfig);
7962
8168
  const driver = createScrollDriver(
7963
8169
  subject,
@@ -7968,6 +8174,7 @@ var PixodeskAnimatorReact = (() => {
7968
8174
  const destroy = api.destroy.bind(api);
7969
8175
  api.destroy = () => {
7970
8176
  driver.destroy();
8177
+ unpin();
7971
8178
  destroy();
7972
8179
  };
7973
8180
  }