UNPKG

use-elevator

Version:

A React hook for smooth scrolling that transforms boring scroll-to-top actions into playful elevator experiences with customizable settings

3 lines (2 loc) 1.46 kB
import{useState as r,useRef as n,useEffect as t,useCallback as e}from"react";const u=(r,n,t,e)=>(r/=e/2)<1?t/2*r*r+n:-t/2*(--r*(r-2)-1)+n,l=(r,n=0)=>{const t=document.getElementById(r);if(!t)return n;let e=0,u=t;for(;u;)e+=u.offsetTop||0,u=u.offsetParent;return e-n},c=(r,n)=>{if(n)return n;const t=1.5*Math.abs(r);return Math.min(t,2e3)},o=(o={})=>{const{targetElement:a,duration:i=0,verticalPadding:s=0,startCallback:m,endCallback:d}=o,[w,f]=r(!1),v=n(null),b=n(null),E=n(null),g=n(null);t((()=>{const r=()=>{w&&(null!==v.current&&(cancelAnimationFrame(v.current),v.current=null),null!==E.current&&window.scrollTo(0,E.current),g.current=null,b.current=null,f(!1))};return window.addEventListener("blur",r),()=>{window.removeEventListener("blur",r)}}),[w]),t((()=>()=>{null!==v.current&&cancelAnimationFrame(v.current)}),[]);const A=e((r=>{if(null===g.current&&(g.current=r),null===b.current||null===E.current)return void f(!1);const n=r-g.current,t=Math.abs(E.current-b.current),e=c(t,i),l=u(n,b.current,E.current-b.current,e);window.scrollTo(0,l),n<e?v.current=requestAnimationFrame(A):(d&&d(),g.current=null,b.current=null,v.current=null,f(!1))}),[i,d]);return{startElevating:e((()=>{w||(f(!0),E.current=a?l(a,s):s,b.current=window.scrollY,m&&m(),v.current=requestAnimationFrame(A))}),[w,a,s,m,A]),isElevating:w}};export{l as calculateElementScrollPosition,c as calculateScrollDuration,u as easeInOutQuad,o as useElevator}; //# sourceMappingURL=index.js.map