scroller-motion
Version:
🛹 Elegant motion scrolling for React
1 lines • 13 kB
Source Map (JSON)
{"version":3,"file":"index.modern.mjs","sources":["../src/context.ts","../src/hooks/useCore/useAxis.ts","../src/hooks/useCore/useSize.ts","../src/hooks/useScrollerMotion.ts","../src/components/Core/Wrap.tsx","../src/components/Core/index.tsx","../src/hooks/useCore/index.ts","../src/hooks/useCore/useWindowSize.ts","../src/hooks/useCore/useSpringScroll.ts"],"sourcesContent":["import { createContext } from 'react'\n\nimport { ScrollerMotionValues } from './types'\n\nexport const Context = createContext<ScrollerMotionValues | undefined>(\n undefined\n)\n","import { useMemo } from 'react'\nimport { transform, useTransform } from 'framer-motion'\n\nimport { MotionValue } from '../../types'\n\ninterface Options {\n axisSpring: MotionValue\n scale: number\n refSize: number\n windowSize: number\n}\n\nexport const useAxis = ({\n axisSpring,\n scale,\n refSize,\n windowSize\n}: Options) => {\n const scaledSize = useMemo(\n () => (refSize > windowSize ? refSize * scale : refSize),\n [refSize, scale, windowSize]\n )\n\n const transformFrom = useMemo(\n () => [0, scaledSize - windowSize],\n [scaledSize, windowSize]\n )\n const transformTo = useMemo(\n () => [0, (refSize - windowSize) * -1],\n [refSize, windowSize]\n )\n\n const axis = useTransform(axisSpring, transformFrom, transformTo, {\n clamp: false\n })\n\n const progress = useTransform(axisSpring, (v) =>\n Math.max(0, Math.min(transform(v, transformFrom, [0, 1]), 1))\n )\n\n return {\n axis,\n progress,\n size: scaledSize\n }\n}\n","import { useEffect, useState } from 'react'\nimport debounceFn from 'debounce-fn'\n\nimport { ChildrenRef } from '../../types'\n\nconst getSize = (el: HTMLElement | null) => ({\n height: el?.scrollHeight ?? 0,\n width: el?.scrollWidth ?? 0\n})\n\nconst supportsResizeObserver = typeof ResizeObserver === 'function'\n\nexport const useSize = (ref: ChildrenRef) => {\n const [size, setSize] = useState({ height: 0, width: 0 })\n\n useEffect(() => {\n const onResize = () => setSize(getSize(ref.current))\n const debouncedOnResize = debounceFn(onResize, { wait: 400 })\n let resizeObserver: ResizeObserver | null = null\n\n if (ref.current) {\n onResize()\n window.addEventListener('resize', debouncedOnResize)\n\n if (supportsResizeObserver) {\n resizeObserver = new ResizeObserver(onResize)\n resizeObserver.observe(ref.current)\n }\n }\n\n return () => {\n window.removeEventListener('resize', debouncedOnResize)\n\n if (resizeObserver) {\n resizeObserver.disconnect()\n }\n }\n }, [])\n\n return size\n}\n","import { useContext } from 'react'\n\nimport { Context } from '../context'\n\nexport const useScrollerMotion = () => {\n const context = useContext(Context)\n\n if (context === undefined) {\n throw new Error('useScrollerMotion must be used within ScrollerMotion')\n }\n\n return context\n}\n","import { useMemo } from 'react'\nimport { motion } from 'framer-motion'\n\nimport { ChildrenRef, DivElementProps, MotionValue } from '../../types'\n\ninterface Props extends DivElementProps {\n childrenRef: ChildrenRef\n disabled?: boolean\n height: number\n width: number\n x: MotionValue\n y: MotionValue\n}\n\nconst FIXED_STYLE = {\n position: 'fixed',\n left: 0,\n top: 0,\n right: 0,\n bottom: 0\n}\n\nexport const Wrap = ({\n children,\n childrenRef,\n disabled,\n height,\n style,\n width,\n x,\n y,\n ...props\n}: Props) => {\n const outerStyle = useMemo(\n () => ({ ...style, ...(!disabled ? { height, width } : {}) }),\n [disabled, height, style, width]\n )\n const fixedStyle = useMemo(() => (!disabled ? FIXED_STYLE : {}), [disabled])\n const motionStyle = useMemo(\n () => ({ x: !disabled ? x : 0, y: !disabled ? y : 0 }),\n [disabled, x, y]\n )\n\n return (\n <div {...props} style={outerStyle}>\n <div style={fixedStyle}>\n <motion.div style={motionStyle} ref={childrenRef}>\n {children}\n </motion.div>\n </div>\n </div>\n )\n}\n","import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react'\n\nimport { Context } from '../../context'\nimport { useCore } from '../../hooks'\nimport { CoreProps, CoreRef } from '../../types'\n\nimport { Wrap } from './Wrap'\n\nconst DEFAULT_SCALE = 1\n\nconst DEFAULT_SPRING = {\n damping: 50,\n mass: 1.25,\n stiffness: 200\n}\n\nexport const Core = forwardRef<CoreRef, CoreProps>(\n (\n {\n children,\n disabled,\n scale = DEFAULT_SCALE,\n spring = DEFAULT_SPRING,\n ...props\n },\n ref\n ) => {\n const childrenRef = useRef(null)\n\n const {\n height,\n width,\n scrollX,\n scrollXProgress,\n scrollY,\n scrollYProgress,\n x,\n y\n } = useCore({\n ref: childrenRef,\n scale,\n spring\n })\n\n useImperativeHandle(\n ref,\n () => ({ scrollX, scrollXProgress, scrollY, scrollYProgress, x, y }),\n [scrollX, scrollXProgress, scrollY, scrollYProgress, x, y]\n )\n\n const contextValue = useMemo(\n () => ({ scrollX, scrollXProgress, scrollY, scrollYProgress, x, y }),\n [scrollX, scrollXProgress, scrollY, scrollYProgress, x, y]\n )\n\n return (\n <Wrap\n {...props}\n childrenRef={childrenRef}\n disabled={disabled}\n height={height}\n width={width}\n x={x}\n y={y}\n >\n <Context.Provider value={contextValue}>{children}</Context.Provider>\n </Wrap>\n )\n }\n)\n\nCore.displayName = 'ScrollerMotion'\n","import { useMemo } from 'react'\n\nimport { ChildrenRef, SpringProp } from '../../types'\n\nimport { useAxis } from './useAxis'\nimport { useSize } from './useSize'\nimport { useSpringScroll } from './useSpringScroll'\nimport { useWindowSize } from './useWindowSize'\n\ninterface Options {\n ref: ChildrenRef\n scale: number\n spring: SpringProp\n}\n\nexport const useCore = ({ ref, scale, spring }: Options) => {\n const innerScale = useMemo(() => Math.max(1, scale), [scale])\n\n const { height: windowHeight, width: windowWidth } = useWindowSize()\n const { height: refHeight, width: refWidth } = useSize(ref)\n\n const { x: springX, y: springY } = useSpringScroll(spring)\n\n const {\n axis: x,\n progress: progressX,\n size: width\n } = useAxis({\n axisSpring: springX,\n scale: innerScale,\n refSize: refWidth,\n windowSize: windowWidth\n })\n\n const {\n axis: y,\n progress: progressY,\n size: height\n } = useAxis({\n axisSpring: springY,\n scale: innerScale,\n refSize: refHeight,\n windowSize: windowHeight\n })\n\n return {\n height,\n width,\n scrollX: springX,\n scrollXProgress: progressX,\n scrollY: springY,\n scrollYProgress: progressY,\n x,\n y\n }\n}\n","import { useEffect, useState } from 'react'\n\nconst getWindowSize = () => ({\n width:\n window.innerWidth ||\n document.documentElement.clientWidth ||\n document.body.clientWidth,\n height:\n window.innerHeight ||\n document.documentElement.clientHeight ||\n document.body.clientHeight\n})\n\nexport const useWindowSize = () => {\n const [size, setSize] = useState({ height: 0, width: 0 })\n\n useEffect(() => {\n const onResize = () => setSize(getWindowSize())\n\n onResize()\n window.addEventListener('resize', onResize, false)\n\n return () => window.removeEventListener('resize', onResize, false)\n }, [])\n\n return size\n}\n","import { useScroll, useSpring } from 'framer-motion'\n\nimport { MotionValue, SpringProp, SpringOptions } from '../../types'\n\nexport const useSpringScroll = (springConfig: SpringProp) => {\n const { scrollX, scrollY } = useScroll()\n\n const config = typeof springConfig === 'object' ? springConfig : undefined\n const springX: MotionValue<number> = useSpring(\n scrollX,\n config as SpringOptions\n )\n const springY: MotionValue<number> = useSpring(\n scrollY,\n config as SpringOptions\n )\n\n return {\n x: config ? springX : scrollX,\n y: config ? springY : scrollY\n }\n}\n"],"names":["Context","createContext","undefined","useAxis","axisSpring","scale","refSize","windowSize","scaledSize","useMemo","transformFrom","transformTo","axis","useTransform","clamp","progress","v","Math","max","min","transform","size","supportsResizeObserver","useScrollerMotion","useContext","context","FIXED_STYLE","position","left","top","right","bottom","Wrap","_ref","children","childrenRef","disabled","height","style","width","x","y","props","_objectWithoutPropertiesLoose","_excluded","outerStyle","motionStyle","_jsx","fixedStyle","motion","div","ref","DEFAULT_SCALE","DEFAULT_SPRING","damping","mass","stiffness","Core","forwardRef","spring","useRef","scrollX","scrollXProgress","scrollY","scrollYProgress","windowHeight","windowWidth","setSize","useState","useEffect","onResize","window","innerWidth","document","documentElement","clientWidth","body","innerHeight","clientHeight","addEventListener","removeEventListener","useWindowSize","refHeight","refWidth","el","current","scrollHeight","_el$scrollHeight","scrollWidth","_el$scrollWidth","debounceFn","wait","resizeObserver","debouncedOnResize","ResizeObserver","observe","disconnect","useSize","springX","springY","springConfig","useScroll","config","useSpring","useSpringScroll","progressX","innerScale","progressY","useCore","useImperativeHandle","contextValue","_extends","Provider","value","displayName"],"mappings":"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"}