Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 30x 30x 30x 30x 30x 30x 30x | import { RefObject } from "react" import { useConstant } from "../../utils/use-constant" import { createScrollMotionValues, ScrollMotionValues, createScrollUpdater, } from "./utils" import { addDomEvent } from "../../events/use-dom-event" import { useIsomorphicLayoutEffect } from "../../utils/use-isomorphic-effect" import { invariant } from "hey-listen" const getElementScrollOffsets = (element: HTMLElement) => () => { return { xOffset: element.scrollLeft, yOffset: element.scrollTop, xMaxOffset: element.scrollWidth - element.offsetWidth, yMaxOffset: element.scrollHeight - element.offsetHeight, } } /** * Returns MotionValues that update when the provided element 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`. * * This element must be set to `overflow: scroll` on either or both axes to report scroll offset. * * ```jsx * export const MyComponent = () => { * const ref = useRef() * const { scrollYProgress } = useElementScroll(ref) * * return ( * <div ref={ref}> * <motion.div style={{ scaleX: scrollYProgress }} /> * </div> * ) * } * ``` * * @public */ export function useElementScroll( ref: RefObject<HTMLElement> ): ScrollMotionValues { const values = useConstant(createScrollMotionValues) useIsomorphicLayoutEffect(() => { const element = ref.current invariant( !!element, "ref provided to useScroll must be passed into a HTML element." ) if (!element) return const updateScrollValues = createScrollUpdater( values, getElementScrollOffsets(element) ) const scrollListener = addDomEvent( element, "scroll", updateScrollValues, { passive: true } ) const resizeListener = addDomEvent( element, "resize", updateScrollValues ) return () => { scrollListener && scrollListener() resizeListener && resizeListener() } }, []) return values } |