use-scroll-to-2
Version:
Scroll to React elements with custom timing function support
2 lines (1 loc) • 1.45 kB
JavaScript
import n from"bezier-easing";export{default as bezier}from"bezier-easing";import{useRef as t,useEffect as e,useCallback as r,useLayoutEffect as o}from"react";var i,u;(u=i||(i={}))[u.Stop=0]="Stop",u[u.Continue=1]="Continue";const a=(n,t)=>{const e=Date.now(),{duration:r,delay:o,easing:i}=t;(n=>{let t;const e=()=>{0===n()?cancelAnimationFrame(t):t=requestAnimationFrame(e)};t=requestAnimationFrame(e)})((()=>{const t=Date.now()-(e+o),u=Math.max(0,Math.min(1,t/r));return n(i(u)),t>=r?0:1}))};function l(n){return t=>"function"==typeof n?n(t):n}function c(i){const{auto:u=!1,delay:c=0,duration:s=480,easing:d=n(.25,.1,.25,1),offsetLeft:f=0,offsetTop:w=0}=null!=i?i:{},m=t(null),p=t(s),g=t(c),b=t(w),v=t(f),y=t(d);e((()=>{p.current=s}),[s]),e((()=>{g.current=c}),[c]),e((()=>{b.current=w}),[w]),e((()=>{v.current=f}),[f]),e((()=>{y.current=d}),[d]);const h=r((()=>{if(!m.current)return;const n=p.current,t=g.current,e=y.current,r=b.current,o=v.current;requestAnimationFrame((()=>{var i,u;const{top:c,left:s}=m.current.getBoundingClientRect(),d=null!=(i=null==window?void 0:window.scrollY)?i:0,f=null!=(u=null==window?void 0:window.scrollX)?u:0,w=c-l(r)(c>0?1:-1),p=s-l(o)(c>0?1:-1);"number"!=typeof n||n<=0?null==window||window.scrollTo({top:d+w,left:f+p,behavior:"auto"}):a((n=>{null==window||window.scrollTo({top:d+n*w,left:f+n*p,behavior:"auto"})}),{duration:n,delay:t,easing:e})}))}),[]);return o((()=>{u&&h()}),[u,h]),[m,h]}export{c as useScrollTo};