framer-motion
Version:
A simple and powerful React animation library
55 lines (52 loc) • 1.91 kB
JavaScript
import { createScrollMotionValues, createScrollUpdater } from './utils.mjs';
import { addDomEvent } from '../../events/use-dom-event.mjs';
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
var viewportScrollValues;
function getViewportScrollOffsets() {
return {
xOffset: window.pageXOffset,
yOffset: window.pageYOffset,
xMaxOffset: document.body.clientWidth - window.innerWidth,
yMaxOffset: document.body.clientHeight - window.innerHeight,
};
}
var hasListeners = false;
function addEventListeners() {
hasListeners = true;
var updateScrollValues = createScrollUpdater(viewportScrollValues, getViewportScrollOffsets);
addDomEvent(window, "scroll", updateScrollValues, { passive: true });
addDomEvent(window, "resize", updateScrollValues);
}
/**
* Returns MotionValues that update when the viewport scrolls:
*
* - `scrollX` — Horizontal scroll distance in pixels.
* - `scrollY` — Vertical scroll distance in pixels.
* - `scrollXProgress` — Horizontal scroll progress between `0` and `1`.
* - `scrollYProgress` — Vertical scroll progress between `0` and `1`.
*
* **Warning:** Setting `body` or `html` to `height: 100%` or similar will break the `Progress`
* values as this breaks the browser's capability to accurately measure the page length.
*
* ```jsx
* export const MyComponent = () => {
* const { scrollYProgress } = useViewportScroll()
* return <motion.div style={{ scaleX: scrollYProgress }} />
* }
* ```
*
* @public
*/
function useViewportScroll() {
/**
* Lazy-initialise the viewport scroll values
*/
if (!viewportScrollValues) {
viewportScrollValues = createScrollMotionValues();
}
useIsomorphicLayoutEffect(function () {
!hasListeners && addEventListeners();
}, []);
return viewportScrollValues;
}
export { useViewportScroll };