UNPKG

framer-motion

Version:

A simple and powerful React animation library

55 lines (52 loc) 1.91 kB
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 };