Files
SnowLuma/.pnpm-store/v11/files/07/ed3460816b77b72b898e64adb85c16af83e9598257148f7a9f36765181d9deef425931086b83141859d5f46097659a70ed311681524c11e0d410fe01cd724c
T
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Skipped
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

90 lines
3.1 KiB
Plaintext

"use client";
import { supportsViewTimeline, supportsScrollTimeline, motionValue } from 'motion-dom';
import { invariant } from 'motion-utils';
import { useRef, useCallback, useEffect } from 'react';
import { scroll } from '../render/dom/scroll/index.mjs';
import { offsetToViewTimelineRange } from '../render/dom/scroll/utils/offset-to-range.mjs';
import { useConstant } from '../utils/use-constant.mjs';
import { useIsomorphicLayoutEffect } from '../utils/use-isomorphic-effect.mjs';
const createScrollMotionValues = () => ({
scrollX: motionValue(0),
scrollY: motionValue(0),
scrollXProgress: motionValue(0),
scrollYProgress: motionValue(0),
});
const isRefPending = (ref) => {
if (!ref)
return false;
return !ref.current;
};
function makeAccelerateConfig(axis, options, container, target) {
return {
factory: (animation) => scroll(animation, {
...options,
axis,
container: container?.current || undefined,
target: target?.current || undefined,
}),
times: [0, 1],
keyframes: [0, 1],
ease: (v) => v,
duration: 1,
};
}
function canAccelerateScroll(target, offset) {
if (typeof window === "undefined")
return false;
return target
? supportsViewTimeline() && !!offsetToViewTimelineRange(offset)
: supportsScrollTimeline();
}
function useScroll({ container, target, ...options } = {}) {
const values = useConstant(createScrollMotionValues);
if (canAccelerateScroll(target, options.offset)) {
values.scrollXProgress.accelerate = makeAccelerateConfig("x", options, container, target);
values.scrollYProgress.accelerate = makeAccelerateConfig("y", options, container, target);
}
const scrollAnimation = useRef(null);
const needsStart = useRef(false);
const start = useCallback(() => {
scrollAnimation.current = scroll((_progress, { x, y, }) => {
values.scrollX.set(x.current);
values.scrollXProgress.set(x.progress);
values.scrollY.set(y.current);
values.scrollYProgress.set(y.progress);
}, {
...options,
container: container?.current || undefined,
target: target?.current || undefined,
});
return () => {
scrollAnimation.current?.();
};
}, [container, target, JSON.stringify(options.offset)]);
useIsomorphicLayoutEffect(() => {
needsStart.current = false;
if (isRefPending(container) || isRefPending(target)) {
needsStart.current = true;
return;
}
else {
return start();
}
}, [start]);
useEffect(() => {
if (needsStart.current) {
invariant(!isRefPending(container), "Container ref is defined but not hydrated", "use-scroll-ref");
invariant(!isRefPending(target), "Target ref is defined but not hydrated", "use-scroll-ref");
return start();
}
else {
return;
}
}, [start]);
return values;
}
export { useScroll };
//# sourceMappingURL=use-scroll.mjs.map