@pixodesk/svg-animator-react 1.0.27 → 1.0.28
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 +135 -8
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.umd.js
CHANGED
|
@@ -2941,6 +2941,12 @@ 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
|
+
pinTop: px.number().optional(),
|
|
2949
|
+
pinDistance: px.number().optional(),
|
|
2944
2950
|
range: PxScrollRangeSchema.optional()
|
|
2945
2951
|
}));
|
|
2946
2952
|
var PxAnimatorConfigSchema = implementsInterface()(px.object({
|
|
@@ -7814,6 +7820,10 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7814
7820
|
if (!config || !isScrollTimeline(config)) return null;
|
|
7815
7821
|
const scroll = config.scroll || {};
|
|
7816
7822
|
const kind = (_a = scroll.kind) != null ? _a : "view";
|
|
7823
|
+
if (scroll.smoothing) {
|
|
7824
|
+
console.warn('scroll timeline: `smoothing` needs the built-in driver \u2014 ignoring `driver: "native"`');
|
|
7825
|
+
return null;
|
|
7826
|
+
}
|
|
7817
7827
|
const g = globalThis;
|
|
7818
7828
|
const view = kind === "view";
|
|
7819
7829
|
const Ctor = view ? g.ViewTimeline : g.ScrollTimeline;
|
|
@@ -7822,7 +7832,7 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7822
7832
|
let timeline;
|
|
7823
7833
|
try {
|
|
7824
7834
|
if (view) {
|
|
7825
|
-
timeline = new Ctor({ subject, axis });
|
|
7835
|
+
timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject), axis });
|
|
7826
7836
|
} else {
|
|
7827
7837
|
const source = scroll.source === "root" ? documentScroller() : findNearestScroller(subject, "y") || findNearestScroller(subject, "x") || documentScroller();
|
|
7828
7838
|
timeline = new Ctor({ source, axis });
|
|
@@ -7838,7 +7848,10 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7838
7848
|
};
|
|
7839
7849
|
}
|
|
7840
7850
|
function findNearestScroller(el, axis) {
|
|
7851
|
+
const body = document.body;
|
|
7852
|
+
const root = document.documentElement;
|
|
7841
7853
|
for (let p = el.parentElement; p; p = p.parentElement) {
|
|
7854
|
+
if (p === body || p === root) return null;
|
|
7842
7855
|
const style = getComputedStyle(p);
|
|
7843
7856
|
const overflow = axis === "y" ? style.overflowY : style.overflowX;
|
|
7844
7857
|
if (overflow === "auto" || overflow === "scroll" || overflow === "hidden" || overflow === "overlay") {
|
|
@@ -7850,11 +7863,42 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7850
7863
|
function documentScroller() {
|
|
7851
7864
|
return document.scrollingElement || document.documentElement;
|
|
7852
7865
|
}
|
|
7866
|
+
var SUBJECT_PARENT = "parent";
|
|
7867
|
+
var SUBJECT_SCROLLER = "scroller";
|
|
7868
|
+
function resolveScrollSubject(svgRoot, subject) {
|
|
7869
|
+
var _a, _b;
|
|
7870
|
+
const spec = subject == null ? void 0 : subject.trim();
|
|
7871
|
+
if (!spec) return svgRoot;
|
|
7872
|
+
if (spec === SUBJECT_PARENT) {
|
|
7873
|
+
let outermostPinned = null;
|
|
7874
|
+
for (let p = svgRoot.parentElement; p && p !== document.body; p = p.parentElement) {
|
|
7875
|
+
const position = getComputedStyle(p).position;
|
|
7876
|
+
if (position === "sticky" || position === "fixed") outermostPinned = p;
|
|
7877
|
+
}
|
|
7878
|
+
return (_b = (_a = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a : svgRoot.parentElement) != null ? _b : svgRoot;
|
|
7879
|
+
}
|
|
7880
|
+
if (spec === SUBJECT_SCROLLER) {
|
|
7881
|
+
return findNearestScroller(svgRoot, "y") || findNearestScroller(svgRoot, "x") || documentScroller();
|
|
7882
|
+
}
|
|
7883
|
+
let found = null;
|
|
7884
|
+
try {
|
|
7885
|
+
found = document.querySelector(spec);
|
|
7886
|
+
} catch (e) {
|
|
7887
|
+
console.warn('scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
|
|
7888
|
+
return svgRoot;
|
|
7889
|
+
}
|
|
7890
|
+
if (!found) {
|
|
7891
|
+
console.warn('scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
|
|
7892
|
+
return svgRoot;
|
|
7893
|
+
}
|
|
7894
|
+
return found;
|
|
7895
|
+
}
|
|
7853
7896
|
function createScrollDriver(subject, config, onProgress) {
|
|
7854
|
-
var _a;
|
|
7897
|
+
var _a, _b;
|
|
7855
7898
|
if (!config || !isScrollTimeline(config)) return null;
|
|
7856
7899
|
const scroll = config.scroll || {};
|
|
7857
7900
|
const kind = (_a = scroll.kind) != null ? _a : "view";
|
|
7901
|
+
const measured = resolveScrollSubject(subject, scroll.subject);
|
|
7858
7902
|
const nearest = findNearestScroller(subject, "y") || findNearestScroller(subject, "x");
|
|
7859
7903
|
const scroller = kind === "scroll" && scroll.source === "root" ? documentScroller() : nearest || documentScroller();
|
|
7860
7904
|
const isRootScroller = scroller === documentScroller();
|
|
@@ -7865,7 +7909,7 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7865
7909
|
const maxOffset = axis === "y" ? scroller.scrollHeight - scroller.clientHeight : scroller.scrollWidth - scroller.clientWidth;
|
|
7866
7910
|
return scrollOffsetProgress(offset, maxOffset, scroll.range);
|
|
7867
7911
|
}
|
|
7868
|
-
const subjectRect =
|
|
7912
|
+
const subjectRect = measured.getBoundingClientRect();
|
|
7869
7913
|
let portStart, portSize;
|
|
7870
7914
|
if (isRootScroller) {
|
|
7871
7915
|
portStart = 0;
|
|
@@ -7879,12 +7923,43 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7879
7923
|
const subjectSize = axis === "y" ? subjectRect.height : subjectRect.width;
|
|
7880
7924
|
return scrollViewProgress(subjectStart, subjectSize, portSize, scroll.range);
|
|
7881
7925
|
};
|
|
7882
|
-
|
|
7926
|
+
const smoothingSec = Math.max(0, (_b = scroll.smoothing) != null ? _b : 0) / 1e3;
|
|
7927
|
+
const SETTLE_EPSILON = 1e-3;
|
|
7883
7928
|
let destroyed = false;
|
|
7929
|
+
let smoothed = null;
|
|
7930
|
+
let smoothRaf = null;
|
|
7931
|
+
let lastFrameMs = 0;
|
|
7932
|
+
const emit = (target) => {
|
|
7933
|
+
if (!smoothingSec) {
|
|
7934
|
+
onProgress(target);
|
|
7935
|
+
return;
|
|
7936
|
+
}
|
|
7937
|
+
if (smoothed === null) {
|
|
7938
|
+
smoothed = target;
|
|
7939
|
+
onProgress(target);
|
|
7940
|
+
return;
|
|
7941
|
+
}
|
|
7942
|
+
if (smoothRaf !== null) return;
|
|
7943
|
+
lastFrameMs = 0;
|
|
7944
|
+
const step = (nowMs) => {
|
|
7945
|
+
smoothRaf = null;
|
|
7946
|
+
if (destroyed) return;
|
|
7947
|
+
const dtSec = lastFrameMs ? Math.min(0.1, (nowMs - lastFrameMs) / 1e3) : 1 / 60;
|
|
7948
|
+
lastFrameMs = nowMs;
|
|
7949
|
+
const goal = compute();
|
|
7950
|
+
const k = 1 - Math.exp(-dtSec / smoothingSec);
|
|
7951
|
+
smoothed = smoothed + (goal - smoothed) * k;
|
|
7952
|
+
if (Math.abs(goal - smoothed) < SETTLE_EPSILON) smoothed = goal;
|
|
7953
|
+
onProgress(smoothed);
|
|
7954
|
+
if (smoothed !== goal) smoothRaf = requestAnimationFrame(step);
|
|
7955
|
+
};
|
|
7956
|
+
smoothRaf = requestAnimationFrame(step);
|
|
7957
|
+
};
|
|
7958
|
+
let rafId = null;
|
|
7884
7959
|
const tick = () => {
|
|
7885
7960
|
rafId = null;
|
|
7886
7961
|
if (destroyed) return;
|
|
7887
|
-
|
|
7962
|
+
emit(compute());
|
|
7888
7963
|
};
|
|
7889
7964
|
const schedule = () => {
|
|
7890
7965
|
if (destroyed || rafId !== null) return;
|
|
@@ -7896,7 +7971,8 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7896
7971
|
let resizeObserver;
|
|
7897
7972
|
if (typeof ResizeObserver !== "undefined") {
|
|
7898
7973
|
resizeObserver = new ResizeObserver(schedule);
|
|
7899
|
-
resizeObserver.observe(
|
|
7974
|
+
resizeObserver.observe(measured);
|
|
7975
|
+
if (measured !== subject) resizeObserver.observe(subject);
|
|
7900
7976
|
if (!isRootScroller) resizeObserver.observe(scroller);
|
|
7901
7977
|
}
|
|
7902
7978
|
const driver = {
|
|
@@ -7910,14 +7986,50 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7910
7986
|
cancelAnimationFrame(rafId);
|
|
7911
7987
|
rafId = null;
|
|
7912
7988
|
}
|
|
7989
|
+
if (smoothRaf !== null) {
|
|
7990
|
+
cancelAnimationFrame(smoothRaf);
|
|
7991
|
+
smoothRaf = null;
|
|
7992
|
+
}
|
|
7913
7993
|
},
|
|
7994
|
+
// `refresh` is a deliberate JUMP (attach, host relayout) — never eased.
|
|
7914
7995
|
refresh: () => {
|
|
7915
|
-
if (!destroyed)
|
|
7996
|
+
if (!destroyed) {
|
|
7997
|
+
smoothed = compute();
|
|
7998
|
+
onProgress(smoothed);
|
|
7999
|
+
}
|
|
7916
8000
|
}
|
|
7917
8001
|
};
|
|
7918
8002
|
driver.refresh();
|
|
7919
8003
|
return driver;
|
|
7920
8004
|
}
|
|
8005
|
+
function applyScrollPin(svgRoot, scroll) {
|
|
8006
|
+
var _a;
|
|
8007
|
+
const styled = svgRoot;
|
|
8008
|
+
if (!(scroll == null ? void 0 : scroll.pin) || !styled.style) return () => {
|
|
8009
|
+
};
|
|
8010
|
+
const style = styled.style;
|
|
8011
|
+
const prevPosition = style.position;
|
|
8012
|
+
const prevTop = style.top;
|
|
8013
|
+
style.position = "sticky";
|
|
8014
|
+
style.top = ((_a = scroll.pinTop) != null ? _a : 0) + "px";
|
|
8015
|
+
let wrapper = null;
|
|
8016
|
+
const parent = svgRoot.parentElement;
|
|
8017
|
+
if (scroll.pinDistance && scroll.pinDistance > 0 && parent) {
|
|
8018
|
+
wrapper = document.createElement("div");
|
|
8019
|
+
wrapper.setAttribute("data-px-pin", "");
|
|
8020
|
+
wrapper.style.height = scroll.pinDistance * 100 + "vh";
|
|
8021
|
+
parent.insertBefore(wrapper, svgRoot);
|
|
8022
|
+
wrapper.appendChild(svgRoot);
|
|
8023
|
+
}
|
|
8024
|
+
return () => {
|
|
8025
|
+
style.position = prevPosition;
|
|
8026
|
+
style.top = prevTop;
|
|
8027
|
+
if (wrapper == null ? void 0 : wrapper.parentElement) {
|
|
8028
|
+
wrapper.parentElement.insertBefore(svgRoot, wrapper);
|
|
8029
|
+
wrapper.remove();
|
|
8030
|
+
}
|
|
8031
|
+
};
|
|
8032
|
+
}
|
|
7921
8033
|
function finaliseAnimator(animatorConfig, callbacks, make) {
|
|
7922
8034
|
let apiRef;
|
|
7923
8035
|
let effectiveCallbacks = callbacks;
|
|
@@ -7942,7 +8054,10 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7942
8054
|
if (isScrollTimeline(animatorConfig)) {
|
|
7943
8055
|
return finaliseAnimator(animatorConfig, callbacks, (cb) => {
|
|
7944
8056
|
var _a, _b;
|
|
8057
|
+
let unpin = () => {
|
|
8058
|
+
};
|
|
7945
8059
|
if (animatorConfig.mode !== PxAnimatorMode.frames && ((_a = animatorConfig.scroll) == null ? void 0 : _a.driver) === "native" && rootElement) {
|
|
8060
|
+
unpin = applyScrollPin(rootElement, animatorConfig.scroll);
|
|
7946
8061
|
const native = createNativeScrollTimeline(rootElement, animatorConfig);
|
|
7947
8062
|
if (native) {
|
|
7948
8063
|
const api2 = createWebApiAnimator(
|
|
@@ -7952,12 +8067,23 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7952
8067
|
animatorConfig.mode === PxAnimatorMode.waapi,
|
|
7953
8068
|
native
|
|
7954
8069
|
);
|
|
7955
|
-
if (api2)
|
|
8070
|
+
if (api2) {
|
|
8071
|
+
const destroyNative = api2.destroy.bind(api2);
|
|
8072
|
+
api2.destroy = () => {
|
|
8073
|
+
unpin();
|
|
8074
|
+
destroyNative();
|
|
8075
|
+
};
|
|
8076
|
+
return api2;
|
|
8077
|
+
}
|
|
7956
8078
|
}
|
|
8079
|
+
unpin();
|
|
8080
|
+
unpin = () => {
|
|
8081
|
+
};
|
|
7957
8082
|
}
|
|
7958
8083
|
const api = (animatorConfig.mode !== PxAnimatorMode.frames ? createWebApiAnimator(doc, cb, rootElement, animatorConfig.mode === PxAnimatorMode.waapi) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
|
|
7959
8084
|
const subject = ((_b = api.getRootElement) == null ? void 0 : _b.call(api)) || rootElement;
|
|
7960
8085
|
if (subject) {
|
|
8086
|
+
unpin = applyScrollPin(subject, animatorConfig.scroll);
|
|
7961
8087
|
const totalMs = scrollTotalDurationMs(animatorConfig);
|
|
7962
8088
|
const driver = createScrollDriver(
|
|
7963
8089
|
subject,
|
|
@@ -7968,6 +8094,7 @@ var PixodeskAnimatorReact = (() => {
|
|
|
7968
8094
|
const destroy = api.destroy.bind(api);
|
|
7969
8095
|
api.destroy = () => {
|
|
7970
8096
|
driver.destroy();
|
|
8097
|
+
unpin();
|
|
7971
8098
|
destroy();
|
|
7972
8099
|
};
|
|
7973
8100
|
}
|