From 4dd292438a11f6490b099735559ec08f5668ea66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Roche?= Date: Sun, 17 Mar 2024 19:48:01 +0100 Subject: [PATCH] firefox deltaMode --- packages/lenis/dist/lenis.cjs.js | 2 +- packages/lenis/dist/lenis.cjs.js.map | 2 +- packages/lenis/dist/lenis.js | 34 ++++--- packages/lenis/dist/lenis.min.js | 2 +- packages/lenis/dist/lenis.mjs | 2 +- packages/lenis/dist/lenis.mjs.map | 2 +- packages/lenis/dist/lenis.umd.js | 2 +- packages/lenis/dist/lenis.umd.js.map | 2 +- packages/lenis/dist/types/index.d.ts | 3 +- packages/lenis/dist/types/virtual-scroll.d.ts | 7 +- packages/lenis/playground/index.html | 88 ++++++++++++++++++- packages/lenis/playground/main.js | 67 -------------- packages/lenis/playground/package.json | 3 + packages/lenis/playground/style.css | 6 ++ packages/lenis/playground/yarn.lock | 5 ++ packages/lenis/src/index.ts | 4 - packages/lenis/src/virtual-scroll.js | 31 ++++--- yarn.lock | 2 +- 18 files changed, 154 insertions(+), 110 deletions(-) diff --git a/packages/lenis/dist/lenis.cjs.js b/packages/lenis/dist/lenis.cjs.js index a67832e5..883d4af3 100644 --- a/packages/lenis/dist/lenis.cjs.js +++ b/packages/lenis/dist/lenis.cjs.js @@ -1,2 +1,2 @@ -"use strict";function t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,l=e,function(t,e,i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*l))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,l;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:l}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=2,normalizeWheel:s=!1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.normalizeWheel=s,this.touchStart={x:null,y:null},this.emitter=new Emitter,this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),this.element.removeEventListener("wheel",this.onWheel,{passive:!1}),this.element.removeEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.removeEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.removeEventListener("touchend",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit("scroll",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=e=>{let{deltaX:i,deltaY:s}=e;this.normalizeWheel&&(i=t(-100,i,100),s=t(-100,s,100)),i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:e})}}module.exports=class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:p=!1,orientation:u="vertical",gestureOrientation:d="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,normalizeWheel:g=!1,autoResize:S=!0,__experimental__naiveDimensions:w=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes("touch"),o=i.type.includes("wheel");if(this.options.syncTouch&&s&&"touchstart"===i.type)return void this.reset();const n=0===t&&0===e,l="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===t;if(n||l)return;let r=i.composedPath();if(r=r.slice(0,r.indexOf(this.rootElement)),r.find((t=>{var e,i,n,l,r;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent-touch"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;"both"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:"horizontal"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&"touchend"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion="1.0.40",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:p,gestureOrientation:d,orientation:u,touchMultiplier:m,wheelMultiplier:v,normalizeWheel:g,autoResize:S,__experimental__naiveDimensions:w},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:S}),this.toggleClassName("lenis",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:v,normalizeWheel:g}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName("lenis",!1),this.toggleClassName("lenis-smooth",!1),this.toggleClassName("lenis-scrolling",!1),this.toggleClassName("lenis-stopped",!1),this.toggleClassName("lenis-locked",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:l=this.options.easing,lerp:r=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(e))e=0;else if(["bottom","right","end"].includes(e))e=this.limit;else{let t;if("string"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:l,lerp:r,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName("lenis-smooth",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName("lenis-scrolling",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName("lenis-stopped",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName("lenis-locked",t))}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),this.isSmooth&&(t+=" lenis-smooth"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit("className change",this)}}; +"use strict";function t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,r=e,function(t,e,i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*r))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,r;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:r}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=r}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}const e=100/6;class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.touchStart={x:null,y:null},this.emitter=new Emitter,window.addEventListener("resize",this.onWindowResize,!1),this.onWindowResize(),this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel,{passive:!1}),this.element.removeEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.removeEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.removeEventListener("touchend",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit("scroll",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=t=>{let{deltaX:i,deltaY:s,deltaMode:o}=t;i*=1===o?e:2===o?this.windowWidth:1,s*=1===o?e:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:t})};onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight}}module.exports=class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:r=.075,touchInertiaMultiplier:l=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:d=!1,orientation:p="vertical",gestureOrientation:u="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,__experimental__naiveDimensions:S=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes("touch"),o=i.type.includes("wheel");if(this.options.syncTouch&&s&&"touchstart"===i.type)return void this.reset();const n=0===t&&0===e,r="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===t;if(n||r)return;let l=i.composedPath();if(l=l.slice(0,l.indexOf(this.rootElement)),l.find((t=>{var e,i,n,r,l;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent-touch"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,"data-lenis-prevent-wheel"))||(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis"))&&!(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis-stopped"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;"both"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:"horizontal"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&"touchend"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion="1.0.40",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:r,touchInertiaMultiplier:l,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:u,orientation:p,touchMultiplier:m,wheelMultiplier:v,autoResize:g,__experimental__naiveDimensions:S},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:g}),this.toggleClassName("lenis",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:v}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName("lenis",!1),this.toggleClassName("lenis-smooth",!1),this.toggleClassName("lenis-scrolling",!1),this.toggleClassName("lenis-stopped",!1),this.toggleClassName("lenis-locked",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:r=this.options.easing,lerp:l=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(e))e=0;else if(["bottom","right","end"].includes(e))e=this.limit;else{let t;if("string"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:r,lerp:l,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName("lenis-smooth",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName("lenis-scrolling",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName("lenis-stopped",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName("lenis-locked",t))}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),this.isSmooth&&(t+=" lenis-smooth"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit("className change",this)}}; //# sourceMappingURL=lenis.cjs.js.map diff --git a/packages/lenis/dist/lenis.cjs.js.map b/packages/lenis/dist/lenis.cjs.js.map index 7adcc7f1..34e8973b 100644 --- a/packages/lenis/dist/lenis.cjs.js.map +++ b/packages/lenis/dist/lenis.cjs.js.map @@ -1 +1 @@ -{"version":3,"file":"lenis.cjs.js","sources":["../src/maths.js","../src/animate.js","../src/dimensions.js","../src/debounce.js","../src/emitter.js","../src/virtual-scroll.js","../../src/index.ts"],"sourcesContent":["// Clamp a value between a minimum and maximum value\nexport function clamp(min, input, max) {\n return Math.max(min, Math.min(input, max))\n}\n\n// Truncate a floating-point number to a specified number of decimal places\nexport function truncate(value, decimals = 0) {\n return parseFloat(value.toFixed(decimals))\n}\n\n// Linearly interpolate between two values using an amount (0 <= t <= 1)\nexport function lerp(x, y, t) {\n return (1 - t) * x + t * y\n}\n\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\nexport function damp(x, y, lambda, dt) {\n return lerp(x, y, 1 - Math.exp(-lambda * dt))\n}\n\n// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor\n// https://anguscroll.com/just/just-modulo\nexport function modulo(n, d) {\n return ((n % d) + d) % d\n}\n","import { clamp, damp } from './maths'\n\n// Animate class to handle value animations with lerping or easing\nexport class Animate {\n // Advance the animation by the given delta time\n advance(deltaTime) {\n if (!this.isRunning) return\n\n let completed = false\n\n if (this.lerp) {\n this.value = damp(this.value, this.to, this.lerp * 60, deltaTime)\n if (Math.round(this.value) === this.to) {\n this.value = this.to\n completed = true\n }\n } else {\n this.currentTime += deltaTime\n const linearProgress = clamp(0, this.currentTime / this.duration, 1)\n\n completed = linearProgress >= 1\n const easedProgress = completed ? 1 : this.easing(linearProgress)\n this.value = this.from + (this.to - this.from) * easedProgress\n }\n\n // Call the onUpdate callback with the current value and completed status\n this.onUpdate?.(this.value, completed)\n\n if (completed) {\n this.stop()\n }\n }\n\n // Stop the animation\n stop() {\n this.isRunning = false\n }\n\n // Set up the animation from a starting value to an ending value\n // with optional parameters for lerping, duration, easing, and onUpdate callback\n fromTo(\n from,\n to,\n { lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }\n ) {\n this.from = this.value = from\n this.to = to\n this.lerp = lerp\n this.duration = duration\n this.easing = easing\n this.currentTime = 0\n this.isRunning = true\n\n onStart?.()\n this.onUpdate = onUpdate\n }\n}\n","import { debounce } from './debounce'\n\nexport class Dimensions {\n constructor({\n wrapper,\n content,\n autoResize = true,\n debounce: debounceValue = 250,\n } = {}) {\n this.wrapper = wrapper\n this.content = content\n\n if (autoResize) {\n this.debouncedResize = debounce(this.resize, debounceValue)\n\n if (this.wrapper === window) {\n window.addEventListener('resize', this.debouncedResize, false)\n } else {\n this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize)\n this.wrapperResizeObserver.observe(this.wrapper)\n }\n\n this.contentResizeObserver = new ResizeObserver(this.debouncedResize)\n this.contentResizeObserver.observe(this.content)\n }\n\n this.resize()\n }\n\n destroy() {\n this.wrapperResizeObserver?.disconnect()\n this.contentResizeObserver?.disconnect()\n window.removeEventListener('resize', this.debouncedResize, false)\n }\n\n resize = () => {\n this.onWrapperResize()\n this.onContentResize()\n }\n\n onWrapperResize = () => {\n if (this.wrapper === window) {\n this.width = window.innerWidth\n this.height = window.innerHeight\n } else {\n this.width = this.wrapper.clientWidth\n this.height = this.wrapper.clientHeight\n }\n }\n\n onContentResize = () => {\n if (this.wrapper === window) {\n this.scrollHeight = this.content.scrollHeight\n this.scrollWidth = this.content.scrollWidth\n } else {\n this.scrollHeight = this.wrapper.scrollHeight\n this.scrollWidth = this.wrapper.scrollWidth\n }\n }\n\n get limit() {\n return {\n x: this.scrollWidth - this.width,\n y: this.scrollHeight - this.height,\n }\n }\n}\n","export function debounce(callback, delay) {\n let timer\n return function () {\n let args = arguments\n let context = this\n clearTimeout(timer)\n timer = setTimeout(function () {\n callback.apply(context, args)\n }, delay)\n }\n}\n","export class Emitter {\n constructor() {\n this.events = {}\n }\n\n emit(event, ...args) {\n let callbacks = this.events[event] || []\n for (let i = 0, length = callbacks.length; i < length; i++) {\n callbacks[i](...args)\n }\n }\n\n on(event, cb) {\n // Add the callback to the event's callback list, or create a new list with the callback\n this.events[event]?.push(cb) || (this.events[event] = [cb])\n\n // Return an unsubscribe function\n return () => {\n this.events[event] = this.events[event]?.filter((i) => cb !== i)\n }\n }\n\n off(event, callback) {\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\n }\n\n destroy() {\n this.events = {}\n }\n}\n","import { Emitter } from './emitter'\nimport { clamp } from './maths'\n\nexport class VirtualScroll {\n constructor(\n element,\n { wheelMultiplier = 1, touchMultiplier = 2, normalizeWheel = false }\n ) {\n this.element = element\n this.wheelMultiplier = wheelMultiplier\n this.touchMultiplier = touchMultiplier\n this.normalizeWheel = normalizeWheel\n\n this.touchStart = {\n x: null,\n y: null,\n }\n\n this.emitter = new Emitter()\n\n this.element.addEventListener('wheel', this.onWheel, { passive: false })\n this.element.addEventListener('touchstart', this.onTouchStart, {\n passive: false,\n })\n this.element.addEventListener('touchmove', this.onTouchMove, {\n passive: false,\n })\n this.element.addEventListener('touchend', this.onTouchEnd, {\n passive: false,\n })\n }\n\n // Add an event listener for the given event and callback\n on(event, callback) {\n return this.emitter.on(event, callback)\n }\n\n // Remove all event listeners and clean up\n destroy() {\n this.emitter.destroy()\n\n this.element.removeEventListener('wheel', this.onWheel, {\n passive: false,\n })\n this.element.removeEventListener('touchstart', this.onTouchStart, {\n passive: false,\n })\n this.element.removeEventListener('touchmove', this.onTouchMove, {\n passive: false,\n })\n this.element.removeEventListener('touchend', this.onTouchEnd, {\n passive: false,\n })\n }\n\n // Event handler for 'touchstart' event\n onTouchStart = (event) => {\n const { clientX, clientY } = event.targetTouches\n ? event.targetTouches[0]\n : event\n\n this.touchStart.x = clientX\n this.touchStart.y = clientY\n\n this.lastDelta = {\n x: 0,\n y: 0,\n }\n\n this.emitter.emit('scroll', {\n deltaX: 0,\n deltaY: 0,\n event,\n })\n }\n\n // Event handler for 'touchmove' event\n onTouchMove = (event) => {\n const { clientX, clientY } = event.targetTouches\n ? event.targetTouches[0]\n : event\n\n const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier\n const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier\n\n this.touchStart.x = clientX\n this.touchStart.y = clientY\n\n this.lastDelta = {\n x: deltaX,\n y: deltaY,\n }\n\n this.emitter.emit('scroll', {\n deltaX,\n deltaY,\n event,\n })\n }\n\n onTouchEnd = (event) => {\n this.emitter.emit('scroll', {\n deltaX: this.lastDelta.x,\n deltaY: this.lastDelta.y,\n event,\n })\n }\n\n // Event handler for 'wheel' event\n onWheel = (event) => {\n let { deltaX, deltaY } = event\n\n if (this.normalizeWheel) {\n deltaX = clamp(-100, deltaX, 100)\n deltaY = clamp(-100, deltaY, 100)\n }\n\n deltaX *= this.wheelMultiplier\n deltaY *= this.wheelMultiplier\n\n this.emitter.emit('scroll', { deltaX, deltaY, event })\n }\n}\n","import { version } from '../package.json'\nimport { Animate } from './animate'\nimport { Dimensions } from './dimensions'\nimport { Emitter } from './emitter'\nimport { clamp, modulo } from './maths'\nimport { VirtualScroll } from './virtual-scroll'\n\n// Technical explanation\n// - listen to 'wheel' events\n// - prevent 'wheel' event to prevent scroll\n// - normalize wheel delta\n// - add delta to targetScroll\n// - animate scroll to targetScroll (smooth context)\n// - if animation is not running, listen to 'scroll' events (native context)\n\ntype EasingFunction = (t: number) => number\ntype Orientation = 'vertical' | 'horizontal'\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\n\nexport type LenisOptions = {\n wrapper?: Window | HTMLElement\n content?: HTMLElement\n wheelEventsTarget?: Window | HTMLElement\n eventsTarget?: Window | HTMLElement\n smoothWheel?: boolean\n syncTouch?: boolean\n syncTouchLerp?: number\n touchInertiaMultiplier?: number\n duration?: number\n easing?: EasingFunction\n lerp?: number\n infinite?: boolean\n orientation?: Orientation\n gestureOrientation?: GestureOrientation\n touchMultiplier?: number\n wheelMultiplier?: number\n normalizeWheel?: boolean\n autoResize?: boolean\n __experimental__naiveDimensions?: boolean\n}\n\nexport default class Lenis {\n __isSmooth: boolean = false // true if scroll should be animated\n __isScrolling: boolean = false // true when scroll is animating\n __isStopped: boolean = false // true if user should not be able to scroll - enable/disable programmatically\n __isLocked: boolean = false // same as isStopped but enabled/disabled when scroll reaches target\n\n constructor({\n wrapper = window,\n content = document.documentElement,\n wheelEventsTarget = wrapper, // deprecated\n eventsTarget = wheelEventsTarget,\n smoothWheel = true,\n syncTouch = false,\n syncTouchLerp = 0.075,\n touchInertiaMultiplier = 35,\n duration, // in seconds\n easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),\n lerp = !duration && 0.1,\n infinite = false,\n orientation = 'vertical', // vertical, horizontal\n gestureOrientation = 'vertical', // vertical, horizontal, both\n touchMultiplier = 1,\n wheelMultiplier = 1,\n normalizeWheel = false, // deprecated\n autoResize = true,\n __experimental__naiveDimensions = false,\n }: LenisOptions = {}) {\n window.lenisVersion = version\n\n // if wrapper is html or body, fallback to window\n if (wrapper === document.documentElement || wrapper === document.body) {\n wrapper = window\n }\n\n this.options = {\n wrapper,\n content,\n wheelEventsTarget,\n eventsTarget,\n smoothWheel,\n syncTouch,\n syncTouchLerp,\n touchInertiaMultiplier,\n duration,\n easing,\n lerp,\n infinite,\n gestureOrientation,\n orientation,\n touchMultiplier,\n wheelMultiplier,\n normalizeWheel,\n autoResize,\n __experimental__naiveDimensions,\n }\n\n this.animate = new Animate()\n this.emitter = new Emitter()\n this.dimensions = new Dimensions({ wrapper, content, autoResize })\n this.toggleClassName('lenis', true)\n\n this.velocity = 0\n this.isLocked = false\n this.isStopped = false\n this.isSmooth = syncTouch || smoothWheel\n this.isScrolling = false\n this.targetScroll = this.animatedScroll = this.actualScroll\n\n this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false)\n\n this.virtualScroll = new VirtualScroll(eventsTarget, {\n touchMultiplier,\n wheelMultiplier,\n normalizeWheel,\n })\n this.virtualScroll.on('scroll', this.onVirtualScroll)\n }\n\n destroy() {\n this.emitter.destroy()\n\n this.options.wrapper.removeEventListener(\n 'scroll',\n this.onNativeScroll,\n false\n )\n\n this.virtualScroll.destroy()\n this.dimensions.destroy()\n\n this.toggleClassName('lenis', false)\n this.toggleClassName('lenis-smooth', false)\n this.toggleClassName('lenis-scrolling', false)\n this.toggleClassName('lenis-stopped', false)\n this.toggleClassName('lenis-locked', false)\n }\n\n on(event: string, callback: Function) {\n return this.emitter.on(event, callback)\n }\n\n off(event: string, callback: Function) {\n return this.emitter.off(event, callback)\n }\n\n private setScroll(scroll) {\n // apply scroll value immediately\n if (this.isHorizontal) {\n this.rootElement.scrollLeft = scroll\n } else {\n this.rootElement.scrollTop = scroll\n }\n }\n\n private onVirtualScroll = ({ deltaX, deltaY, event }) => {\n // keep zoom feature\n if (event.ctrlKey) return\n\n const isTouch = event.type.includes('touch')\n const isWheel = event.type.includes('wheel')\n\n const isTapToStop =\n this.options.syncTouch && isTouch && event.type === 'touchstart'\n\n if (isTapToStop) {\n this.reset()\n return\n }\n\n const isClick = deltaX === 0 && deltaY === 0 // click event\n\n // const isPullToRefresh =\n // this.options.gestureOrientation === 'vertical' &&\n // this.scroll === 0 &&\n // !this.options.infinite &&\n // deltaY <= 5 // touch pull to refresh, not reliable yet\n\n const isUnknownGesture =\n (this.options.gestureOrientation === 'vertical' && deltaY === 0) ||\n (this.options.gestureOrientation === 'horizontal' && deltaX === 0)\n\n if (isClick || isUnknownGesture) {\n // console.log('prevent')\n return\n }\n\n // catch if scrolling on nested scroll elements\n let composedPath = event.composedPath()\n composedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement)) // remove parents elements\n\n if (\n !!composedPath.find(\n (node) =>\n node.hasAttribute?.('data-lenis-prevent') ||\n (isTouch && node.hasAttribute?.('data-lenis-prevent-touch')) ||\n (isWheel && node.hasAttribute?.('data-lenis-prevent-wheel')) ||\n (node.classList?.contains('lenis') &&\n !node.classList?.contains('lenis-stopped')) // nested lenis instance\n )\n )\n return\n\n if (this.isStopped || this.isLocked) {\n event.preventDefault() // this will stop forwarding the event to the parent, this is problematic\n return\n }\n\n this.isSmooth =\n (this.options.syncTouch && isTouch) ||\n (this.options.smoothWheel && isWheel)\n\n if (!this.isSmooth) {\n this.isScrolling = false\n this.animate.stop()\n return\n }\n\n event.preventDefault()\n\n let delta = deltaY\n if (this.options.gestureOrientation === 'both') {\n delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX\n } else if (this.options.gestureOrientation === 'horizontal') {\n delta = deltaX\n }\n\n const syncTouch = isTouch && this.options.syncTouch\n const isTouchEnd = isTouch && event.type === 'touchend'\n\n const hasTouchInertia = isTouchEnd && Math.abs(delta) > 5\n\n if (hasTouchInertia) {\n delta = this.velocity * this.options.touchInertiaMultiplier\n }\n\n this.scrollTo(this.targetScroll + delta, {\n programmatic: false,\n ...(syncTouch\n ? {\n lerp: hasTouchInertia ? this.options.syncTouchLerp : 1,\n }\n : {\n lerp: this.options.lerp,\n duration: this.options.duration,\n easing: this.options.easing,\n }),\n })\n }\n\n resize() {\n this.dimensions.resize()\n }\n\n private emit() {\n this.emitter.emit('scroll', this)\n }\n\n private onNativeScroll = () => {\n if (this.__preventNextScrollEvent) return\n\n if (!this.isScrolling) {\n const lastScroll = this.animatedScroll\n this.animatedScroll = this.targetScroll = this.actualScroll\n this.velocity = 0\n this.direction = Math.sign(this.animatedScroll - lastScroll)\n this.emit()\n }\n }\n\n private reset() {\n this.isLocked = false\n this.isScrolling = false\n this.animatedScroll = this.targetScroll = this.actualScroll\n this.velocity = 0\n this.animate.stop()\n }\n\n start() {\n if (!this.isStopped) return\n this.isStopped = false\n\n this.reset()\n }\n\n stop() {\n if (this.isStopped) return\n this.isStopped = true\n this.animate.stop()\n\n this.reset()\n }\n\n raf(time: number) {\n const deltaTime = time - (this.time || time)\n this.time = time\n\n this.animate.advance(deltaTime * 0.001)\n }\n\n scrollTo(\n target: number | string | HTMLElement,\n {\n offset = 0,\n immediate = false,\n lock = false,\n duration = this.options.duration,\n easing = this.options.easing,\n lerp = !duration && this.options.lerp,\n onComplete,\n force = false, // scroll even if stopped\n programmatic = true, // called from outside of the class\n }: {\n offset?: number\n immediate?: boolean\n lock?: boolean\n duration?: number\n easing?: EasingFunction\n lerp?: number\n onComplete?: (lenis: Lenis) => void\n force?: boolean\n programmatic?: boolean\n } = {}\n ) {\n if ((this.isStopped || this.isLocked) && !force) return\n\n // keywords\n if (['top', 'left', 'start'].includes(target)) {\n target = 0\n } else if (['bottom', 'right', 'end'].includes(target)) {\n target = this.limit\n } else {\n let node\n\n if (typeof target === 'string') {\n // CSS selector\n node = document.querySelector(target)\n } else if (target?.nodeType) {\n // Node element\n node = target\n }\n\n if (node) {\n if (this.options.wrapper !== window) {\n // nested scroll offset correction\n const wrapperRect = this.options.wrapper.getBoundingClientRect()\n offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top\n }\n\n const rect = node.getBoundingClientRect()\n\n target =\n (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll\n }\n }\n\n if (typeof target !== 'number') return\n\n target += offset\n target = Math.round(target)\n\n if (this.options.infinite) {\n if (programmatic) {\n this.targetScroll = this.animatedScroll = this.scroll\n }\n } else {\n target = clamp(0, target, this.limit)\n }\n\n if (immediate) {\n this.animatedScroll = this.targetScroll = target\n this.setScroll(this.scroll)\n this.reset()\n onComplete?.(this)\n return\n }\n\n if (!programmatic) {\n if (target === this.targetScroll) return\n\n this.targetScroll = target\n }\n\n this.animate.fromTo(this.animatedScroll, target, {\n duration,\n easing,\n lerp,\n onStart: () => {\n // started\n if (lock) this.isLocked = true\n this.isScrolling = true\n },\n onUpdate: (value: number, completed: boolean) => {\n this.isScrolling = true\n\n // updated\n this.velocity = value - this.animatedScroll\n this.direction = Math.sign(this.velocity)\n\n this.animatedScroll = value\n this.setScroll(this.scroll)\n\n if (programmatic) {\n // wheel during programmatic should stop it\n this.targetScroll = value\n }\n\n if (!completed) this.emit()\n\n if (completed) {\n this.reset()\n this.emit()\n onComplete?.(this)\n\n // avoid emitting event twice\n this.__preventNextScrollEvent = true\n requestAnimationFrame(() => {\n delete this.__preventNextScrollEvent\n })\n }\n },\n })\n }\n\n get rootElement() {\n return this.options.wrapper === window\n ? document.documentElement\n : this.options.wrapper\n }\n\n get limit() {\n if (this.options.__experimental__naiveDimensions) {\n if (this.isHorizontal) {\n return this.rootElement.scrollWidth - this.rootElement.clientWidth\n } else {\n return this.rootElement.scrollHeight - this.rootElement.clientHeight\n }\n } else {\n return this.dimensions.limit[this.isHorizontal ? 'x' : 'y']\n }\n }\n\n get isHorizontal() {\n return this.options.orientation === 'horizontal'\n }\n\n get actualScroll() {\n // value browser takes into account\n return this.isHorizontal\n ? this.rootElement.scrollLeft\n : this.rootElement.scrollTop\n }\n\n get scroll() {\n return this.options.infinite\n ? modulo(this.animatedScroll, this.limit)\n : this.animatedScroll\n }\n\n get progress() {\n // avoid progress to be NaN\n return this.limit === 0 ? 1 : this.scroll / this.limit\n }\n\n get isSmooth() {\n return this.__isSmooth\n }\n\n private set isSmooth(value: boolean) {\n if (this.__isSmooth !== value) {\n this.__isSmooth = value\n this.toggleClassName('lenis-smooth', value)\n }\n }\n\n get isScrolling() {\n return this.__isScrolling\n }\n\n private set isScrolling(value: boolean) {\n if (this.__isScrolling !== value) {\n this.__isScrolling = value\n this.toggleClassName('lenis-scrolling', value)\n }\n }\n\n get isStopped() {\n return this.__isStopped\n }\n\n private set isStopped(value: boolean) {\n if (this.__isStopped !== value) {\n this.__isStopped = value\n this.toggleClassName('lenis-stopped', value)\n }\n }\n\n get isLocked() {\n return this.__isLocked\n }\n\n private set isLocked(value: boolean) {\n if (this.__isLocked !== value) {\n this.__isLocked = value\n this.toggleClassName('lenis-locked', value)\n }\n }\n\n get className() {\n let className = 'lenis'\n if (this.isStopped) className += ' lenis-stopped'\n if (this.isLocked) className += ' lenis-locked'\n if (this.isScrolling) className += ' lenis-scrolling'\n if (this.isSmooth) className += ' lenis-smooth'\n return className\n }\n\n private toggleClassName(name: string, value: boolean) {\n this.rootElement.classList.toggle(name, value)\n this.emitter.emit('className change', this)\n }\n}\n"],"names":["clamp","min","input","max","Math","Animate","advance","deltaTime","this","isRunning","completed","lerp","value","x","y","to","lambda","dt","t","exp","round","currentTime","linearProgress","duration","easedProgress","easing","from","onUpdate","stop","fromTo","onStart","Dimensions","constructor","wrapper","content","autoResize","debounce","debounceValue","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","resize","window","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","removeEventListener","onWrapperResize","onContentResize","width","innerWidth","height","innerHeight","clientWidth","clientHeight","scrollHeight","scrollWidth","limit","Emitter","events","emit","event","callbacks","i","length","on","cb","push","filter","off","VirtualScroll","element","wheelMultiplier","touchMultiplier","normalizeWheel","touchStart","emitter","onWheel","passive","onTouchStart","onTouchMove","onTouchEnd","clientX","clientY","targetTouches","lastDelta","deltaX","deltaY","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","__experimental__naiveDimensions","__isSmooth","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","options","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","isStopped","isLocked","preventDefault","isSmooth","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__preventNextScrollEvent","lastScroll","animatedScroll","actualScroll","direction","sign","lenisVersion","body","dimensions","toggleClassName","virtualScroll","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","time","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","requestAnimationFrame","n","d","progress","className","name","toggle"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"lenis.cjs.js","sources":["../src/maths.js","../src/animate.js","../src/dimensions.js","../src/debounce.js","../src/emitter.js","../src/virtual-scroll.js","../../src/index.ts"],"sourcesContent":["// Clamp a value between a minimum and maximum value\r\nexport function clamp(min, input, max) {\r\n return Math.max(min, Math.min(input, max))\r\n}\r\n\r\n// Truncate a floating-point number to a specified number of decimal places\r\nexport function truncate(value, decimals = 0) {\r\n return parseFloat(value.toFixed(decimals))\r\n}\r\n\r\n// Linearly interpolate between two values using an amount (0 <= t <= 1)\r\nexport function lerp(x, y, t) {\r\n return (1 - t) * x + t * y\r\n}\r\n\r\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\r\nexport function damp(x, y, lambda, dt) {\r\n return lerp(x, y, 1 - Math.exp(-lambda * dt))\r\n}\r\n\r\n// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor\r\n// https://anguscroll.com/just/just-modulo\r\nexport function modulo(n, d) {\r\n return ((n % d) + d) % d\r\n}\r\n","import { clamp, damp } from './maths'\r\n\r\n// Animate class to handle value animations with lerping or easing\r\nexport class Animate {\r\n // Advance the animation by the given delta time\r\n advance(deltaTime) {\r\n if (!this.isRunning) return\r\n\r\n let completed = false\r\n\r\n if (this.lerp) {\r\n this.value = damp(this.value, this.to, this.lerp * 60, deltaTime)\r\n if (Math.round(this.value) === this.to) {\r\n this.value = this.to\r\n completed = true\r\n }\r\n } else {\r\n this.currentTime += deltaTime\r\n const linearProgress = clamp(0, this.currentTime / this.duration, 1)\r\n\r\n completed = linearProgress >= 1\r\n const easedProgress = completed ? 1 : this.easing(linearProgress)\r\n this.value = this.from + (this.to - this.from) * easedProgress\r\n }\r\n\r\n // Call the onUpdate callback with the current value and completed status\r\n this.onUpdate?.(this.value, completed)\r\n\r\n if (completed) {\r\n this.stop()\r\n }\r\n }\r\n\r\n // Stop the animation\r\n stop() {\r\n this.isRunning = false\r\n }\r\n\r\n // Set up the animation from a starting value to an ending value\r\n // with optional parameters for lerping, duration, easing, and onUpdate callback\r\n fromTo(\r\n from,\r\n to,\r\n { lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }\r\n ) {\r\n this.from = this.value = from\r\n this.to = to\r\n this.lerp = lerp\r\n this.duration = duration\r\n this.easing = easing\r\n this.currentTime = 0\r\n this.isRunning = true\r\n\r\n onStart?.()\r\n this.onUpdate = onUpdate\r\n }\r\n}\r\n","import { debounce } from './debounce'\r\n\r\nexport class Dimensions {\r\n constructor({\r\n wrapper,\r\n content,\r\n autoResize = true,\r\n debounce: debounceValue = 250,\r\n } = {}) {\r\n this.wrapper = wrapper\r\n this.content = content\r\n\r\n if (autoResize) {\r\n this.debouncedResize = debounce(this.resize, debounceValue)\r\n\r\n if (this.wrapper === window) {\r\n window.addEventListener('resize', this.debouncedResize, false)\r\n } else {\r\n this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize)\r\n this.wrapperResizeObserver.observe(this.wrapper)\r\n }\r\n\r\n this.contentResizeObserver = new ResizeObserver(this.debouncedResize)\r\n this.contentResizeObserver.observe(this.content)\r\n }\r\n\r\n this.resize()\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver?.disconnect()\r\n this.contentResizeObserver?.disconnect()\r\n window.removeEventListener('resize', this.debouncedResize, false)\r\n }\r\n\r\n resize = () => {\r\n this.onWrapperResize()\r\n this.onContentResize()\r\n }\r\n\r\n onWrapperResize = () => {\r\n if (this.wrapper === window) {\r\n this.width = window.innerWidth\r\n this.height = window.innerHeight\r\n } else {\r\n this.width = this.wrapper.clientWidth\r\n this.height = this.wrapper.clientHeight\r\n }\r\n }\r\n\r\n onContentResize = () => {\r\n if (this.wrapper === window) {\r\n this.scrollHeight = this.content.scrollHeight\r\n this.scrollWidth = this.content.scrollWidth\r\n } else {\r\n this.scrollHeight = this.wrapper.scrollHeight\r\n this.scrollWidth = this.wrapper.scrollWidth\r\n }\r\n }\r\n\r\n get limit() {\r\n return {\r\n x: this.scrollWidth - this.width,\r\n y: this.scrollHeight - this.height,\r\n }\r\n }\r\n}\r\n","export function debounce(callback, delay) {\r\n let timer\r\n return function () {\r\n let args = arguments\r\n let context = this\r\n clearTimeout(timer)\r\n timer = setTimeout(function () {\r\n callback.apply(context, args)\r\n }, delay)\r\n }\r\n}\r\n","export class Emitter {\r\n constructor() {\r\n this.events = {}\r\n }\r\n\r\n emit(event, ...args) {\r\n let callbacks = this.events[event] || []\r\n for (let i = 0, length = callbacks.length; i < length; i++) {\r\n callbacks[i](...args)\r\n }\r\n }\r\n\r\n on(event, cb) {\r\n // Add the callback to the event's callback list, or create a new list with the callback\r\n this.events[event]?.push(cb) || (this.events[event] = [cb])\r\n\r\n // Return an unsubscribe function\r\n return () => {\r\n this.events[event] = this.events[event]?.filter((i) => cb !== i)\r\n }\r\n }\r\n\r\n off(event, callback) {\r\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\r\n }\r\n\r\n destroy() {\r\n this.events = {}\r\n }\r\n}\r\n","import { Emitter } from './emitter'\r\n\r\nconst LINE_HEIGHT = 100 / 6\r\n\r\nexport class VirtualScroll {\r\n constructor(element, { wheelMultiplier = 1, touchMultiplier = 1 }) {\r\n this.element = element\r\n this.wheelMultiplier = wheelMultiplier\r\n this.touchMultiplier = touchMultiplier\r\n\r\n this.touchStart = {\r\n x: null,\r\n y: null,\r\n }\r\n\r\n this.emitter = new Emitter()\r\n window.addEventListener('resize', this.onWindowResize, false)\r\n this.onWindowResize()\r\n\r\n this.element.addEventListener('wheel', this.onWheel, { passive: false })\r\n this.element.addEventListener('touchstart', this.onTouchStart, {\r\n passive: false,\r\n })\r\n this.element.addEventListener('touchmove', this.onTouchMove, {\r\n passive: false,\r\n })\r\n this.element.addEventListener('touchend', this.onTouchEnd, {\r\n passive: false,\r\n })\r\n }\r\n\r\n // Add an event listener for the given event and callback\r\n on(event, callback) {\r\n return this.emitter.on(event, callback)\r\n }\r\n\r\n // Remove all event listeners and clean up\r\n destroy() {\r\n this.emitter.destroy()\r\n\r\n window.removeEventListener('resize', this.onWindowResize, false)\r\n\r\n this.element.removeEventListener('wheel', this.onWheel, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchstart', this.onTouchStart, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchmove', this.onTouchMove, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchend', this.onTouchEnd, {\r\n passive: false,\r\n })\r\n }\r\n\r\n // Event handler for 'touchstart' event\r\n onTouchStart = (event) => {\r\n const { clientX, clientY } = event.targetTouches\r\n ? event.targetTouches[0]\r\n : event\r\n\r\n this.touchStart.x = clientX\r\n this.touchStart.y = clientY\r\n\r\n this.lastDelta = {\r\n x: 0,\r\n y: 0,\r\n }\r\n\r\n this.emitter.emit('scroll', {\r\n deltaX: 0,\r\n deltaY: 0,\r\n event,\r\n })\r\n }\r\n\r\n // Event handler for 'touchmove' event\r\n onTouchMove = (event) => {\r\n const { clientX, clientY } = event.targetTouches\r\n ? event.targetTouches[0]\r\n : event\r\n\r\n const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier\r\n const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier\r\n\r\n this.touchStart.x = clientX\r\n this.touchStart.y = clientY\r\n\r\n this.lastDelta = {\r\n x: deltaX,\r\n y: deltaY,\r\n }\r\n\r\n this.emitter.emit('scroll', {\r\n deltaX,\r\n deltaY,\r\n event,\r\n })\r\n }\r\n\r\n onTouchEnd = (event) => {\r\n this.emitter.emit('scroll', {\r\n deltaX: this.lastDelta.x,\r\n deltaY: this.lastDelta.y,\r\n event,\r\n })\r\n }\r\n\r\n // Event handler for 'wheel' event\r\n onWheel = (event) => {\r\n let { deltaX, deltaY, deltaMode } = event\r\n\r\n const multiplierX =\r\n deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowWidth : 1\r\n const multiplierY =\r\n deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowHeight : 1\r\n\r\n deltaX *= multiplierX\r\n deltaY *= multiplierY\r\n\r\n deltaX *= this.wheelMultiplier\r\n deltaY *= this.wheelMultiplier\r\n\r\n this.emitter.emit('scroll', { deltaX, deltaY, event })\r\n }\r\n\r\n onWindowResize = () => {\r\n this.windowWidth = window.innerWidth\r\n this.windowHeight = window.innerHeight\r\n }\r\n}\r\n","import { version } from '../package.json'\r\nimport { Animate } from './animate'\r\nimport { Dimensions } from './dimensions'\r\nimport { Emitter } from './emitter'\r\nimport { clamp, modulo } from './maths'\r\nimport { VirtualScroll } from './virtual-scroll'\r\n\r\n// Technical explanation\r\n// - listen to 'wheel' events\r\n// - prevent 'wheel' event to prevent scroll\r\n// - normalize wheel delta\r\n// - add delta to targetScroll\r\n// - animate scroll to targetScroll (smooth context)\r\n// - if animation is not running, listen to 'scroll' events (native context)\r\n\r\ntype EasingFunction = (t: number) => number\r\ntype Orientation = 'vertical' | 'horizontal'\r\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\r\n\r\nexport type LenisOptions = {\r\n wrapper?: Window | HTMLElement\r\n content?: HTMLElement\r\n wheelEventsTarget?: Window | HTMLElement\r\n eventsTarget?: Window | HTMLElement\r\n smoothWheel?: boolean\r\n syncTouch?: boolean\r\n syncTouchLerp?: number\r\n touchInertiaMultiplier?: number\r\n duration?: number\r\n easing?: EasingFunction\r\n lerp?: number\r\n infinite?: boolean\r\n orientation?: Orientation\r\n gestureOrientation?: GestureOrientation\r\n touchMultiplier?: number\r\n wheelMultiplier?: number\r\n autoResize?: boolean\r\n __experimental__naiveDimensions?: boolean\r\n}\r\n\r\nexport default class Lenis {\r\n __isSmooth: boolean = false // true if scroll should be animated\r\n __isScrolling: boolean = false // true when scroll is animating\r\n __isStopped: boolean = false // true if user should not be able to scroll - enable/disable programmatically\r\n __isLocked: boolean = false // same as isStopped but enabled/disabled when scroll reaches target\r\n\r\n constructor({\r\n wrapper = window,\r\n content = document.documentElement,\r\n wheelEventsTarget = wrapper, // deprecated\r\n eventsTarget = wheelEventsTarget,\r\n smoothWheel = true,\r\n syncTouch = false,\r\n syncTouchLerp = 0.075,\r\n touchInertiaMultiplier = 35,\r\n duration, // in seconds\r\n easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),\r\n lerp = !duration && 0.1,\r\n infinite = false,\r\n orientation = 'vertical', // vertical, horizontal\r\n gestureOrientation = 'vertical', // vertical, horizontal, both\r\n touchMultiplier = 1,\r\n wheelMultiplier = 1,\r\n autoResize = true,\r\n __experimental__naiveDimensions = false,\r\n }: LenisOptions = {}) {\r\n window.lenisVersion = version\r\n\r\n // if wrapper is html or body, fallback to window\r\n if (wrapper === document.documentElement || wrapper === document.body) {\r\n wrapper = window\r\n }\r\n\r\n this.options = {\r\n wrapper,\r\n content,\r\n wheelEventsTarget,\r\n eventsTarget,\r\n smoothWheel,\r\n syncTouch,\r\n syncTouchLerp,\r\n touchInertiaMultiplier,\r\n duration,\r\n easing,\r\n lerp,\r\n infinite,\r\n gestureOrientation,\r\n orientation,\r\n touchMultiplier,\r\n wheelMultiplier,\r\n autoResize,\r\n __experimental__naiveDimensions,\r\n }\r\n\r\n this.animate = new Animate()\r\n this.emitter = new Emitter()\r\n this.dimensions = new Dimensions({ wrapper, content, autoResize })\r\n this.toggleClassName('lenis', true)\r\n\r\n this.velocity = 0\r\n this.isLocked = false\r\n this.isStopped = false\r\n this.isSmooth = syncTouch || smoothWheel\r\n this.isScrolling = false\r\n this.targetScroll = this.animatedScroll = this.actualScroll\r\n\r\n this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false)\r\n\r\n this.virtualScroll = new VirtualScroll(eventsTarget, {\r\n touchMultiplier,\r\n wheelMultiplier,\r\n })\r\n this.virtualScroll.on('scroll', this.onVirtualScroll)\r\n }\r\n\r\n destroy() {\r\n this.emitter.destroy()\r\n\r\n this.options.wrapper.removeEventListener(\r\n 'scroll',\r\n this.onNativeScroll,\r\n false\r\n )\r\n\r\n this.virtualScroll.destroy()\r\n this.dimensions.destroy()\r\n\r\n this.toggleClassName('lenis', false)\r\n this.toggleClassName('lenis-smooth', false)\r\n this.toggleClassName('lenis-scrolling', false)\r\n this.toggleClassName('lenis-stopped', false)\r\n this.toggleClassName('lenis-locked', false)\r\n }\r\n\r\n on(event: string, callback: Function) {\r\n return this.emitter.on(event, callback)\r\n }\r\n\r\n off(event: string, callback: Function) {\r\n return this.emitter.off(event, callback)\r\n }\r\n\r\n private setScroll(scroll) {\r\n // apply scroll value immediately\r\n if (this.isHorizontal) {\r\n this.rootElement.scrollLeft = scroll\r\n } else {\r\n this.rootElement.scrollTop = scroll\r\n }\r\n }\r\n\r\n private onVirtualScroll = ({ deltaX, deltaY, event }) => {\r\n // keep zoom feature\r\n if (event.ctrlKey) return\r\n\r\n const isTouch = event.type.includes('touch')\r\n const isWheel = event.type.includes('wheel')\r\n\r\n const isTapToStop =\r\n this.options.syncTouch && isTouch && event.type === 'touchstart'\r\n\r\n if (isTapToStop) {\r\n this.reset()\r\n return\r\n }\r\n\r\n const isClick = deltaX === 0 && deltaY === 0 // click event\r\n\r\n // const isPullToRefresh =\r\n // this.options.gestureOrientation === 'vertical' &&\r\n // this.scroll === 0 &&\r\n // !this.options.infinite &&\r\n // deltaY <= 5 // touch pull to refresh, not reliable yet\r\n\r\n const isUnknownGesture =\r\n (this.options.gestureOrientation === 'vertical' && deltaY === 0) ||\r\n (this.options.gestureOrientation === 'horizontal' && deltaX === 0)\r\n\r\n if (isClick || isUnknownGesture) {\r\n // console.log('prevent')\r\n return\r\n }\r\n\r\n // catch if scrolling on nested scroll elements\r\n let composedPath = event.composedPath()\r\n composedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement)) // remove parents elements\r\n\r\n if (\r\n !!composedPath.find(\r\n (node) =>\r\n node.hasAttribute?.('data-lenis-prevent') ||\r\n (isTouch && node.hasAttribute?.('data-lenis-prevent-touch')) ||\r\n (isWheel && node.hasAttribute?.('data-lenis-prevent-wheel')) ||\r\n (node.classList?.contains('lenis') &&\r\n !node.classList?.contains('lenis-stopped')) // nested lenis instance\r\n )\r\n )\r\n return\r\n\r\n if (this.isStopped || this.isLocked) {\r\n event.preventDefault() // this will stop forwarding the event to the parent, this is problematic\r\n return\r\n }\r\n\r\n this.isSmooth =\r\n (this.options.syncTouch && isTouch) ||\r\n (this.options.smoothWheel && isWheel)\r\n\r\n if (!this.isSmooth) {\r\n this.isScrolling = false\r\n this.animate.stop()\r\n return\r\n }\r\n\r\n event.preventDefault()\r\n\r\n let delta = deltaY\r\n if (this.options.gestureOrientation === 'both') {\r\n delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX\r\n } else if (this.options.gestureOrientation === 'horizontal') {\r\n delta = deltaX\r\n }\r\n\r\n const syncTouch = isTouch && this.options.syncTouch\r\n const isTouchEnd = isTouch && event.type === 'touchend'\r\n\r\n const hasTouchInertia = isTouchEnd && Math.abs(delta) > 5\r\n\r\n if (hasTouchInertia) {\r\n delta = this.velocity * this.options.touchInertiaMultiplier\r\n }\r\n\r\n this.scrollTo(this.targetScroll + delta, {\r\n programmatic: false,\r\n ...(syncTouch\r\n ? {\r\n lerp: hasTouchInertia ? this.options.syncTouchLerp : 1,\r\n }\r\n : {\r\n lerp: this.options.lerp,\r\n duration: this.options.duration,\r\n easing: this.options.easing,\r\n }),\r\n })\r\n }\r\n\r\n resize() {\r\n this.dimensions.resize()\r\n }\r\n\r\n private emit() {\r\n this.emitter.emit('scroll', this)\r\n }\r\n\r\n private onNativeScroll = () => {\r\n if (this.__preventNextScrollEvent) return\r\n\r\n if (!this.isScrolling) {\r\n const lastScroll = this.animatedScroll\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.velocity = 0\r\n this.direction = Math.sign(this.animatedScroll - lastScroll)\r\n this.emit()\r\n }\r\n }\r\n\r\n private reset() {\r\n this.isLocked = false\r\n this.isScrolling = false\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.velocity = 0\r\n this.animate.stop()\r\n }\r\n\r\n start() {\r\n if (!this.isStopped) return\r\n this.isStopped = false\r\n\r\n this.reset()\r\n }\r\n\r\n stop() {\r\n if (this.isStopped) return\r\n this.isStopped = true\r\n this.animate.stop()\r\n\r\n this.reset()\r\n }\r\n\r\n raf(time: number) {\r\n const deltaTime = time - (this.time || time)\r\n this.time = time\r\n\r\n this.animate.advance(deltaTime * 0.001)\r\n }\r\n\r\n scrollTo(\r\n target: number | string | HTMLElement,\r\n {\r\n offset = 0,\r\n immediate = false,\r\n lock = false,\r\n duration = this.options.duration,\r\n easing = this.options.easing,\r\n lerp = !duration && this.options.lerp,\r\n onComplete,\r\n force = false, // scroll even if stopped\r\n programmatic = true, // called from outside of the class\r\n }: {\r\n offset?: number\r\n immediate?: boolean\r\n lock?: boolean\r\n duration?: number\r\n easing?: EasingFunction\r\n lerp?: number\r\n onComplete?: (lenis: Lenis) => void\r\n force?: boolean\r\n programmatic?: boolean\r\n } = {}\r\n ) {\r\n if ((this.isStopped || this.isLocked) && !force) return\r\n\r\n // keywords\r\n if (['top', 'left', 'start'].includes(target)) {\r\n target = 0\r\n } else if (['bottom', 'right', 'end'].includes(target)) {\r\n target = this.limit\r\n } else {\r\n let node\r\n\r\n if (typeof target === 'string') {\r\n // CSS selector\r\n node = document.querySelector(target)\r\n } else if (target?.nodeType) {\r\n // Node element\r\n node = target\r\n }\r\n\r\n if (node) {\r\n if (this.options.wrapper !== window) {\r\n // nested scroll offset correction\r\n const wrapperRect = this.options.wrapper.getBoundingClientRect()\r\n offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top\r\n }\r\n\r\n const rect = node.getBoundingClientRect()\r\n\r\n target =\r\n (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll\r\n }\r\n }\r\n\r\n if (typeof target !== 'number') return\r\n\r\n target += offset\r\n target = Math.round(target)\r\n\r\n if (this.options.infinite) {\r\n if (programmatic) {\r\n this.targetScroll = this.animatedScroll = this.scroll\r\n }\r\n } else {\r\n target = clamp(0, target, this.limit)\r\n }\r\n\r\n if (immediate) {\r\n this.animatedScroll = this.targetScroll = target\r\n this.setScroll(this.scroll)\r\n this.reset()\r\n onComplete?.(this)\r\n return\r\n }\r\n\r\n if (!programmatic) {\r\n if (target === this.targetScroll) return\r\n\r\n this.targetScroll = target\r\n }\r\n\r\n this.animate.fromTo(this.animatedScroll, target, {\r\n duration,\r\n easing,\r\n lerp,\r\n onStart: () => {\r\n // started\r\n if (lock) this.isLocked = true\r\n this.isScrolling = true\r\n },\r\n onUpdate: (value: number, completed: boolean) => {\r\n this.isScrolling = true\r\n\r\n // updated\r\n this.velocity = value - this.animatedScroll\r\n this.direction = Math.sign(this.velocity)\r\n\r\n this.animatedScroll = value\r\n this.setScroll(this.scroll)\r\n\r\n if (programmatic) {\r\n // wheel during programmatic should stop it\r\n this.targetScroll = value\r\n }\r\n\r\n if (!completed) this.emit()\r\n\r\n if (completed) {\r\n this.reset()\r\n this.emit()\r\n onComplete?.(this)\r\n\r\n // avoid emitting event twice\r\n this.__preventNextScrollEvent = true\r\n requestAnimationFrame(() => {\r\n delete this.__preventNextScrollEvent\r\n })\r\n }\r\n },\r\n })\r\n }\r\n\r\n get rootElement() {\r\n return this.options.wrapper === window\r\n ? document.documentElement\r\n : this.options.wrapper\r\n }\r\n\r\n get limit() {\r\n if (this.options.__experimental__naiveDimensions) {\r\n if (this.isHorizontal) {\r\n return this.rootElement.scrollWidth - this.rootElement.clientWidth\r\n } else {\r\n return this.rootElement.scrollHeight - this.rootElement.clientHeight\r\n }\r\n } else {\r\n return this.dimensions.limit[this.isHorizontal ? 'x' : 'y']\r\n }\r\n }\r\n\r\n get isHorizontal() {\r\n return this.options.orientation === 'horizontal'\r\n }\r\n\r\n get actualScroll() {\r\n // value browser takes into account\r\n return this.isHorizontal\r\n ? this.rootElement.scrollLeft\r\n : this.rootElement.scrollTop\r\n }\r\n\r\n get scroll() {\r\n return this.options.infinite\r\n ? modulo(this.animatedScroll, this.limit)\r\n : this.animatedScroll\r\n }\r\n\r\n get progress() {\r\n // avoid progress to be NaN\r\n return this.limit === 0 ? 1 : this.scroll / this.limit\r\n }\r\n\r\n get isSmooth() {\r\n return this.__isSmooth\r\n }\r\n\r\n private set isSmooth(value: boolean) {\r\n if (this.__isSmooth !== value) {\r\n this.__isSmooth = value\r\n this.toggleClassName('lenis-smooth', value)\r\n }\r\n }\r\n\r\n get isScrolling() {\r\n return this.__isScrolling\r\n }\r\n\r\n private set isScrolling(value: boolean) {\r\n if (this.__isScrolling !== value) {\r\n this.__isScrolling = value\r\n this.toggleClassName('lenis-scrolling', value)\r\n }\r\n }\r\n\r\n get isStopped() {\r\n return this.__isStopped\r\n }\r\n\r\n private set isStopped(value: boolean) {\r\n if (this.__isStopped !== value) {\r\n this.__isStopped = value\r\n this.toggleClassName('lenis-stopped', value)\r\n }\r\n }\r\n\r\n get isLocked() {\r\n return this.__isLocked\r\n }\r\n\r\n private set isLocked(value: boolean) {\r\n if (this.__isLocked !== value) {\r\n this.__isLocked = value\r\n this.toggleClassName('lenis-locked', value)\r\n }\r\n }\r\n\r\n get className() {\r\n let className = 'lenis'\r\n if (this.isStopped) className += ' lenis-stopped'\r\n if (this.isLocked) className += ' lenis-locked'\r\n if (this.isScrolling) className += ' lenis-scrolling'\r\n if (this.isSmooth) className += ' lenis-smooth'\r\n return className\r\n }\r\n\r\n private toggleClassName(name: string, value: boolean) {\r\n this.rootElement.classList.toggle(name, value)\r\n this.emitter.emit('className change', this)\r\n }\r\n}\r\n"],"names":["clamp","min","input","max","Math","Animate","advance","deltaTime","this","isRunning","completed","lerp","value","x","y","to","lambda","dt","t","exp","round","currentTime","linearProgress","duration","easedProgress","easing","from","onUpdate","stop","fromTo","onStart","Dimensions","constructor","wrapper","content","autoResize","debounce","debounceValue","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","resize","window","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","removeEventListener","onWrapperResize","onContentResize","width","innerWidth","height","innerHeight","clientWidth","clientHeight","scrollHeight","scrollWidth","limit","Emitter","events","emit","event","callbacks","i","length","on","cb","push","filter","off","LINE_HEIGHT","VirtualScroll","element","wheelMultiplier","touchMultiplier","touchStart","emitter","onWindowResize","onWheel","passive","onTouchStart","onTouchMove","onTouchEnd","clientX","clientY","targetTouches","lastDelta","deltaX","deltaY","deltaMode","windowWidth","windowHeight","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","__experimental__naiveDimensions","__isSmooth","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","options","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","isStopped","isLocked","preventDefault","isSmooth","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__preventNextScrollEvent","lastScroll","animatedScroll","actualScroll","direction","sign","lenisVersion","body","dimensions","toggleClassName","virtualScroll","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","time","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","requestAnimationFrame","n","d","progress","className","name","toggle"],"mappings":"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"} \ No newline at end of file diff --git a/packages/lenis/dist/lenis.js b/packages/lenis/dist/lenis.js index 1fde1446..88af1f18 100644 --- a/packages/lenis/dist/lenis.js +++ b/packages/lenis/dist/lenis.js @@ -192,15 +192,13 @@ } } + const LINE_HEIGHT = 100 / 6; + class VirtualScroll { - constructor( - element, - { wheelMultiplier = 1, touchMultiplier = 2, normalizeWheel = false } - ) { + constructor(element, { wheelMultiplier = 1, touchMultiplier = 1 }) { this.element = element; this.wheelMultiplier = wheelMultiplier; this.touchMultiplier = touchMultiplier; - this.normalizeWheel = normalizeWheel; this.touchStart = { x: null, @@ -208,6 +206,8 @@ }; this.emitter = new Emitter(); + window.addEventListener('resize', this.onWindowResize, false); + this.onWindowResize(); this.element.addEventListener('wheel', this.onWheel, { passive: false }); this.element.addEventListener('touchstart', this.onTouchStart, { @@ -230,6 +230,8 @@ destroy() { this.emitter.destroy(); + window.removeEventListener('resize', this.onWindowResize, false); + this.element.removeEventListener('wheel', this.onWheel, { passive: false, }); @@ -299,22 +301,30 @@ // Event handler for 'wheel' event onWheel = (event) => { - let { deltaX, deltaY } = event; + let { deltaX, deltaY, deltaMode } = event; - if (this.normalizeWheel) { - deltaX = clamp(-100, deltaX, 100); - deltaY = clamp(-100, deltaY, 100); - } + const multiplierX = + deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowWidth : 1; + const multiplierY = + deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowHeight : 1; + + deltaX *= multiplierX; + deltaY *= multiplierY; deltaX *= this.wheelMultiplier; deltaY *= this.wheelMultiplier; this.emitter.emit('scroll', { deltaX, deltaY, event }); } + + onWindowResize = () => { + this.windowWidth = window.innerWidth; + this.windowHeight = window.innerHeight; + } } class Lenis { - constructor({ wrapper = window, content = document.documentElement, wheelEventsTarget = wrapper, eventsTarget = wheelEventsTarget, smoothWheel = true, syncTouch = false, syncTouchLerp = 0.075, touchInertiaMultiplier = 35, duration, easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), lerp = !duration && 0.1, infinite = false, orientation = 'vertical', gestureOrientation = 'vertical', touchMultiplier = 1, wheelMultiplier = 1, normalizeWheel = false, autoResize = true, __experimental__naiveDimensions = false, } = {}) { + constructor({ wrapper = window, content = document.documentElement, wheelEventsTarget = wrapper, eventsTarget = wheelEventsTarget, smoothWheel = true, syncTouch = false, syncTouchLerp = 0.075, touchInertiaMultiplier = 35, duration, easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), lerp = !duration && 0.1, infinite = false, orientation = 'vertical', gestureOrientation = 'vertical', touchMultiplier = 1, wheelMultiplier = 1, autoResize = true, __experimental__naiveDimensions = false, } = {}) { this.__isSmooth = false; this.__isScrolling = false; this.__isStopped = false; @@ -414,7 +424,6 @@ orientation, touchMultiplier, wheelMultiplier, - normalizeWheel, autoResize, __experimental__naiveDimensions, }; @@ -432,7 +441,6 @@ this.virtualScroll = new VirtualScroll(eventsTarget, { touchMultiplier, wheelMultiplier, - normalizeWheel, }); this.virtualScroll.on('scroll', this.onVirtualScroll); } diff --git a/packages/lenis/dist/lenis.min.js b/packages/lenis/dist/lenis.min.js index cd91ade5..71b36ba8 100644 --- a/packages/lenis/dist/lenis.min.js +++ b/packages/lenis/dist/lenis.min.js @@ -1 +1 @@ -var t,e;t=this,e=function(){function t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,l=e,function(t,e,i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*l))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,l;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:l}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=2,normalizeWheel:s=!1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.normalizeWheel=s,this.touchStart={x:null,y:null},this.emitter=new Emitter,this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),this.element.removeEventListener("wheel",this.onWheel,{passive:!1}),this.element.removeEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.removeEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.removeEventListener("touchend",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit("scroll",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=e=>{let{deltaX:i,deltaY:s}=e;this.normalizeWheel&&(i=t(-100,i,100),s=t(-100,s,100)),i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:e})}}return class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:p=!1,orientation:u="vertical",gestureOrientation:d="vertical",touchMultiplier:m=1,wheelMultiplier:g=1,normalizeWheel:v=!1,autoResize:S=!0,__experimental__naiveDimensions:w=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes("touch"),o=i.type.includes("wheel");if(this.options.syncTouch&&s&&"touchstart"===i.type)return void this.reset();const n=0===t&&0===e,l="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===t;if(n||l)return;let r=i.composedPath();if(r=r.slice(0,r.indexOf(this.rootElement)),r.find((t=>{var e,i,n,l,r;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent-touch"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;"both"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:"horizontal"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&"touchend"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion="1.0.40",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:p,gestureOrientation:d,orientation:u,touchMultiplier:m,wheelMultiplier:g,normalizeWheel:v,autoResize:S,__experimental__naiveDimensions:w},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:S}),this.toggleClassName("lenis",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:g,normalizeWheel:v}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName("lenis",!1),this.toggleClassName("lenis-smooth",!1),this.toggleClassName("lenis-scrolling",!1),this.toggleClassName("lenis-stopped",!1),this.toggleClassName("lenis-locked",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:l=this.options.easing,lerp:r=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(e))e=0;else if(["bottom","right","end"].includes(e))e=this.limit;else{let t;if("string"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:l,lerp:r,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName("lenis-smooth",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName("lenis-scrolling",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName("lenis-stopped",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName("lenis-locked",t))}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),this.isSmooth&&(t+=" lenis-smooth"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit("className change",this)}}},"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Lenis=e(); +var t,e;t=this,e=function(){function t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,l=e,function(t,e,i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*l))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,l;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:l}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}const e=100/6;class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.touchStart={x:null,y:null},this.emitter=new Emitter,window.addEventListener("resize",this.onWindowResize,!1),this.onWindowResize(),this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel,{passive:!1}),this.element.removeEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.removeEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.removeEventListener("touchend",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit("scroll",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=t=>{let{deltaX:i,deltaY:s,deltaMode:o}=t;i*=1===o?e:2===o?this.windowWidth:1,s*=1===o?e:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:t})};onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight}}return class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:d=!1,orientation:p="vertical",gestureOrientation:u="vertical",touchMultiplier:m=1,wheelMultiplier:g=1,autoResize:v=!0,__experimental__naiveDimensions:S=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes("touch"),o=i.type.includes("wheel");if(this.options.syncTouch&&s&&"touchstart"===i.type)return void this.reset();const n=0===t&&0===e,l="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===t;if(n||l)return;let r=i.composedPath();if(r=r.slice(0,r.indexOf(this.rootElement)),r.find((t=>{var e,i,n,l,r;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent-touch"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;"both"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:"horizontal"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&"touchend"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion="1.0.40",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:u,orientation:p,touchMultiplier:m,wheelMultiplier:g,autoResize:v,__experimental__naiveDimensions:S},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:v}),this.toggleClassName("lenis",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:g}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName("lenis",!1),this.toggleClassName("lenis-smooth",!1),this.toggleClassName("lenis-scrolling",!1),this.toggleClassName("lenis-stopped",!1),this.toggleClassName("lenis-locked",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:l=this.options.easing,lerp:r=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(e))e=0;else if(["bottom","right","end"].includes(e))e=this.limit;else{let t;if("string"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:l,lerp:r,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName("lenis-smooth",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName("lenis-scrolling",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName("lenis-stopped",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName("lenis-locked",t))}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),this.isSmooth&&(t+=" lenis-smooth"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit("className change",this)}}},"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Lenis=e(); diff --git a/packages/lenis/dist/lenis.mjs b/packages/lenis/dist/lenis.mjs index f5b396b2..10f83046 100644 --- a/packages/lenis/dist/lenis.mjs +++ b/packages/lenis/dist/lenis.mjs @@ -1,2 +1,2 @@ -function t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,l=e,function(t,e,i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*l))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,l;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:l}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=2,normalizeWheel:s=!1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.normalizeWheel=s,this.touchStart={x:null,y:null},this.emitter=new Emitter,this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),this.element.removeEventListener("wheel",this.onWheel,{passive:!1}),this.element.removeEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.removeEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.removeEventListener("touchend",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit("scroll",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=e=>{let{deltaX:i,deltaY:s}=e;this.normalizeWheel&&(i=t(-100,i,100),s=t(-100,s,100)),i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:e})}}class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:p=!1,orientation:u="vertical",gestureOrientation:d="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,normalizeWheel:g=!1,autoResize:S=!0,__experimental__naiveDimensions:w=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes("touch"),o=i.type.includes("wheel");if(this.options.syncTouch&&s&&"touchstart"===i.type)return void this.reset();const n=0===t&&0===e,l="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===t;if(n||l)return;let r=i.composedPath();if(r=r.slice(0,r.indexOf(this.rootElement)),r.find((t=>{var e,i,n,l,r;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent-touch"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;"both"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:"horizontal"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&"touchend"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion="1.0.40",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:p,gestureOrientation:d,orientation:u,touchMultiplier:m,wheelMultiplier:v,normalizeWheel:g,autoResize:S,__experimental__naiveDimensions:w},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:S}),this.toggleClassName("lenis",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:v,normalizeWheel:g}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName("lenis",!1),this.toggleClassName("lenis-smooth",!1),this.toggleClassName("lenis-scrolling",!1),this.toggleClassName("lenis-stopped",!1),this.toggleClassName("lenis-locked",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:l=this.options.easing,lerp:r=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(e))e=0;else if(["bottom","right","end"].includes(e))e=this.limit;else{let t;if("string"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:l,lerp:r,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName("lenis-smooth",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName("lenis-scrolling",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName("lenis-stopped",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName("lenis-locked",t))}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),this.isSmooth&&(t+=" lenis-smooth"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit("className change",this)}}export{Lenis as default}; +function t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,r=e,function(t,e,i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*r))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,r;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:r}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=r}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}const e=100/6;class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.touchStart={x:null,y:null},this.emitter=new Emitter,window.addEventListener("resize",this.onWindowResize,!1),this.onWindowResize(),this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel,{passive:!1}),this.element.removeEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.removeEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.removeEventListener("touchend",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit("scroll",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=t=>{let{deltaX:i,deltaY:s,deltaMode:o}=t;i*=1===o?e:2===o?this.windowWidth:1,s*=1===o?e:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:t})};onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight}}class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:r=.075,touchInertiaMultiplier:l=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:d=!1,orientation:p="vertical",gestureOrientation:u="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,__experimental__naiveDimensions:S=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes("touch"),o=i.type.includes("wheel");if(this.options.syncTouch&&s&&"touchstart"===i.type)return void this.reset();const n=0===t&&0===e,r="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===t;if(n||r)return;let l=i.composedPath();if(l=l.slice(0,l.indexOf(this.rootElement)),l.find((t=>{var e,i,n,r,l;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent-touch"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,"data-lenis-prevent-wheel"))||(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis"))&&!(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis-stopped"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;"both"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:"horizontal"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&"touchend"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion="1.0.40",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:r,touchInertiaMultiplier:l,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:u,orientation:p,touchMultiplier:m,wheelMultiplier:v,autoResize:g,__experimental__naiveDimensions:S},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:g}),this.toggleClassName("lenis",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:v}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName("lenis",!1),this.toggleClassName("lenis-smooth",!1),this.toggleClassName("lenis-scrolling",!1),this.toggleClassName("lenis-stopped",!1),this.toggleClassName("lenis-locked",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:r=this.options.easing,lerp:l=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(e))e=0;else if(["bottom","right","end"].includes(e))e=this.limit;else{let t;if("string"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:r,lerp:l,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName("lenis-smooth",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName("lenis-scrolling",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName("lenis-stopped",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName("lenis-locked",t))}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),this.isSmooth&&(t+=" lenis-smooth"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit("className change",this)}}export{Lenis as default}; //# sourceMappingURL=lenis.mjs.map diff --git a/packages/lenis/dist/lenis.mjs.map b/packages/lenis/dist/lenis.mjs.map index 393a0474..8d0b2f64 100644 --- a/packages/lenis/dist/lenis.mjs.map +++ b/packages/lenis/dist/lenis.mjs.map @@ -1 +1 @@ -{"version":3,"file":"lenis.mjs","sources":["../src/maths.js","../src/animate.js","../src/dimensions.js","../src/debounce.js","../src/emitter.js","../src/virtual-scroll.js","../../src/index.ts"],"sourcesContent":["// Clamp a value between a minimum and maximum value\nexport function clamp(min, input, max) {\n return Math.max(min, Math.min(input, max))\n}\n\n// Truncate a floating-point number to a specified number of decimal places\nexport function truncate(value, decimals = 0) {\n return parseFloat(value.toFixed(decimals))\n}\n\n// Linearly interpolate between two values using an amount (0 <= t <= 1)\nexport function lerp(x, y, t) {\n return (1 - t) * x + t * y\n}\n\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\nexport function damp(x, y, lambda, dt) {\n return lerp(x, y, 1 - Math.exp(-lambda * dt))\n}\n\n// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor\n// https://anguscroll.com/just/just-modulo\nexport function modulo(n, d) {\n return ((n % d) + d) % d\n}\n","import { clamp, damp } from './maths'\n\n// Animate class to handle value animations with lerping or easing\nexport class Animate {\n // Advance the animation by the given delta time\n advance(deltaTime) {\n if (!this.isRunning) return\n\n let completed = false\n\n if (this.lerp) {\n this.value = damp(this.value, this.to, this.lerp * 60, deltaTime)\n if (Math.round(this.value) === this.to) {\n this.value = this.to\n completed = true\n }\n } else {\n this.currentTime += deltaTime\n const linearProgress = clamp(0, this.currentTime / this.duration, 1)\n\n completed = linearProgress >= 1\n const easedProgress = completed ? 1 : this.easing(linearProgress)\n this.value = this.from + (this.to - this.from) * easedProgress\n }\n\n // Call the onUpdate callback with the current value and completed status\n this.onUpdate?.(this.value, completed)\n\n if (completed) {\n this.stop()\n }\n }\n\n // Stop the animation\n stop() {\n this.isRunning = false\n }\n\n // Set up the animation from a starting value to an ending value\n // with optional parameters for lerping, duration, easing, and onUpdate callback\n fromTo(\n from,\n to,\n { lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }\n ) {\n this.from = this.value = from\n this.to = to\n this.lerp = lerp\n this.duration = duration\n this.easing = easing\n this.currentTime = 0\n this.isRunning = true\n\n onStart?.()\n this.onUpdate = onUpdate\n }\n}\n","import { debounce } from './debounce'\n\nexport class Dimensions {\n constructor({\n wrapper,\n content,\n autoResize = true,\n debounce: debounceValue = 250,\n } = {}) {\n this.wrapper = wrapper\n this.content = content\n\n if (autoResize) {\n this.debouncedResize = debounce(this.resize, debounceValue)\n\n if (this.wrapper === window) {\n window.addEventListener('resize', this.debouncedResize, false)\n } else {\n this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize)\n this.wrapperResizeObserver.observe(this.wrapper)\n }\n\n this.contentResizeObserver = new ResizeObserver(this.debouncedResize)\n this.contentResizeObserver.observe(this.content)\n }\n\n this.resize()\n }\n\n destroy() {\n this.wrapperResizeObserver?.disconnect()\n this.contentResizeObserver?.disconnect()\n window.removeEventListener('resize', this.debouncedResize, false)\n }\n\n resize = () => {\n this.onWrapperResize()\n this.onContentResize()\n }\n\n onWrapperResize = () => {\n if (this.wrapper === window) {\n this.width = window.innerWidth\n this.height = window.innerHeight\n } else {\n this.width = this.wrapper.clientWidth\n this.height = this.wrapper.clientHeight\n }\n }\n\n onContentResize = () => {\n if (this.wrapper === window) {\n this.scrollHeight = this.content.scrollHeight\n this.scrollWidth = this.content.scrollWidth\n } else {\n this.scrollHeight = this.wrapper.scrollHeight\n this.scrollWidth = this.wrapper.scrollWidth\n }\n }\n\n get limit() {\n return {\n x: this.scrollWidth - this.width,\n y: this.scrollHeight - this.height,\n }\n }\n}\n","export function debounce(callback, delay) {\n let timer\n return function () {\n let args = arguments\n let context = this\n clearTimeout(timer)\n timer = setTimeout(function () {\n callback.apply(context, args)\n }, delay)\n }\n}\n","export class Emitter {\n constructor() {\n this.events = {}\n }\n\n emit(event, ...args) {\n let callbacks = this.events[event] || []\n for (let i = 0, length = callbacks.length; i < length; i++) {\n callbacks[i](...args)\n }\n }\n\n on(event, cb) {\n // Add the callback to the event's callback list, or create a new list with the callback\n this.events[event]?.push(cb) || (this.events[event] = [cb])\n\n // Return an unsubscribe function\n return () => {\n this.events[event] = this.events[event]?.filter((i) => cb !== i)\n }\n }\n\n off(event, callback) {\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\n }\n\n destroy() {\n this.events = {}\n }\n}\n","import { Emitter } from './emitter'\nimport { clamp } from './maths'\n\nexport class VirtualScroll {\n constructor(\n element,\n { wheelMultiplier = 1, touchMultiplier = 2, normalizeWheel = false }\n ) {\n this.element = element\n this.wheelMultiplier = wheelMultiplier\n this.touchMultiplier = touchMultiplier\n this.normalizeWheel = normalizeWheel\n\n this.touchStart = {\n x: null,\n y: null,\n }\n\n this.emitter = new Emitter()\n\n this.element.addEventListener('wheel', this.onWheel, { passive: false })\n this.element.addEventListener('touchstart', this.onTouchStart, {\n passive: false,\n })\n this.element.addEventListener('touchmove', this.onTouchMove, {\n passive: false,\n })\n this.element.addEventListener('touchend', this.onTouchEnd, {\n passive: false,\n })\n }\n\n // Add an event listener for the given event and callback\n on(event, callback) {\n return this.emitter.on(event, callback)\n }\n\n // Remove all event listeners and clean up\n destroy() {\n this.emitter.destroy()\n\n this.element.removeEventListener('wheel', this.onWheel, {\n passive: false,\n })\n this.element.removeEventListener('touchstart', this.onTouchStart, {\n passive: false,\n })\n this.element.removeEventListener('touchmove', this.onTouchMove, {\n passive: false,\n })\n this.element.removeEventListener('touchend', this.onTouchEnd, {\n passive: false,\n })\n }\n\n // Event handler for 'touchstart' event\n onTouchStart = (event) => {\n const { clientX, clientY } = event.targetTouches\n ? event.targetTouches[0]\n : event\n\n this.touchStart.x = clientX\n this.touchStart.y = clientY\n\n this.lastDelta = {\n x: 0,\n y: 0,\n }\n\n this.emitter.emit('scroll', {\n deltaX: 0,\n deltaY: 0,\n event,\n })\n }\n\n // Event handler for 'touchmove' event\n onTouchMove = (event) => {\n const { clientX, clientY } = event.targetTouches\n ? event.targetTouches[0]\n : event\n\n const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier\n const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier\n\n this.touchStart.x = clientX\n this.touchStart.y = clientY\n\n this.lastDelta = {\n x: deltaX,\n y: deltaY,\n }\n\n this.emitter.emit('scroll', {\n deltaX,\n deltaY,\n event,\n })\n }\n\n onTouchEnd = (event) => {\n this.emitter.emit('scroll', {\n deltaX: this.lastDelta.x,\n deltaY: this.lastDelta.y,\n event,\n })\n }\n\n // Event handler for 'wheel' event\n onWheel = (event) => {\n let { deltaX, deltaY } = event\n\n if (this.normalizeWheel) {\n deltaX = clamp(-100, deltaX, 100)\n deltaY = clamp(-100, deltaY, 100)\n }\n\n deltaX *= this.wheelMultiplier\n deltaY *= this.wheelMultiplier\n\n this.emitter.emit('scroll', { deltaX, deltaY, event })\n }\n}\n","import { version } from '../package.json'\nimport { Animate } from './animate'\nimport { Dimensions } from './dimensions'\nimport { Emitter } from './emitter'\nimport { clamp, modulo } from './maths'\nimport { VirtualScroll } from './virtual-scroll'\n\n// Technical explanation\n// - listen to 'wheel' events\n// - prevent 'wheel' event to prevent scroll\n// - normalize wheel delta\n// - add delta to targetScroll\n// - animate scroll to targetScroll (smooth context)\n// - if animation is not running, listen to 'scroll' events (native context)\n\ntype EasingFunction = (t: number) => number\ntype Orientation = 'vertical' | 'horizontal'\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\n\nexport type LenisOptions = {\n wrapper?: Window | HTMLElement\n content?: HTMLElement\n wheelEventsTarget?: Window | HTMLElement\n eventsTarget?: Window | HTMLElement\n smoothWheel?: boolean\n syncTouch?: boolean\n syncTouchLerp?: number\n touchInertiaMultiplier?: number\n duration?: number\n easing?: EasingFunction\n lerp?: number\n infinite?: boolean\n orientation?: Orientation\n gestureOrientation?: GestureOrientation\n touchMultiplier?: number\n wheelMultiplier?: number\n normalizeWheel?: boolean\n autoResize?: boolean\n __experimental__naiveDimensions?: boolean\n}\n\nexport default class Lenis {\n __isSmooth: boolean = false // true if scroll should be animated\n __isScrolling: boolean = false // true when scroll is animating\n __isStopped: boolean = false // true if user should not be able to scroll - enable/disable programmatically\n __isLocked: boolean = false // same as isStopped but enabled/disabled when scroll reaches target\n\n constructor({\n wrapper = window,\n content = document.documentElement,\n wheelEventsTarget = wrapper, // deprecated\n eventsTarget = wheelEventsTarget,\n smoothWheel = true,\n syncTouch = false,\n syncTouchLerp = 0.075,\n touchInertiaMultiplier = 35,\n duration, // in seconds\n easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),\n lerp = !duration && 0.1,\n infinite = false,\n orientation = 'vertical', // vertical, horizontal\n gestureOrientation = 'vertical', // vertical, horizontal, both\n touchMultiplier = 1,\n wheelMultiplier = 1,\n normalizeWheel = false, // deprecated\n autoResize = true,\n __experimental__naiveDimensions = false,\n }: LenisOptions = {}) {\n window.lenisVersion = version\n\n // if wrapper is html or body, fallback to window\n if (wrapper === document.documentElement || wrapper === document.body) {\n wrapper = window\n }\n\n this.options = {\n wrapper,\n content,\n wheelEventsTarget,\n eventsTarget,\n smoothWheel,\n syncTouch,\n syncTouchLerp,\n touchInertiaMultiplier,\n duration,\n easing,\n lerp,\n infinite,\n gestureOrientation,\n orientation,\n touchMultiplier,\n wheelMultiplier,\n normalizeWheel,\n autoResize,\n __experimental__naiveDimensions,\n }\n\n this.animate = new Animate()\n this.emitter = new Emitter()\n this.dimensions = new Dimensions({ wrapper, content, autoResize })\n this.toggleClassName('lenis', true)\n\n this.velocity = 0\n this.isLocked = false\n this.isStopped = false\n this.isSmooth = syncTouch || smoothWheel\n this.isScrolling = false\n this.targetScroll = this.animatedScroll = this.actualScroll\n\n this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false)\n\n this.virtualScroll = new VirtualScroll(eventsTarget, {\n touchMultiplier,\n wheelMultiplier,\n normalizeWheel,\n })\n this.virtualScroll.on('scroll', this.onVirtualScroll)\n }\n\n destroy() {\n this.emitter.destroy()\n\n this.options.wrapper.removeEventListener(\n 'scroll',\n this.onNativeScroll,\n false\n )\n\n this.virtualScroll.destroy()\n this.dimensions.destroy()\n\n this.toggleClassName('lenis', false)\n this.toggleClassName('lenis-smooth', false)\n this.toggleClassName('lenis-scrolling', false)\n this.toggleClassName('lenis-stopped', false)\n this.toggleClassName('lenis-locked', false)\n }\n\n on(event: string, callback: Function) {\n return this.emitter.on(event, callback)\n }\n\n off(event: string, callback: Function) {\n return this.emitter.off(event, callback)\n }\n\n private setScroll(scroll) {\n // apply scroll value immediately\n if (this.isHorizontal) {\n this.rootElement.scrollLeft = scroll\n } else {\n this.rootElement.scrollTop = scroll\n }\n }\n\n private onVirtualScroll = ({ deltaX, deltaY, event }) => {\n // keep zoom feature\n if (event.ctrlKey) return\n\n const isTouch = event.type.includes('touch')\n const isWheel = event.type.includes('wheel')\n\n const isTapToStop =\n this.options.syncTouch && isTouch && event.type === 'touchstart'\n\n if (isTapToStop) {\n this.reset()\n return\n }\n\n const isClick = deltaX === 0 && deltaY === 0 // click event\n\n // const isPullToRefresh =\n // this.options.gestureOrientation === 'vertical' &&\n // this.scroll === 0 &&\n // !this.options.infinite &&\n // deltaY <= 5 // touch pull to refresh, not reliable yet\n\n const isUnknownGesture =\n (this.options.gestureOrientation === 'vertical' && deltaY === 0) ||\n (this.options.gestureOrientation === 'horizontal' && deltaX === 0)\n\n if (isClick || isUnknownGesture) {\n // console.log('prevent')\n return\n }\n\n // catch if scrolling on nested scroll elements\n let composedPath = event.composedPath()\n composedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement)) // remove parents elements\n\n if (\n !!composedPath.find(\n (node) =>\n node.hasAttribute?.('data-lenis-prevent') ||\n (isTouch && node.hasAttribute?.('data-lenis-prevent-touch')) ||\n (isWheel && node.hasAttribute?.('data-lenis-prevent-wheel')) ||\n (node.classList?.contains('lenis') &&\n !node.classList?.contains('lenis-stopped')) // nested lenis instance\n )\n )\n return\n\n if (this.isStopped || this.isLocked) {\n event.preventDefault() // this will stop forwarding the event to the parent, this is problematic\n return\n }\n\n this.isSmooth =\n (this.options.syncTouch && isTouch) ||\n (this.options.smoothWheel && isWheel)\n\n if (!this.isSmooth) {\n this.isScrolling = false\n this.animate.stop()\n return\n }\n\n event.preventDefault()\n\n let delta = deltaY\n if (this.options.gestureOrientation === 'both') {\n delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX\n } else if (this.options.gestureOrientation === 'horizontal') {\n delta = deltaX\n }\n\n const syncTouch = isTouch && this.options.syncTouch\n const isTouchEnd = isTouch && event.type === 'touchend'\n\n const hasTouchInertia = isTouchEnd && Math.abs(delta) > 5\n\n if (hasTouchInertia) {\n delta = this.velocity * this.options.touchInertiaMultiplier\n }\n\n this.scrollTo(this.targetScroll + delta, {\n programmatic: false,\n ...(syncTouch\n ? {\n lerp: hasTouchInertia ? this.options.syncTouchLerp : 1,\n }\n : {\n lerp: this.options.lerp,\n duration: this.options.duration,\n easing: this.options.easing,\n }),\n })\n }\n\n resize() {\n this.dimensions.resize()\n }\n\n private emit() {\n this.emitter.emit('scroll', this)\n }\n\n private onNativeScroll = () => {\n if (this.__preventNextScrollEvent) return\n\n if (!this.isScrolling) {\n const lastScroll = this.animatedScroll\n this.animatedScroll = this.targetScroll = this.actualScroll\n this.velocity = 0\n this.direction = Math.sign(this.animatedScroll - lastScroll)\n this.emit()\n }\n }\n\n private reset() {\n this.isLocked = false\n this.isScrolling = false\n this.animatedScroll = this.targetScroll = this.actualScroll\n this.velocity = 0\n this.animate.stop()\n }\n\n start() {\n if (!this.isStopped) return\n this.isStopped = false\n\n this.reset()\n }\n\n stop() {\n if (this.isStopped) return\n this.isStopped = true\n this.animate.stop()\n\n this.reset()\n }\n\n raf(time: number) {\n const deltaTime = time - (this.time || time)\n this.time = time\n\n this.animate.advance(deltaTime * 0.001)\n }\n\n scrollTo(\n target: number | string | HTMLElement,\n {\n offset = 0,\n immediate = false,\n lock = false,\n duration = this.options.duration,\n easing = this.options.easing,\n lerp = !duration && this.options.lerp,\n onComplete,\n force = false, // scroll even if stopped\n programmatic = true, // called from outside of the class\n }: {\n offset?: number\n immediate?: boolean\n lock?: boolean\n duration?: number\n easing?: EasingFunction\n lerp?: number\n onComplete?: (lenis: Lenis) => void\n force?: boolean\n programmatic?: boolean\n } = {}\n ) {\n if ((this.isStopped || this.isLocked) && !force) return\n\n // keywords\n if (['top', 'left', 'start'].includes(target)) {\n target = 0\n } else if (['bottom', 'right', 'end'].includes(target)) {\n target = this.limit\n } else {\n let node\n\n if (typeof target === 'string') {\n // CSS selector\n node = document.querySelector(target)\n } else if (target?.nodeType) {\n // Node element\n node = target\n }\n\n if (node) {\n if (this.options.wrapper !== window) {\n // nested scroll offset correction\n const wrapperRect = this.options.wrapper.getBoundingClientRect()\n offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top\n }\n\n const rect = node.getBoundingClientRect()\n\n target =\n (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll\n }\n }\n\n if (typeof target !== 'number') return\n\n target += offset\n target = Math.round(target)\n\n if (this.options.infinite) {\n if (programmatic) {\n this.targetScroll = this.animatedScroll = this.scroll\n }\n } else {\n target = clamp(0, target, this.limit)\n }\n\n if (immediate) {\n this.animatedScroll = this.targetScroll = target\n this.setScroll(this.scroll)\n this.reset()\n onComplete?.(this)\n return\n }\n\n if (!programmatic) {\n if (target === this.targetScroll) return\n\n this.targetScroll = target\n }\n\n this.animate.fromTo(this.animatedScroll, target, {\n duration,\n easing,\n lerp,\n onStart: () => {\n // started\n if (lock) this.isLocked = true\n this.isScrolling = true\n },\n onUpdate: (value: number, completed: boolean) => {\n this.isScrolling = true\n\n // updated\n this.velocity = value - this.animatedScroll\n this.direction = Math.sign(this.velocity)\n\n this.animatedScroll = value\n this.setScroll(this.scroll)\n\n if (programmatic) {\n // wheel during programmatic should stop it\n this.targetScroll = value\n }\n\n if (!completed) this.emit()\n\n if (completed) {\n this.reset()\n this.emit()\n onComplete?.(this)\n\n // avoid emitting event twice\n this.__preventNextScrollEvent = true\n requestAnimationFrame(() => {\n delete this.__preventNextScrollEvent\n })\n }\n },\n })\n }\n\n get rootElement() {\n return this.options.wrapper === window\n ? document.documentElement\n : this.options.wrapper\n }\n\n get limit() {\n if (this.options.__experimental__naiveDimensions) {\n if (this.isHorizontal) {\n return this.rootElement.scrollWidth - this.rootElement.clientWidth\n } else {\n return this.rootElement.scrollHeight - this.rootElement.clientHeight\n }\n } else {\n return this.dimensions.limit[this.isHorizontal ? 'x' : 'y']\n }\n }\n\n get isHorizontal() {\n return this.options.orientation === 'horizontal'\n }\n\n get actualScroll() {\n // value browser takes into account\n return this.isHorizontal\n ? this.rootElement.scrollLeft\n : this.rootElement.scrollTop\n }\n\n get scroll() {\n return this.options.infinite\n ? modulo(this.animatedScroll, this.limit)\n : this.animatedScroll\n }\n\n get progress() {\n // avoid progress to be NaN\n return this.limit === 0 ? 1 : this.scroll / this.limit\n }\n\n get isSmooth() {\n return this.__isSmooth\n }\n\n private set isSmooth(value: boolean) {\n if (this.__isSmooth !== value) {\n this.__isSmooth = value\n this.toggleClassName('lenis-smooth', value)\n }\n }\n\n get isScrolling() {\n return this.__isScrolling\n }\n\n private set isScrolling(value: boolean) {\n if (this.__isScrolling !== value) {\n this.__isScrolling = value\n this.toggleClassName('lenis-scrolling', value)\n }\n }\n\n get isStopped() {\n return this.__isStopped\n }\n\n private set isStopped(value: boolean) {\n if (this.__isStopped !== value) {\n this.__isStopped = value\n this.toggleClassName('lenis-stopped', value)\n }\n }\n\n get isLocked() {\n return this.__isLocked\n }\n\n private set isLocked(value: boolean) {\n if (this.__isLocked !== value) {\n this.__isLocked = value\n this.toggleClassName('lenis-locked', value)\n }\n }\n\n get className() {\n let className = 'lenis'\n if (this.isStopped) className += ' lenis-stopped'\n if (this.isLocked) className += ' lenis-locked'\n if (this.isScrolling) className += ' lenis-scrolling'\n if (this.isSmooth) className += ' lenis-smooth'\n return className\n }\n\n private toggleClassName(name: string, value: boolean) {\n this.rootElement.classList.toggle(name, value)\n this.emitter.emit('className change', this)\n }\n}\n"],"names":["clamp","min","input","max","Math","Animate","advance","deltaTime","this","isRunning","completed","lerp","value","x","y","to","lambda","dt","t","exp","round","currentTime","linearProgress","duration","easedProgress","easing","from","onUpdate","stop","fromTo","onStart","Dimensions","constructor","wrapper","content","autoResize","debounce","debounceValue","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","resize","window","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","removeEventListener","onWrapperResize","onContentResize","width","innerWidth","height","innerHeight","clientWidth","clientHeight","scrollHeight","scrollWidth","limit","Emitter","events","emit","event","callbacks","i","length","on","cb","push","filter","off","VirtualScroll","element","wheelMultiplier","touchMultiplier","normalizeWheel","touchStart","emitter","onWheel","passive","onTouchStart","onTouchMove","onTouchEnd","clientX","clientY","targetTouches","lastDelta","deltaX","deltaY","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","__experimental__naiveDimensions","__isSmooth","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","options","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","isStopped","isLocked","preventDefault","isSmooth","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__preventNextScrollEvent","lastScroll","animatedScroll","actualScroll","direction","sign","lenisVersion","body","dimensions","toggleClassName","virtualScroll","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","time","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","requestAnimationFrame","n","d","progress","className","name","toggle"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"lenis.mjs","sources":["../src/maths.js","../src/animate.js","../src/dimensions.js","../src/debounce.js","../src/emitter.js","../src/virtual-scroll.js","../../src/index.ts"],"sourcesContent":["// Clamp a value between a minimum and maximum value\r\nexport function clamp(min, input, max) {\r\n return Math.max(min, Math.min(input, max))\r\n}\r\n\r\n// Truncate a floating-point number to a specified number of decimal places\r\nexport function truncate(value, decimals = 0) {\r\n return parseFloat(value.toFixed(decimals))\r\n}\r\n\r\n// Linearly interpolate between two values using an amount (0 <= t <= 1)\r\nexport function lerp(x, y, t) {\r\n return (1 - t) * x + t * y\r\n}\r\n\r\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\r\nexport function damp(x, y, lambda, dt) {\r\n return lerp(x, y, 1 - Math.exp(-lambda * dt))\r\n}\r\n\r\n// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor\r\n// https://anguscroll.com/just/just-modulo\r\nexport function modulo(n, d) {\r\n return ((n % d) + d) % d\r\n}\r\n","import { clamp, damp } from './maths'\r\n\r\n// Animate class to handle value animations with lerping or easing\r\nexport class Animate {\r\n // Advance the animation by the given delta time\r\n advance(deltaTime) {\r\n if (!this.isRunning) return\r\n\r\n let completed = false\r\n\r\n if (this.lerp) {\r\n this.value = damp(this.value, this.to, this.lerp * 60, deltaTime)\r\n if (Math.round(this.value) === this.to) {\r\n this.value = this.to\r\n completed = true\r\n }\r\n } else {\r\n this.currentTime += deltaTime\r\n const linearProgress = clamp(0, this.currentTime / this.duration, 1)\r\n\r\n completed = linearProgress >= 1\r\n const easedProgress = completed ? 1 : this.easing(linearProgress)\r\n this.value = this.from + (this.to - this.from) * easedProgress\r\n }\r\n\r\n // Call the onUpdate callback with the current value and completed status\r\n this.onUpdate?.(this.value, completed)\r\n\r\n if (completed) {\r\n this.stop()\r\n }\r\n }\r\n\r\n // Stop the animation\r\n stop() {\r\n this.isRunning = false\r\n }\r\n\r\n // Set up the animation from a starting value to an ending value\r\n // with optional parameters for lerping, duration, easing, and onUpdate callback\r\n fromTo(\r\n from,\r\n to,\r\n { lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }\r\n ) {\r\n this.from = this.value = from\r\n this.to = to\r\n this.lerp = lerp\r\n this.duration = duration\r\n this.easing = easing\r\n this.currentTime = 0\r\n this.isRunning = true\r\n\r\n onStart?.()\r\n this.onUpdate = onUpdate\r\n }\r\n}\r\n","import { debounce } from './debounce'\r\n\r\nexport class Dimensions {\r\n constructor({\r\n wrapper,\r\n content,\r\n autoResize = true,\r\n debounce: debounceValue = 250,\r\n } = {}) {\r\n this.wrapper = wrapper\r\n this.content = content\r\n\r\n if (autoResize) {\r\n this.debouncedResize = debounce(this.resize, debounceValue)\r\n\r\n if (this.wrapper === window) {\r\n window.addEventListener('resize', this.debouncedResize, false)\r\n } else {\r\n this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize)\r\n this.wrapperResizeObserver.observe(this.wrapper)\r\n }\r\n\r\n this.contentResizeObserver = new ResizeObserver(this.debouncedResize)\r\n this.contentResizeObserver.observe(this.content)\r\n }\r\n\r\n this.resize()\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver?.disconnect()\r\n this.contentResizeObserver?.disconnect()\r\n window.removeEventListener('resize', this.debouncedResize, false)\r\n }\r\n\r\n resize = () => {\r\n this.onWrapperResize()\r\n this.onContentResize()\r\n }\r\n\r\n onWrapperResize = () => {\r\n if (this.wrapper === window) {\r\n this.width = window.innerWidth\r\n this.height = window.innerHeight\r\n } else {\r\n this.width = this.wrapper.clientWidth\r\n this.height = this.wrapper.clientHeight\r\n }\r\n }\r\n\r\n onContentResize = () => {\r\n if (this.wrapper === window) {\r\n this.scrollHeight = this.content.scrollHeight\r\n this.scrollWidth = this.content.scrollWidth\r\n } else {\r\n this.scrollHeight = this.wrapper.scrollHeight\r\n this.scrollWidth = this.wrapper.scrollWidth\r\n }\r\n }\r\n\r\n get limit() {\r\n return {\r\n x: this.scrollWidth - this.width,\r\n y: this.scrollHeight - this.height,\r\n }\r\n }\r\n}\r\n","export function debounce(callback, delay) {\r\n let timer\r\n return function () {\r\n let args = arguments\r\n let context = this\r\n clearTimeout(timer)\r\n timer = setTimeout(function () {\r\n callback.apply(context, args)\r\n }, delay)\r\n }\r\n}\r\n","export class Emitter {\r\n constructor() {\r\n this.events = {}\r\n }\r\n\r\n emit(event, ...args) {\r\n let callbacks = this.events[event] || []\r\n for (let i = 0, length = callbacks.length; i < length; i++) {\r\n callbacks[i](...args)\r\n }\r\n }\r\n\r\n on(event, cb) {\r\n // Add the callback to the event's callback list, or create a new list with the callback\r\n this.events[event]?.push(cb) || (this.events[event] = [cb])\r\n\r\n // Return an unsubscribe function\r\n return () => {\r\n this.events[event] = this.events[event]?.filter((i) => cb !== i)\r\n }\r\n }\r\n\r\n off(event, callback) {\r\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\r\n }\r\n\r\n destroy() {\r\n this.events = {}\r\n }\r\n}\r\n","import { Emitter } from './emitter'\r\n\r\nconst LINE_HEIGHT = 100 / 6\r\n\r\nexport class VirtualScroll {\r\n constructor(element, { wheelMultiplier = 1, touchMultiplier = 1 }) {\r\n this.element = element\r\n this.wheelMultiplier = wheelMultiplier\r\n this.touchMultiplier = touchMultiplier\r\n\r\n this.touchStart = {\r\n x: null,\r\n y: null,\r\n }\r\n\r\n this.emitter = new Emitter()\r\n window.addEventListener('resize', this.onWindowResize, false)\r\n this.onWindowResize()\r\n\r\n this.element.addEventListener('wheel', this.onWheel, { passive: false })\r\n this.element.addEventListener('touchstart', this.onTouchStart, {\r\n passive: false,\r\n })\r\n this.element.addEventListener('touchmove', this.onTouchMove, {\r\n passive: false,\r\n })\r\n this.element.addEventListener('touchend', this.onTouchEnd, {\r\n passive: false,\r\n })\r\n }\r\n\r\n // Add an event listener for the given event and callback\r\n on(event, callback) {\r\n return this.emitter.on(event, callback)\r\n }\r\n\r\n // Remove all event listeners and clean up\r\n destroy() {\r\n this.emitter.destroy()\r\n\r\n window.removeEventListener('resize', this.onWindowResize, false)\r\n\r\n this.element.removeEventListener('wheel', this.onWheel, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchstart', this.onTouchStart, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchmove', this.onTouchMove, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchend', this.onTouchEnd, {\r\n passive: false,\r\n })\r\n }\r\n\r\n // Event handler for 'touchstart' event\r\n onTouchStart = (event) => {\r\n const { clientX, clientY } = event.targetTouches\r\n ? event.targetTouches[0]\r\n : event\r\n\r\n this.touchStart.x = clientX\r\n this.touchStart.y = clientY\r\n\r\n this.lastDelta = {\r\n x: 0,\r\n y: 0,\r\n }\r\n\r\n this.emitter.emit('scroll', {\r\n deltaX: 0,\r\n deltaY: 0,\r\n event,\r\n })\r\n }\r\n\r\n // Event handler for 'touchmove' event\r\n onTouchMove = (event) => {\r\n const { clientX, clientY } = event.targetTouches\r\n ? event.targetTouches[0]\r\n : event\r\n\r\n const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier\r\n const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier\r\n\r\n this.touchStart.x = clientX\r\n this.touchStart.y = clientY\r\n\r\n this.lastDelta = {\r\n x: deltaX,\r\n y: deltaY,\r\n }\r\n\r\n this.emitter.emit('scroll', {\r\n deltaX,\r\n deltaY,\r\n event,\r\n })\r\n }\r\n\r\n onTouchEnd = (event) => {\r\n this.emitter.emit('scroll', {\r\n deltaX: this.lastDelta.x,\r\n deltaY: this.lastDelta.y,\r\n event,\r\n })\r\n }\r\n\r\n // Event handler for 'wheel' event\r\n onWheel = (event) => {\r\n let { deltaX, deltaY, deltaMode } = event\r\n\r\n const multiplierX =\r\n deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowWidth : 1\r\n const multiplierY =\r\n deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowHeight : 1\r\n\r\n deltaX *= multiplierX\r\n deltaY *= multiplierY\r\n\r\n deltaX *= this.wheelMultiplier\r\n deltaY *= this.wheelMultiplier\r\n\r\n this.emitter.emit('scroll', { deltaX, deltaY, event })\r\n }\r\n\r\n onWindowResize = () => {\r\n this.windowWidth = window.innerWidth\r\n this.windowHeight = window.innerHeight\r\n }\r\n}\r\n","import { version } from '../package.json'\r\nimport { Animate } from './animate'\r\nimport { Dimensions } from './dimensions'\r\nimport { Emitter } from './emitter'\r\nimport { clamp, modulo } from './maths'\r\nimport { VirtualScroll } from './virtual-scroll'\r\n\r\n// Technical explanation\r\n// - listen to 'wheel' events\r\n// - prevent 'wheel' event to prevent scroll\r\n// - normalize wheel delta\r\n// - add delta to targetScroll\r\n// - animate scroll to targetScroll (smooth context)\r\n// - if animation is not running, listen to 'scroll' events (native context)\r\n\r\ntype EasingFunction = (t: number) => number\r\ntype Orientation = 'vertical' | 'horizontal'\r\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\r\n\r\nexport type LenisOptions = {\r\n wrapper?: Window | HTMLElement\r\n content?: HTMLElement\r\n wheelEventsTarget?: Window | HTMLElement\r\n eventsTarget?: Window | HTMLElement\r\n smoothWheel?: boolean\r\n syncTouch?: boolean\r\n syncTouchLerp?: number\r\n touchInertiaMultiplier?: number\r\n duration?: number\r\n easing?: EasingFunction\r\n lerp?: number\r\n infinite?: boolean\r\n orientation?: Orientation\r\n gestureOrientation?: GestureOrientation\r\n touchMultiplier?: number\r\n wheelMultiplier?: number\r\n autoResize?: boolean\r\n __experimental__naiveDimensions?: boolean\r\n}\r\n\r\nexport default class Lenis {\r\n __isSmooth: boolean = false // true if scroll should be animated\r\n __isScrolling: boolean = false // true when scroll is animating\r\n __isStopped: boolean = false // true if user should not be able to scroll - enable/disable programmatically\r\n __isLocked: boolean = false // same as isStopped but enabled/disabled when scroll reaches target\r\n\r\n constructor({\r\n wrapper = window,\r\n content = document.documentElement,\r\n wheelEventsTarget = wrapper, // deprecated\r\n eventsTarget = wheelEventsTarget,\r\n smoothWheel = true,\r\n syncTouch = false,\r\n syncTouchLerp = 0.075,\r\n touchInertiaMultiplier = 35,\r\n duration, // in seconds\r\n easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),\r\n lerp = !duration && 0.1,\r\n infinite = false,\r\n orientation = 'vertical', // vertical, horizontal\r\n gestureOrientation = 'vertical', // vertical, horizontal, both\r\n touchMultiplier = 1,\r\n wheelMultiplier = 1,\r\n autoResize = true,\r\n __experimental__naiveDimensions = false,\r\n }: LenisOptions = {}) {\r\n window.lenisVersion = version\r\n\r\n // if wrapper is html or body, fallback to window\r\n if (wrapper === document.documentElement || wrapper === document.body) {\r\n wrapper = window\r\n }\r\n\r\n this.options = {\r\n wrapper,\r\n content,\r\n wheelEventsTarget,\r\n eventsTarget,\r\n smoothWheel,\r\n syncTouch,\r\n syncTouchLerp,\r\n touchInertiaMultiplier,\r\n duration,\r\n easing,\r\n lerp,\r\n infinite,\r\n gestureOrientation,\r\n orientation,\r\n touchMultiplier,\r\n wheelMultiplier,\r\n autoResize,\r\n __experimental__naiveDimensions,\r\n }\r\n\r\n this.animate = new Animate()\r\n this.emitter = new Emitter()\r\n this.dimensions = new Dimensions({ wrapper, content, autoResize })\r\n this.toggleClassName('lenis', true)\r\n\r\n this.velocity = 0\r\n this.isLocked = false\r\n this.isStopped = false\r\n this.isSmooth = syncTouch || smoothWheel\r\n this.isScrolling = false\r\n this.targetScroll = this.animatedScroll = this.actualScroll\r\n\r\n this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false)\r\n\r\n this.virtualScroll = new VirtualScroll(eventsTarget, {\r\n touchMultiplier,\r\n wheelMultiplier,\r\n })\r\n this.virtualScroll.on('scroll', this.onVirtualScroll)\r\n }\r\n\r\n destroy() {\r\n this.emitter.destroy()\r\n\r\n this.options.wrapper.removeEventListener(\r\n 'scroll',\r\n this.onNativeScroll,\r\n false\r\n )\r\n\r\n this.virtualScroll.destroy()\r\n this.dimensions.destroy()\r\n\r\n this.toggleClassName('lenis', false)\r\n this.toggleClassName('lenis-smooth', false)\r\n this.toggleClassName('lenis-scrolling', false)\r\n this.toggleClassName('lenis-stopped', false)\r\n this.toggleClassName('lenis-locked', false)\r\n }\r\n\r\n on(event: string, callback: Function) {\r\n return this.emitter.on(event, callback)\r\n }\r\n\r\n off(event: string, callback: Function) {\r\n return this.emitter.off(event, callback)\r\n }\r\n\r\n private setScroll(scroll) {\r\n // apply scroll value immediately\r\n if (this.isHorizontal) {\r\n this.rootElement.scrollLeft = scroll\r\n } else {\r\n this.rootElement.scrollTop = scroll\r\n }\r\n }\r\n\r\n private onVirtualScroll = ({ deltaX, deltaY, event }) => {\r\n // keep zoom feature\r\n if (event.ctrlKey) return\r\n\r\n const isTouch = event.type.includes('touch')\r\n const isWheel = event.type.includes('wheel')\r\n\r\n const isTapToStop =\r\n this.options.syncTouch && isTouch && event.type === 'touchstart'\r\n\r\n if (isTapToStop) {\r\n this.reset()\r\n return\r\n }\r\n\r\n const isClick = deltaX === 0 && deltaY === 0 // click event\r\n\r\n // const isPullToRefresh =\r\n // this.options.gestureOrientation === 'vertical' &&\r\n // this.scroll === 0 &&\r\n // !this.options.infinite &&\r\n // deltaY <= 5 // touch pull to refresh, not reliable yet\r\n\r\n const isUnknownGesture =\r\n (this.options.gestureOrientation === 'vertical' && deltaY === 0) ||\r\n (this.options.gestureOrientation === 'horizontal' && deltaX === 0)\r\n\r\n if (isClick || isUnknownGesture) {\r\n // console.log('prevent')\r\n return\r\n }\r\n\r\n // catch if scrolling on nested scroll elements\r\n let composedPath = event.composedPath()\r\n composedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement)) // remove parents elements\r\n\r\n if (\r\n !!composedPath.find(\r\n (node) =>\r\n node.hasAttribute?.('data-lenis-prevent') ||\r\n (isTouch && node.hasAttribute?.('data-lenis-prevent-touch')) ||\r\n (isWheel && node.hasAttribute?.('data-lenis-prevent-wheel')) ||\r\n (node.classList?.contains('lenis') &&\r\n !node.classList?.contains('lenis-stopped')) // nested lenis instance\r\n )\r\n )\r\n return\r\n\r\n if (this.isStopped || this.isLocked) {\r\n event.preventDefault() // this will stop forwarding the event to the parent, this is problematic\r\n return\r\n }\r\n\r\n this.isSmooth =\r\n (this.options.syncTouch && isTouch) ||\r\n (this.options.smoothWheel && isWheel)\r\n\r\n if (!this.isSmooth) {\r\n this.isScrolling = false\r\n this.animate.stop()\r\n return\r\n }\r\n\r\n event.preventDefault()\r\n\r\n let delta = deltaY\r\n if (this.options.gestureOrientation === 'both') {\r\n delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX\r\n } else if (this.options.gestureOrientation === 'horizontal') {\r\n delta = deltaX\r\n }\r\n\r\n const syncTouch = isTouch && this.options.syncTouch\r\n const isTouchEnd = isTouch && event.type === 'touchend'\r\n\r\n const hasTouchInertia = isTouchEnd && Math.abs(delta) > 5\r\n\r\n if (hasTouchInertia) {\r\n delta = this.velocity * this.options.touchInertiaMultiplier\r\n }\r\n\r\n this.scrollTo(this.targetScroll + delta, {\r\n programmatic: false,\r\n ...(syncTouch\r\n ? {\r\n lerp: hasTouchInertia ? this.options.syncTouchLerp : 1,\r\n }\r\n : {\r\n lerp: this.options.lerp,\r\n duration: this.options.duration,\r\n easing: this.options.easing,\r\n }),\r\n })\r\n }\r\n\r\n resize() {\r\n this.dimensions.resize()\r\n }\r\n\r\n private emit() {\r\n this.emitter.emit('scroll', this)\r\n }\r\n\r\n private onNativeScroll = () => {\r\n if (this.__preventNextScrollEvent) return\r\n\r\n if (!this.isScrolling) {\r\n const lastScroll = this.animatedScroll\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.velocity = 0\r\n this.direction = Math.sign(this.animatedScroll - lastScroll)\r\n this.emit()\r\n }\r\n }\r\n\r\n private reset() {\r\n this.isLocked = false\r\n this.isScrolling = false\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.velocity = 0\r\n this.animate.stop()\r\n }\r\n\r\n start() {\r\n if (!this.isStopped) return\r\n this.isStopped = false\r\n\r\n this.reset()\r\n }\r\n\r\n stop() {\r\n if (this.isStopped) return\r\n this.isStopped = true\r\n this.animate.stop()\r\n\r\n this.reset()\r\n }\r\n\r\n raf(time: number) {\r\n const deltaTime = time - (this.time || time)\r\n this.time = time\r\n\r\n this.animate.advance(deltaTime * 0.001)\r\n }\r\n\r\n scrollTo(\r\n target: number | string | HTMLElement,\r\n {\r\n offset = 0,\r\n immediate = false,\r\n lock = false,\r\n duration = this.options.duration,\r\n easing = this.options.easing,\r\n lerp = !duration && this.options.lerp,\r\n onComplete,\r\n force = false, // scroll even if stopped\r\n programmatic = true, // called from outside of the class\r\n }: {\r\n offset?: number\r\n immediate?: boolean\r\n lock?: boolean\r\n duration?: number\r\n easing?: EasingFunction\r\n lerp?: number\r\n onComplete?: (lenis: Lenis) => void\r\n force?: boolean\r\n programmatic?: boolean\r\n } = {}\r\n ) {\r\n if ((this.isStopped || this.isLocked) && !force) return\r\n\r\n // keywords\r\n if (['top', 'left', 'start'].includes(target)) {\r\n target = 0\r\n } else if (['bottom', 'right', 'end'].includes(target)) {\r\n target = this.limit\r\n } else {\r\n let node\r\n\r\n if (typeof target === 'string') {\r\n // CSS selector\r\n node = document.querySelector(target)\r\n } else if (target?.nodeType) {\r\n // Node element\r\n node = target\r\n }\r\n\r\n if (node) {\r\n if (this.options.wrapper !== window) {\r\n // nested scroll offset correction\r\n const wrapperRect = this.options.wrapper.getBoundingClientRect()\r\n offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top\r\n }\r\n\r\n const rect = node.getBoundingClientRect()\r\n\r\n target =\r\n (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll\r\n }\r\n }\r\n\r\n if (typeof target !== 'number') return\r\n\r\n target += offset\r\n target = Math.round(target)\r\n\r\n if (this.options.infinite) {\r\n if (programmatic) {\r\n this.targetScroll = this.animatedScroll = this.scroll\r\n }\r\n } else {\r\n target = clamp(0, target, this.limit)\r\n }\r\n\r\n if (immediate) {\r\n this.animatedScroll = this.targetScroll = target\r\n this.setScroll(this.scroll)\r\n this.reset()\r\n onComplete?.(this)\r\n return\r\n }\r\n\r\n if (!programmatic) {\r\n if (target === this.targetScroll) return\r\n\r\n this.targetScroll = target\r\n }\r\n\r\n this.animate.fromTo(this.animatedScroll, target, {\r\n duration,\r\n easing,\r\n lerp,\r\n onStart: () => {\r\n // started\r\n if (lock) this.isLocked = true\r\n this.isScrolling = true\r\n },\r\n onUpdate: (value: number, completed: boolean) => {\r\n this.isScrolling = true\r\n\r\n // updated\r\n this.velocity = value - this.animatedScroll\r\n this.direction = Math.sign(this.velocity)\r\n\r\n this.animatedScroll = value\r\n this.setScroll(this.scroll)\r\n\r\n if (programmatic) {\r\n // wheel during programmatic should stop it\r\n this.targetScroll = value\r\n }\r\n\r\n if (!completed) this.emit()\r\n\r\n if (completed) {\r\n this.reset()\r\n this.emit()\r\n onComplete?.(this)\r\n\r\n // avoid emitting event twice\r\n this.__preventNextScrollEvent = true\r\n requestAnimationFrame(() => {\r\n delete this.__preventNextScrollEvent\r\n })\r\n }\r\n },\r\n })\r\n }\r\n\r\n get rootElement() {\r\n return this.options.wrapper === window\r\n ? document.documentElement\r\n : this.options.wrapper\r\n }\r\n\r\n get limit() {\r\n if (this.options.__experimental__naiveDimensions) {\r\n if (this.isHorizontal) {\r\n return this.rootElement.scrollWidth - this.rootElement.clientWidth\r\n } else {\r\n return this.rootElement.scrollHeight - this.rootElement.clientHeight\r\n }\r\n } else {\r\n return this.dimensions.limit[this.isHorizontal ? 'x' : 'y']\r\n }\r\n }\r\n\r\n get isHorizontal() {\r\n return this.options.orientation === 'horizontal'\r\n }\r\n\r\n get actualScroll() {\r\n // value browser takes into account\r\n return this.isHorizontal\r\n ? this.rootElement.scrollLeft\r\n : this.rootElement.scrollTop\r\n }\r\n\r\n get scroll() {\r\n return this.options.infinite\r\n ? modulo(this.animatedScroll, this.limit)\r\n : this.animatedScroll\r\n }\r\n\r\n get progress() {\r\n // avoid progress to be NaN\r\n return this.limit === 0 ? 1 : this.scroll / this.limit\r\n }\r\n\r\n get isSmooth() {\r\n return this.__isSmooth\r\n }\r\n\r\n private set isSmooth(value: boolean) {\r\n if (this.__isSmooth !== value) {\r\n this.__isSmooth = value\r\n this.toggleClassName('lenis-smooth', value)\r\n }\r\n }\r\n\r\n get isScrolling() {\r\n return this.__isScrolling\r\n }\r\n\r\n private set isScrolling(value: boolean) {\r\n if (this.__isScrolling !== value) {\r\n this.__isScrolling = value\r\n this.toggleClassName('lenis-scrolling', value)\r\n }\r\n }\r\n\r\n get isStopped() {\r\n return this.__isStopped\r\n }\r\n\r\n private set isStopped(value: boolean) {\r\n if (this.__isStopped !== value) {\r\n this.__isStopped = value\r\n this.toggleClassName('lenis-stopped', value)\r\n }\r\n }\r\n\r\n get isLocked() {\r\n return this.__isLocked\r\n }\r\n\r\n private set isLocked(value: boolean) {\r\n if (this.__isLocked !== value) {\r\n this.__isLocked = value\r\n this.toggleClassName('lenis-locked', value)\r\n }\r\n }\r\n\r\n get className() {\r\n let className = 'lenis'\r\n if (this.isStopped) className += ' lenis-stopped'\r\n if (this.isLocked) className += ' lenis-locked'\r\n if (this.isScrolling) className += ' lenis-scrolling'\r\n if (this.isSmooth) className += ' lenis-smooth'\r\n return className\r\n }\r\n\r\n private toggleClassName(name: string, value: boolean) {\r\n this.rootElement.classList.toggle(name, value)\r\n this.emitter.emit('className change', this)\r\n }\r\n}\r\n"],"names":["clamp","min","input","max","Math","Animate","advance","deltaTime","this","isRunning","completed","lerp","value","x","y","to","lambda","dt","t","exp","round","currentTime","linearProgress","duration","easedProgress","easing","from","onUpdate","stop","fromTo","onStart","Dimensions","constructor","wrapper","content","autoResize","debounce","debounceValue","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","resize","window","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","removeEventListener","onWrapperResize","onContentResize","width","innerWidth","height","innerHeight","clientWidth","clientHeight","scrollHeight","scrollWidth","limit","Emitter","events","emit","event","callbacks","i","length","on","cb","push","filter","off","LINE_HEIGHT","VirtualScroll","element","wheelMultiplier","touchMultiplier","touchStart","emitter","onWindowResize","onWheel","passive","onTouchStart","onTouchMove","onTouchEnd","clientX","clientY","targetTouches","lastDelta","deltaX","deltaY","deltaMode","windowWidth","windowHeight","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","__experimental__naiveDimensions","__isSmooth","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","options","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","isStopped","isLocked","preventDefault","isSmooth","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__preventNextScrollEvent","lastScroll","animatedScroll","actualScroll","direction","sign","lenisVersion","body","dimensions","toggleClassName","virtualScroll","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","time","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","requestAnimationFrame","n","d","progress","className","name","toggle"],"mappings":"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"} \ No newline at end of file diff --git a/packages/lenis/dist/lenis.umd.js b/packages/lenis/dist/lenis.umd.js index 00a2a7d8..e7e789d7 100644 --- a/packages/lenis/dist/lenis.umd.js +++ b/packages/lenis/dist/lenis.umd.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Lenis=e()}(this,(function(){"use strict";function t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,l=e,function(t,e,i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*l))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,l;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:l}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=2,normalizeWheel:s=!1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.normalizeWheel=s,this.touchStart={x:null,y:null},this.emitter=new Emitter,this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),this.element.removeEventListener("wheel",this.onWheel,{passive:!1}),this.element.removeEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.removeEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.removeEventListener("touchend",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit("scroll",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=e=>{let{deltaX:i,deltaY:s}=e;this.normalizeWheel&&(i=t(-100,i,100),s=t(-100,s,100)),i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:e})}}return class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:p=!1,orientation:u="vertical",gestureOrientation:d="vertical",touchMultiplier:m=1,wheelMultiplier:g=1,normalizeWheel:v=!1,autoResize:S=!0,__experimental__naiveDimensions:w=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes("touch"),o=i.type.includes("wheel");if(this.options.syncTouch&&s&&"touchstart"===i.type)return void this.reset();const n=0===t&&0===e,l="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===t;if(n||l)return;let r=i.composedPath();if(r=r.slice(0,r.indexOf(this.rootElement)),r.find((t=>{var e,i,n,l,r;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent-touch"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;"both"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:"horizontal"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&"touchend"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion="1.0.40",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:p,gestureOrientation:d,orientation:u,touchMultiplier:m,wheelMultiplier:g,normalizeWheel:v,autoResize:S,__experimental__naiveDimensions:w},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:S}),this.toggleClassName("lenis",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:g,normalizeWheel:v}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName("lenis",!1),this.toggleClassName("lenis-smooth",!1),this.toggleClassName("lenis-scrolling",!1),this.toggleClassName("lenis-stopped",!1),this.toggleClassName("lenis-locked",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:l=this.options.easing,lerp:r=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(e))e=0;else if(["bottom","right","end"].includes(e))e=this.limit;else{let t;if("string"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:l,lerp:r,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName("lenis-smooth",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName("lenis-scrolling",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName("lenis-stopped",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName("lenis-locked",t))}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),this.isSmooth&&(t+=" lenis-smooth"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit("className change",this)}}})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Lenis=e()}(this,(function(){"use strict";function t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,l=e,function(t,e,i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*l))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,l;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:l}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener("resize",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}const e=100/6;class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.touchStart={x:null,y:null},this.emitter=new Emitter,window.addEventListener("resize",this.onWindowResize,!1),this.onWindowResize(),this.element.addEventListener("wheel",this.onWheel,{passive:!1}),this.element.addEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.addEventListener("touchend",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel,{passive:!1}),this.element.removeEventListener("touchstart",this.onTouchStart,{passive:!1}),this.element.removeEventListener("touchmove",this.onTouchMove,{passive:!1}),this.element.removeEventListener("touchend",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit("scroll",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=t=>{let{deltaX:i,deltaY:s,deltaMode:o}=t;i*=1===o?e:2===o?this.windowWidth:1,s*=1===o?e:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:t})};onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight}}return class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:d=!1,orientation:p="vertical",gestureOrientation:u="vertical",touchMultiplier:m=1,wheelMultiplier:g=1,autoResize:v=!0,__experimental__naiveDimensions:S=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes("touch"),o=i.type.includes("wheel");if(this.options.syncTouch&&s&&"touchstart"===i.type)return void this.reset();const n=0===t&&0===e,l="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===t;if(n||l)return;let r=i.composedPath();if(r=r.slice(0,r.indexOf(this.rootElement)),r.find((t=>{var e,i,n,l,r;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent-touch"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;"both"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:"horizontal"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&"touchend"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion="1.0.40",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:u,orientation:p,touchMultiplier:m,wheelMultiplier:g,autoResize:v,__experimental__naiveDimensions:S},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:v}),this.toggleClassName("lenis",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:g}),this.virtualScroll.on("scroll",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener("scroll",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName("lenis",!1),this.toggleClassName("lenis-smooth",!1),this.toggleClassName("lenis-scrolling",!1),this.toggleClassName("lenis-stopped",!1),this.toggleClassName("lenis-locked",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:l=this.options.easing,lerp:r=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(e))e=0;else if(["bottom","right","end"].includes(e))e=this.limit;else{let t;if("string"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:l,lerp:r,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?"x":"y"]}get isHorizontal(){return"horizontal"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName("lenis-smooth",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName("lenis-scrolling",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName("lenis-stopped",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName("lenis-locked",t))}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),this.isSmooth&&(t+=" lenis-smooth"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit("className change",this)}}})); //# sourceMappingURL=lenis.umd.js.map diff --git a/packages/lenis/dist/lenis.umd.js.map b/packages/lenis/dist/lenis.umd.js.map index 70bf0de2..a6444dfb 100644 --- a/packages/lenis/dist/lenis.umd.js.map +++ b/packages/lenis/dist/lenis.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"lenis.umd.js","sources":["../src/maths.js","../src/animate.js","../src/dimensions.js","../src/debounce.js","../src/emitter.js","../src/virtual-scroll.js","../../src/index.ts"],"sourcesContent":["// Clamp a value between a minimum and maximum value\nexport function clamp(min, input, max) {\n return Math.max(min, Math.min(input, max))\n}\n\n// Truncate a floating-point number to a specified number of decimal places\nexport function truncate(value, decimals = 0) {\n return parseFloat(value.toFixed(decimals))\n}\n\n// Linearly interpolate between two values using an amount (0 <= t <= 1)\nexport function lerp(x, y, t) {\n return (1 - t) * x + t * y\n}\n\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\nexport function damp(x, y, lambda, dt) {\n return lerp(x, y, 1 - Math.exp(-lambda * dt))\n}\n\n// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor\n// https://anguscroll.com/just/just-modulo\nexport function modulo(n, d) {\n return ((n % d) + d) % d\n}\n","import { clamp, damp } from './maths'\n\n// Animate class to handle value animations with lerping or easing\nexport class Animate {\n // Advance the animation by the given delta time\n advance(deltaTime) {\n if (!this.isRunning) return\n\n let completed = false\n\n if (this.lerp) {\n this.value = damp(this.value, this.to, this.lerp * 60, deltaTime)\n if (Math.round(this.value) === this.to) {\n this.value = this.to\n completed = true\n }\n } else {\n this.currentTime += deltaTime\n const linearProgress = clamp(0, this.currentTime / this.duration, 1)\n\n completed = linearProgress >= 1\n const easedProgress = completed ? 1 : this.easing(linearProgress)\n this.value = this.from + (this.to - this.from) * easedProgress\n }\n\n // Call the onUpdate callback with the current value and completed status\n this.onUpdate?.(this.value, completed)\n\n if (completed) {\n this.stop()\n }\n }\n\n // Stop the animation\n stop() {\n this.isRunning = false\n }\n\n // Set up the animation from a starting value to an ending value\n // with optional parameters for lerping, duration, easing, and onUpdate callback\n fromTo(\n from,\n to,\n { lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }\n ) {\n this.from = this.value = from\n this.to = to\n this.lerp = lerp\n this.duration = duration\n this.easing = easing\n this.currentTime = 0\n this.isRunning = true\n\n onStart?.()\n this.onUpdate = onUpdate\n }\n}\n","import { debounce } from './debounce'\n\nexport class Dimensions {\n constructor({\n wrapper,\n content,\n autoResize = true,\n debounce: debounceValue = 250,\n } = {}) {\n this.wrapper = wrapper\n this.content = content\n\n if (autoResize) {\n this.debouncedResize = debounce(this.resize, debounceValue)\n\n if (this.wrapper === window) {\n window.addEventListener('resize', this.debouncedResize, false)\n } else {\n this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize)\n this.wrapperResizeObserver.observe(this.wrapper)\n }\n\n this.contentResizeObserver = new ResizeObserver(this.debouncedResize)\n this.contentResizeObserver.observe(this.content)\n }\n\n this.resize()\n }\n\n destroy() {\n this.wrapperResizeObserver?.disconnect()\n this.contentResizeObserver?.disconnect()\n window.removeEventListener('resize', this.debouncedResize, false)\n }\n\n resize = () => {\n this.onWrapperResize()\n this.onContentResize()\n }\n\n onWrapperResize = () => {\n if (this.wrapper === window) {\n this.width = window.innerWidth\n this.height = window.innerHeight\n } else {\n this.width = this.wrapper.clientWidth\n this.height = this.wrapper.clientHeight\n }\n }\n\n onContentResize = () => {\n if (this.wrapper === window) {\n this.scrollHeight = this.content.scrollHeight\n this.scrollWidth = this.content.scrollWidth\n } else {\n this.scrollHeight = this.wrapper.scrollHeight\n this.scrollWidth = this.wrapper.scrollWidth\n }\n }\n\n get limit() {\n return {\n x: this.scrollWidth - this.width,\n y: this.scrollHeight - this.height,\n }\n }\n}\n","export function debounce(callback, delay) {\n let timer\n return function () {\n let args = arguments\n let context = this\n clearTimeout(timer)\n timer = setTimeout(function () {\n callback.apply(context, args)\n }, delay)\n }\n}\n","export class Emitter {\n constructor() {\n this.events = {}\n }\n\n emit(event, ...args) {\n let callbacks = this.events[event] || []\n for (let i = 0, length = callbacks.length; i < length; i++) {\n callbacks[i](...args)\n }\n }\n\n on(event, cb) {\n // Add the callback to the event's callback list, or create a new list with the callback\n this.events[event]?.push(cb) || (this.events[event] = [cb])\n\n // Return an unsubscribe function\n return () => {\n this.events[event] = this.events[event]?.filter((i) => cb !== i)\n }\n }\n\n off(event, callback) {\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\n }\n\n destroy() {\n this.events = {}\n }\n}\n","import { Emitter } from './emitter'\nimport { clamp } from './maths'\n\nexport class VirtualScroll {\n constructor(\n element,\n { wheelMultiplier = 1, touchMultiplier = 2, normalizeWheel = false }\n ) {\n this.element = element\n this.wheelMultiplier = wheelMultiplier\n this.touchMultiplier = touchMultiplier\n this.normalizeWheel = normalizeWheel\n\n this.touchStart = {\n x: null,\n y: null,\n }\n\n this.emitter = new Emitter()\n\n this.element.addEventListener('wheel', this.onWheel, { passive: false })\n this.element.addEventListener('touchstart', this.onTouchStart, {\n passive: false,\n })\n this.element.addEventListener('touchmove', this.onTouchMove, {\n passive: false,\n })\n this.element.addEventListener('touchend', this.onTouchEnd, {\n passive: false,\n })\n }\n\n // Add an event listener for the given event and callback\n on(event, callback) {\n return this.emitter.on(event, callback)\n }\n\n // Remove all event listeners and clean up\n destroy() {\n this.emitter.destroy()\n\n this.element.removeEventListener('wheel', this.onWheel, {\n passive: false,\n })\n this.element.removeEventListener('touchstart', this.onTouchStart, {\n passive: false,\n })\n this.element.removeEventListener('touchmove', this.onTouchMove, {\n passive: false,\n })\n this.element.removeEventListener('touchend', this.onTouchEnd, {\n passive: false,\n })\n }\n\n // Event handler for 'touchstart' event\n onTouchStart = (event) => {\n const { clientX, clientY } = event.targetTouches\n ? event.targetTouches[0]\n : event\n\n this.touchStart.x = clientX\n this.touchStart.y = clientY\n\n this.lastDelta = {\n x: 0,\n y: 0,\n }\n\n this.emitter.emit('scroll', {\n deltaX: 0,\n deltaY: 0,\n event,\n })\n }\n\n // Event handler for 'touchmove' event\n onTouchMove = (event) => {\n const { clientX, clientY } = event.targetTouches\n ? event.targetTouches[0]\n : event\n\n const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier\n const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier\n\n this.touchStart.x = clientX\n this.touchStart.y = clientY\n\n this.lastDelta = {\n x: deltaX,\n y: deltaY,\n }\n\n this.emitter.emit('scroll', {\n deltaX,\n deltaY,\n event,\n })\n }\n\n onTouchEnd = (event) => {\n this.emitter.emit('scroll', {\n deltaX: this.lastDelta.x,\n deltaY: this.lastDelta.y,\n event,\n })\n }\n\n // Event handler for 'wheel' event\n onWheel = (event) => {\n let { deltaX, deltaY } = event\n\n if (this.normalizeWheel) {\n deltaX = clamp(-100, deltaX, 100)\n deltaY = clamp(-100, deltaY, 100)\n }\n\n deltaX *= this.wheelMultiplier\n deltaY *= this.wheelMultiplier\n\n this.emitter.emit('scroll', { deltaX, deltaY, event })\n }\n}\n","import { version } from '../package.json'\nimport { Animate } from './animate'\nimport { Dimensions } from './dimensions'\nimport { Emitter } from './emitter'\nimport { clamp, modulo } from './maths'\nimport { VirtualScroll } from './virtual-scroll'\n\n// Technical explanation\n// - listen to 'wheel' events\n// - prevent 'wheel' event to prevent scroll\n// - normalize wheel delta\n// - add delta to targetScroll\n// - animate scroll to targetScroll (smooth context)\n// - if animation is not running, listen to 'scroll' events (native context)\n\ntype EasingFunction = (t: number) => number\ntype Orientation = 'vertical' | 'horizontal'\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\n\nexport type LenisOptions = {\n wrapper?: Window | HTMLElement\n content?: HTMLElement\n wheelEventsTarget?: Window | HTMLElement\n eventsTarget?: Window | HTMLElement\n smoothWheel?: boolean\n syncTouch?: boolean\n syncTouchLerp?: number\n touchInertiaMultiplier?: number\n duration?: number\n easing?: EasingFunction\n lerp?: number\n infinite?: boolean\n orientation?: Orientation\n gestureOrientation?: GestureOrientation\n touchMultiplier?: number\n wheelMultiplier?: number\n normalizeWheel?: boolean\n autoResize?: boolean\n __experimental__naiveDimensions?: boolean\n}\n\nexport default class Lenis {\n __isSmooth: boolean = false // true if scroll should be animated\n __isScrolling: boolean = false // true when scroll is animating\n __isStopped: boolean = false // true if user should not be able to scroll - enable/disable programmatically\n __isLocked: boolean = false // same as isStopped but enabled/disabled when scroll reaches target\n\n constructor({\n wrapper = window,\n content = document.documentElement,\n wheelEventsTarget = wrapper, // deprecated\n eventsTarget = wheelEventsTarget,\n smoothWheel = true,\n syncTouch = false,\n syncTouchLerp = 0.075,\n touchInertiaMultiplier = 35,\n duration, // in seconds\n easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),\n lerp = !duration && 0.1,\n infinite = false,\n orientation = 'vertical', // vertical, horizontal\n gestureOrientation = 'vertical', // vertical, horizontal, both\n touchMultiplier = 1,\n wheelMultiplier = 1,\n normalizeWheel = false, // deprecated\n autoResize = true,\n __experimental__naiveDimensions = false,\n }: LenisOptions = {}) {\n window.lenisVersion = version\n\n // if wrapper is html or body, fallback to window\n if (wrapper === document.documentElement || wrapper === document.body) {\n wrapper = window\n }\n\n this.options = {\n wrapper,\n content,\n wheelEventsTarget,\n eventsTarget,\n smoothWheel,\n syncTouch,\n syncTouchLerp,\n touchInertiaMultiplier,\n duration,\n easing,\n lerp,\n infinite,\n gestureOrientation,\n orientation,\n touchMultiplier,\n wheelMultiplier,\n normalizeWheel,\n autoResize,\n __experimental__naiveDimensions,\n }\n\n this.animate = new Animate()\n this.emitter = new Emitter()\n this.dimensions = new Dimensions({ wrapper, content, autoResize })\n this.toggleClassName('lenis', true)\n\n this.velocity = 0\n this.isLocked = false\n this.isStopped = false\n this.isSmooth = syncTouch || smoothWheel\n this.isScrolling = false\n this.targetScroll = this.animatedScroll = this.actualScroll\n\n this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false)\n\n this.virtualScroll = new VirtualScroll(eventsTarget, {\n touchMultiplier,\n wheelMultiplier,\n normalizeWheel,\n })\n this.virtualScroll.on('scroll', this.onVirtualScroll)\n }\n\n destroy() {\n this.emitter.destroy()\n\n this.options.wrapper.removeEventListener(\n 'scroll',\n this.onNativeScroll,\n false\n )\n\n this.virtualScroll.destroy()\n this.dimensions.destroy()\n\n this.toggleClassName('lenis', false)\n this.toggleClassName('lenis-smooth', false)\n this.toggleClassName('lenis-scrolling', false)\n this.toggleClassName('lenis-stopped', false)\n this.toggleClassName('lenis-locked', false)\n }\n\n on(event: string, callback: Function) {\n return this.emitter.on(event, callback)\n }\n\n off(event: string, callback: Function) {\n return this.emitter.off(event, callback)\n }\n\n private setScroll(scroll) {\n // apply scroll value immediately\n if (this.isHorizontal) {\n this.rootElement.scrollLeft = scroll\n } else {\n this.rootElement.scrollTop = scroll\n }\n }\n\n private onVirtualScroll = ({ deltaX, deltaY, event }) => {\n // keep zoom feature\n if (event.ctrlKey) return\n\n const isTouch = event.type.includes('touch')\n const isWheel = event.type.includes('wheel')\n\n const isTapToStop =\n this.options.syncTouch && isTouch && event.type === 'touchstart'\n\n if (isTapToStop) {\n this.reset()\n return\n }\n\n const isClick = deltaX === 0 && deltaY === 0 // click event\n\n // const isPullToRefresh =\n // this.options.gestureOrientation === 'vertical' &&\n // this.scroll === 0 &&\n // !this.options.infinite &&\n // deltaY <= 5 // touch pull to refresh, not reliable yet\n\n const isUnknownGesture =\n (this.options.gestureOrientation === 'vertical' && deltaY === 0) ||\n (this.options.gestureOrientation === 'horizontal' && deltaX === 0)\n\n if (isClick || isUnknownGesture) {\n // console.log('prevent')\n return\n }\n\n // catch if scrolling on nested scroll elements\n let composedPath = event.composedPath()\n composedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement)) // remove parents elements\n\n if (\n !!composedPath.find(\n (node) =>\n node.hasAttribute?.('data-lenis-prevent') ||\n (isTouch && node.hasAttribute?.('data-lenis-prevent-touch')) ||\n (isWheel && node.hasAttribute?.('data-lenis-prevent-wheel')) ||\n (node.classList?.contains('lenis') &&\n !node.classList?.contains('lenis-stopped')) // nested lenis instance\n )\n )\n return\n\n if (this.isStopped || this.isLocked) {\n event.preventDefault() // this will stop forwarding the event to the parent, this is problematic\n return\n }\n\n this.isSmooth =\n (this.options.syncTouch && isTouch) ||\n (this.options.smoothWheel && isWheel)\n\n if (!this.isSmooth) {\n this.isScrolling = false\n this.animate.stop()\n return\n }\n\n event.preventDefault()\n\n let delta = deltaY\n if (this.options.gestureOrientation === 'both') {\n delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX\n } else if (this.options.gestureOrientation === 'horizontal') {\n delta = deltaX\n }\n\n const syncTouch = isTouch && this.options.syncTouch\n const isTouchEnd = isTouch && event.type === 'touchend'\n\n const hasTouchInertia = isTouchEnd && Math.abs(delta) > 5\n\n if (hasTouchInertia) {\n delta = this.velocity * this.options.touchInertiaMultiplier\n }\n\n this.scrollTo(this.targetScroll + delta, {\n programmatic: false,\n ...(syncTouch\n ? {\n lerp: hasTouchInertia ? this.options.syncTouchLerp : 1,\n }\n : {\n lerp: this.options.lerp,\n duration: this.options.duration,\n easing: this.options.easing,\n }),\n })\n }\n\n resize() {\n this.dimensions.resize()\n }\n\n private emit() {\n this.emitter.emit('scroll', this)\n }\n\n private onNativeScroll = () => {\n if (this.__preventNextScrollEvent) return\n\n if (!this.isScrolling) {\n const lastScroll = this.animatedScroll\n this.animatedScroll = this.targetScroll = this.actualScroll\n this.velocity = 0\n this.direction = Math.sign(this.animatedScroll - lastScroll)\n this.emit()\n }\n }\n\n private reset() {\n this.isLocked = false\n this.isScrolling = false\n this.animatedScroll = this.targetScroll = this.actualScroll\n this.velocity = 0\n this.animate.stop()\n }\n\n start() {\n if (!this.isStopped) return\n this.isStopped = false\n\n this.reset()\n }\n\n stop() {\n if (this.isStopped) return\n this.isStopped = true\n this.animate.stop()\n\n this.reset()\n }\n\n raf(time: number) {\n const deltaTime = time - (this.time || time)\n this.time = time\n\n this.animate.advance(deltaTime * 0.001)\n }\n\n scrollTo(\n target: number | string | HTMLElement,\n {\n offset = 0,\n immediate = false,\n lock = false,\n duration = this.options.duration,\n easing = this.options.easing,\n lerp = !duration && this.options.lerp,\n onComplete,\n force = false, // scroll even if stopped\n programmatic = true, // called from outside of the class\n }: {\n offset?: number\n immediate?: boolean\n lock?: boolean\n duration?: number\n easing?: EasingFunction\n lerp?: number\n onComplete?: (lenis: Lenis) => void\n force?: boolean\n programmatic?: boolean\n } = {}\n ) {\n if ((this.isStopped || this.isLocked) && !force) return\n\n // keywords\n if (['top', 'left', 'start'].includes(target)) {\n target = 0\n } else if (['bottom', 'right', 'end'].includes(target)) {\n target = this.limit\n } else {\n let node\n\n if (typeof target === 'string') {\n // CSS selector\n node = document.querySelector(target)\n } else if (target?.nodeType) {\n // Node element\n node = target\n }\n\n if (node) {\n if (this.options.wrapper !== window) {\n // nested scroll offset correction\n const wrapperRect = this.options.wrapper.getBoundingClientRect()\n offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top\n }\n\n const rect = node.getBoundingClientRect()\n\n target =\n (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll\n }\n }\n\n if (typeof target !== 'number') return\n\n target += offset\n target = Math.round(target)\n\n if (this.options.infinite) {\n if (programmatic) {\n this.targetScroll = this.animatedScroll = this.scroll\n }\n } else {\n target = clamp(0, target, this.limit)\n }\n\n if (immediate) {\n this.animatedScroll = this.targetScroll = target\n this.setScroll(this.scroll)\n this.reset()\n onComplete?.(this)\n return\n }\n\n if (!programmatic) {\n if (target === this.targetScroll) return\n\n this.targetScroll = target\n }\n\n this.animate.fromTo(this.animatedScroll, target, {\n duration,\n easing,\n lerp,\n onStart: () => {\n // started\n if (lock) this.isLocked = true\n this.isScrolling = true\n },\n onUpdate: (value: number, completed: boolean) => {\n this.isScrolling = true\n\n // updated\n this.velocity = value - this.animatedScroll\n this.direction = Math.sign(this.velocity)\n\n this.animatedScroll = value\n this.setScroll(this.scroll)\n\n if (programmatic) {\n // wheel during programmatic should stop it\n this.targetScroll = value\n }\n\n if (!completed) this.emit()\n\n if (completed) {\n this.reset()\n this.emit()\n onComplete?.(this)\n\n // avoid emitting event twice\n this.__preventNextScrollEvent = true\n requestAnimationFrame(() => {\n delete this.__preventNextScrollEvent\n })\n }\n },\n })\n }\n\n get rootElement() {\n return this.options.wrapper === window\n ? document.documentElement\n : this.options.wrapper\n }\n\n get limit() {\n if (this.options.__experimental__naiveDimensions) {\n if (this.isHorizontal) {\n return this.rootElement.scrollWidth - this.rootElement.clientWidth\n } else {\n return this.rootElement.scrollHeight - this.rootElement.clientHeight\n }\n } else {\n return this.dimensions.limit[this.isHorizontal ? 'x' : 'y']\n }\n }\n\n get isHorizontal() {\n return this.options.orientation === 'horizontal'\n }\n\n get actualScroll() {\n // value browser takes into account\n return this.isHorizontal\n ? this.rootElement.scrollLeft\n : this.rootElement.scrollTop\n }\n\n get scroll() {\n return this.options.infinite\n ? modulo(this.animatedScroll, this.limit)\n : this.animatedScroll\n }\n\n get progress() {\n // avoid progress to be NaN\n return this.limit === 0 ? 1 : this.scroll / this.limit\n }\n\n get isSmooth() {\n return this.__isSmooth\n }\n\n private set isSmooth(value: boolean) {\n if (this.__isSmooth !== value) {\n this.__isSmooth = value\n this.toggleClassName('lenis-smooth', value)\n }\n }\n\n get isScrolling() {\n return this.__isScrolling\n }\n\n private set isScrolling(value: boolean) {\n if (this.__isScrolling !== value) {\n this.__isScrolling = value\n this.toggleClassName('lenis-scrolling', value)\n }\n }\n\n get isStopped() {\n return this.__isStopped\n }\n\n private set isStopped(value: boolean) {\n if (this.__isStopped !== value) {\n this.__isStopped = value\n this.toggleClassName('lenis-stopped', value)\n }\n }\n\n get isLocked() {\n return this.__isLocked\n }\n\n private set isLocked(value: boolean) {\n if (this.__isLocked !== value) {\n this.__isLocked = value\n this.toggleClassName('lenis-locked', value)\n }\n }\n\n get className() {\n let className = 'lenis'\n if (this.isStopped) className += ' lenis-stopped'\n if (this.isLocked) className += ' lenis-locked'\n if (this.isScrolling) className += ' lenis-scrolling'\n if (this.isSmooth) className += ' lenis-smooth'\n return className\n }\n\n private toggleClassName(name: string, value: boolean) {\n this.rootElement.classList.toggle(name, value)\n this.emitter.emit('className change', this)\n }\n}\n"],"names":["clamp","min","input","max","Math","Animate","advance","deltaTime","this","isRunning","completed","lerp","value","x","y","to","lambda","dt","t","exp","round","currentTime","linearProgress","duration","easedProgress","easing","from","onUpdate","stop","fromTo","onStart","Dimensions","constructor","wrapper","content","autoResize","debounce","debounceValue","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","resize","window","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","removeEventListener","onWrapperResize","onContentResize","width","innerWidth","height","innerHeight","clientWidth","clientHeight","scrollHeight","scrollWidth","limit","Emitter","events","emit","event","callbacks","i","length","on","cb","push","filter","off","VirtualScroll","element","wheelMultiplier","touchMultiplier","normalizeWheel","touchStart","emitter","onWheel","passive","onTouchStart","onTouchMove","onTouchEnd","clientX","clientY","targetTouches","lastDelta","deltaX","deltaY","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","__experimental__naiveDimensions","__isSmooth","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","options","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","isStopped","isLocked","preventDefault","isSmooth","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__preventNextScrollEvent","lastScroll","animatedScroll","actualScroll","direction","sign","lenisVersion","body","dimensions","toggleClassName","virtualScroll","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","time","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","requestAnimationFrame","n","d","progress","className","name","toggle"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"lenis.umd.js","sources":["../src/maths.js","../src/animate.js","../src/dimensions.js","../src/debounce.js","../src/emitter.js","../src/virtual-scroll.js","../../src/index.ts"],"sourcesContent":["// Clamp a value between a minimum and maximum value\r\nexport function clamp(min, input, max) {\r\n return Math.max(min, Math.min(input, max))\r\n}\r\n\r\n// Truncate a floating-point number to a specified number of decimal places\r\nexport function truncate(value, decimals = 0) {\r\n return parseFloat(value.toFixed(decimals))\r\n}\r\n\r\n// Linearly interpolate between two values using an amount (0 <= t <= 1)\r\nexport function lerp(x, y, t) {\r\n return (1 - t) * x + t * y\r\n}\r\n\r\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\r\nexport function damp(x, y, lambda, dt) {\r\n return lerp(x, y, 1 - Math.exp(-lambda * dt))\r\n}\r\n\r\n// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor\r\n// https://anguscroll.com/just/just-modulo\r\nexport function modulo(n, d) {\r\n return ((n % d) + d) % d\r\n}\r\n","import { clamp, damp } from './maths'\r\n\r\n// Animate class to handle value animations with lerping or easing\r\nexport class Animate {\r\n // Advance the animation by the given delta time\r\n advance(deltaTime) {\r\n if (!this.isRunning) return\r\n\r\n let completed = false\r\n\r\n if (this.lerp) {\r\n this.value = damp(this.value, this.to, this.lerp * 60, deltaTime)\r\n if (Math.round(this.value) === this.to) {\r\n this.value = this.to\r\n completed = true\r\n }\r\n } else {\r\n this.currentTime += deltaTime\r\n const linearProgress = clamp(0, this.currentTime / this.duration, 1)\r\n\r\n completed = linearProgress >= 1\r\n const easedProgress = completed ? 1 : this.easing(linearProgress)\r\n this.value = this.from + (this.to - this.from) * easedProgress\r\n }\r\n\r\n // Call the onUpdate callback with the current value and completed status\r\n this.onUpdate?.(this.value, completed)\r\n\r\n if (completed) {\r\n this.stop()\r\n }\r\n }\r\n\r\n // Stop the animation\r\n stop() {\r\n this.isRunning = false\r\n }\r\n\r\n // Set up the animation from a starting value to an ending value\r\n // with optional parameters for lerping, duration, easing, and onUpdate callback\r\n fromTo(\r\n from,\r\n to,\r\n { lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }\r\n ) {\r\n this.from = this.value = from\r\n this.to = to\r\n this.lerp = lerp\r\n this.duration = duration\r\n this.easing = easing\r\n this.currentTime = 0\r\n this.isRunning = true\r\n\r\n onStart?.()\r\n this.onUpdate = onUpdate\r\n }\r\n}\r\n","import { debounce } from './debounce'\r\n\r\nexport class Dimensions {\r\n constructor({\r\n wrapper,\r\n content,\r\n autoResize = true,\r\n debounce: debounceValue = 250,\r\n } = {}) {\r\n this.wrapper = wrapper\r\n this.content = content\r\n\r\n if (autoResize) {\r\n this.debouncedResize = debounce(this.resize, debounceValue)\r\n\r\n if (this.wrapper === window) {\r\n window.addEventListener('resize', this.debouncedResize, false)\r\n } else {\r\n this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize)\r\n this.wrapperResizeObserver.observe(this.wrapper)\r\n }\r\n\r\n this.contentResizeObserver = new ResizeObserver(this.debouncedResize)\r\n this.contentResizeObserver.observe(this.content)\r\n }\r\n\r\n this.resize()\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver?.disconnect()\r\n this.contentResizeObserver?.disconnect()\r\n window.removeEventListener('resize', this.debouncedResize, false)\r\n }\r\n\r\n resize = () => {\r\n this.onWrapperResize()\r\n this.onContentResize()\r\n }\r\n\r\n onWrapperResize = () => {\r\n if (this.wrapper === window) {\r\n this.width = window.innerWidth\r\n this.height = window.innerHeight\r\n } else {\r\n this.width = this.wrapper.clientWidth\r\n this.height = this.wrapper.clientHeight\r\n }\r\n }\r\n\r\n onContentResize = () => {\r\n if (this.wrapper === window) {\r\n this.scrollHeight = this.content.scrollHeight\r\n this.scrollWidth = this.content.scrollWidth\r\n } else {\r\n this.scrollHeight = this.wrapper.scrollHeight\r\n this.scrollWidth = this.wrapper.scrollWidth\r\n }\r\n }\r\n\r\n get limit() {\r\n return {\r\n x: this.scrollWidth - this.width,\r\n y: this.scrollHeight - this.height,\r\n }\r\n }\r\n}\r\n","export function debounce(callback, delay) {\r\n let timer\r\n return function () {\r\n let args = arguments\r\n let context = this\r\n clearTimeout(timer)\r\n timer = setTimeout(function () {\r\n callback.apply(context, args)\r\n }, delay)\r\n }\r\n}\r\n","export class Emitter {\r\n constructor() {\r\n this.events = {}\r\n }\r\n\r\n emit(event, ...args) {\r\n let callbacks = this.events[event] || []\r\n for (let i = 0, length = callbacks.length; i < length; i++) {\r\n callbacks[i](...args)\r\n }\r\n }\r\n\r\n on(event, cb) {\r\n // Add the callback to the event's callback list, or create a new list with the callback\r\n this.events[event]?.push(cb) || (this.events[event] = [cb])\r\n\r\n // Return an unsubscribe function\r\n return () => {\r\n this.events[event] = this.events[event]?.filter((i) => cb !== i)\r\n }\r\n }\r\n\r\n off(event, callback) {\r\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\r\n }\r\n\r\n destroy() {\r\n this.events = {}\r\n }\r\n}\r\n","import { Emitter } from './emitter'\r\n\r\nconst LINE_HEIGHT = 100 / 6\r\n\r\nexport class VirtualScroll {\r\n constructor(element, { wheelMultiplier = 1, touchMultiplier = 1 }) {\r\n this.element = element\r\n this.wheelMultiplier = wheelMultiplier\r\n this.touchMultiplier = touchMultiplier\r\n\r\n this.touchStart = {\r\n x: null,\r\n y: null,\r\n }\r\n\r\n this.emitter = new Emitter()\r\n window.addEventListener('resize', this.onWindowResize, false)\r\n this.onWindowResize()\r\n\r\n this.element.addEventListener('wheel', this.onWheel, { passive: false })\r\n this.element.addEventListener('touchstart', this.onTouchStart, {\r\n passive: false,\r\n })\r\n this.element.addEventListener('touchmove', this.onTouchMove, {\r\n passive: false,\r\n })\r\n this.element.addEventListener('touchend', this.onTouchEnd, {\r\n passive: false,\r\n })\r\n }\r\n\r\n // Add an event listener for the given event and callback\r\n on(event, callback) {\r\n return this.emitter.on(event, callback)\r\n }\r\n\r\n // Remove all event listeners and clean up\r\n destroy() {\r\n this.emitter.destroy()\r\n\r\n window.removeEventListener('resize', this.onWindowResize, false)\r\n\r\n this.element.removeEventListener('wheel', this.onWheel, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchstart', this.onTouchStart, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchmove', this.onTouchMove, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchend', this.onTouchEnd, {\r\n passive: false,\r\n })\r\n }\r\n\r\n // Event handler for 'touchstart' event\r\n onTouchStart = (event) => {\r\n const { clientX, clientY } = event.targetTouches\r\n ? event.targetTouches[0]\r\n : event\r\n\r\n this.touchStart.x = clientX\r\n this.touchStart.y = clientY\r\n\r\n this.lastDelta = {\r\n x: 0,\r\n y: 0,\r\n }\r\n\r\n this.emitter.emit('scroll', {\r\n deltaX: 0,\r\n deltaY: 0,\r\n event,\r\n })\r\n }\r\n\r\n // Event handler for 'touchmove' event\r\n onTouchMove = (event) => {\r\n const { clientX, clientY } = event.targetTouches\r\n ? event.targetTouches[0]\r\n : event\r\n\r\n const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier\r\n const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier\r\n\r\n this.touchStart.x = clientX\r\n this.touchStart.y = clientY\r\n\r\n this.lastDelta = {\r\n x: deltaX,\r\n y: deltaY,\r\n }\r\n\r\n this.emitter.emit('scroll', {\r\n deltaX,\r\n deltaY,\r\n event,\r\n })\r\n }\r\n\r\n onTouchEnd = (event) => {\r\n this.emitter.emit('scroll', {\r\n deltaX: this.lastDelta.x,\r\n deltaY: this.lastDelta.y,\r\n event,\r\n })\r\n }\r\n\r\n // Event handler for 'wheel' event\r\n onWheel = (event) => {\r\n let { deltaX, deltaY, deltaMode } = event\r\n\r\n const multiplierX =\r\n deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowWidth : 1\r\n const multiplierY =\r\n deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowHeight : 1\r\n\r\n deltaX *= multiplierX\r\n deltaY *= multiplierY\r\n\r\n deltaX *= this.wheelMultiplier\r\n deltaY *= this.wheelMultiplier\r\n\r\n this.emitter.emit('scroll', { deltaX, deltaY, event })\r\n }\r\n\r\n onWindowResize = () => {\r\n this.windowWidth = window.innerWidth\r\n this.windowHeight = window.innerHeight\r\n }\r\n}\r\n","import { version } from '../package.json'\r\nimport { Animate } from './animate'\r\nimport { Dimensions } from './dimensions'\r\nimport { Emitter } from './emitter'\r\nimport { clamp, modulo } from './maths'\r\nimport { VirtualScroll } from './virtual-scroll'\r\n\r\n// Technical explanation\r\n// - listen to 'wheel' events\r\n// - prevent 'wheel' event to prevent scroll\r\n// - normalize wheel delta\r\n// - add delta to targetScroll\r\n// - animate scroll to targetScroll (smooth context)\r\n// - if animation is not running, listen to 'scroll' events (native context)\r\n\r\ntype EasingFunction = (t: number) => number\r\ntype Orientation = 'vertical' | 'horizontal'\r\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\r\n\r\nexport type LenisOptions = {\r\n wrapper?: Window | HTMLElement\r\n content?: HTMLElement\r\n wheelEventsTarget?: Window | HTMLElement\r\n eventsTarget?: Window | HTMLElement\r\n smoothWheel?: boolean\r\n syncTouch?: boolean\r\n syncTouchLerp?: number\r\n touchInertiaMultiplier?: number\r\n duration?: number\r\n easing?: EasingFunction\r\n lerp?: number\r\n infinite?: boolean\r\n orientation?: Orientation\r\n gestureOrientation?: GestureOrientation\r\n touchMultiplier?: number\r\n wheelMultiplier?: number\r\n autoResize?: boolean\r\n __experimental__naiveDimensions?: boolean\r\n}\r\n\r\nexport default class Lenis {\r\n __isSmooth: boolean = false // true if scroll should be animated\r\n __isScrolling: boolean = false // true when scroll is animating\r\n __isStopped: boolean = false // true if user should not be able to scroll - enable/disable programmatically\r\n __isLocked: boolean = false // same as isStopped but enabled/disabled when scroll reaches target\r\n\r\n constructor({\r\n wrapper = window,\r\n content = document.documentElement,\r\n wheelEventsTarget = wrapper, // deprecated\r\n eventsTarget = wheelEventsTarget,\r\n smoothWheel = true,\r\n syncTouch = false,\r\n syncTouchLerp = 0.075,\r\n touchInertiaMultiplier = 35,\r\n duration, // in seconds\r\n easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),\r\n lerp = !duration && 0.1,\r\n infinite = false,\r\n orientation = 'vertical', // vertical, horizontal\r\n gestureOrientation = 'vertical', // vertical, horizontal, both\r\n touchMultiplier = 1,\r\n wheelMultiplier = 1,\r\n autoResize = true,\r\n __experimental__naiveDimensions = false,\r\n }: LenisOptions = {}) {\r\n window.lenisVersion = version\r\n\r\n // if wrapper is html or body, fallback to window\r\n if (wrapper === document.documentElement || wrapper === document.body) {\r\n wrapper = window\r\n }\r\n\r\n this.options = {\r\n wrapper,\r\n content,\r\n wheelEventsTarget,\r\n eventsTarget,\r\n smoothWheel,\r\n syncTouch,\r\n syncTouchLerp,\r\n touchInertiaMultiplier,\r\n duration,\r\n easing,\r\n lerp,\r\n infinite,\r\n gestureOrientation,\r\n orientation,\r\n touchMultiplier,\r\n wheelMultiplier,\r\n autoResize,\r\n __experimental__naiveDimensions,\r\n }\r\n\r\n this.animate = new Animate()\r\n this.emitter = new Emitter()\r\n this.dimensions = new Dimensions({ wrapper, content, autoResize })\r\n this.toggleClassName('lenis', true)\r\n\r\n this.velocity = 0\r\n this.isLocked = false\r\n this.isStopped = false\r\n this.isSmooth = syncTouch || smoothWheel\r\n this.isScrolling = false\r\n this.targetScroll = this.animatedScroll = this.actualScroll\r\n\r\n this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false)\r\n\r\n this.virtualScroll = new VirtualScroll(eventsTarget, {\r\n touchMultiplier,\r\n wheelMultiplier,\r\n })\r\n this.virtualScroll.on('scroll', this.onVirtualScroll)\r\n }\r\n\r\n destroy() {\r\n this.emitter.destroy()\r\n\r\n this.options.wrapper.removeEventListener(\r\n 'scroll',\r\n this.onNativeScroll,\r\n false\r\n )\r\n\r\n this.virtualScroll.destroy()\r\n this.dimensions.destroy()\r\n\r\n this.toggleClassName('lenis', false)\r\n this.toggleClassName('lenis-smooth', false)\r\n this.toggleClassName('lenis-scrolling', false)\r\n this.toggleClassName('lenis-stopped', false)\r\n this.toggleClassName('lenis-locked', false)\r\n }\r\n\r\n on(event: string, callback: Function) {\r\n return this.emitter.on(event, callback)\r\n }\r\n\r\n off(event: string, callback: Function) {\r\n return this.emitter.off(event, callback)\r\n }\r\n\r\n private setScroll(scroll) {\r\n // apply scroll value immediately\r\n if (this.isHorizontal) {\r\n this.rootElement.scrollLeft = scroll\r\n } else {\r\n this.rootElement.scrollTop = scroll\r\n }\r\n }\r\n\r\n private onVirtualScroll = ({ deltaX, deltaY, event }) => {\r\n // keep zoom feature\r\n if (event.ctrlKey) return\r\n\r\n const isTouch = event.type.includes('touch')\r\n const isWheel = event.type.includes('wheel')\r\n\r\n const isTapToStop =\r\n this.options.syncTouch && isTouch && event.type === 'touchstart'\r\n\r\n if (isTapToStop) {\r\n this.reset()\r\n return\r\n }\r\n\r\n const isClick = deltaX === 0 && deltaY === 0 // click event\r\n\r\n // const isPullToRefresh =\r\n // this.options.gestureOrientation === 'vertical' &&\r\n // this.scroll === 0 &&\r\n // !this.options.infinite &&\r\n // deltaY <= 5 // touch pull to refresh, not reliable yet\r\n\r\n const isUnknownGesture =\r\n (this.options.gestureOrientation === 'vertical' && deltaY === 0) ||\r\n (this.options.gestureOrientation === 'horizontal' && deltaX === 0)\r\n\r\n if (isClick || isUnknownGesture) {\r\n // console.log('prevent')\r\n return\r\n }\r\n\r\n // catch if scrolling on nested scroll elements\r\n let composedPath = event.composedPath()\r\n composedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement)) // remove parents elements\r\n\r\n if (\r\n !!composedPath.find(\r\n (node) =>\r\n node.hasAttribute?.('data-lenis-prevent') ||\r\n (isTouch && node.hasAttribute?.('data-lenis-prevent-touch')) ||\r\n (isWheel && node.hasAttribute?.('data-lenis-prevent-wheel')) ||\r\n (node.classList?.contains('lenis') &&\r\n !node.classList?.contains('lenis-stopped')) // nested lenis instance\r\n )\r\n )\r\n return\r\n\r\n if (this.isStopped || this.isLocked) {\r\n event.preventDefault() // this will stop forwarding the event to the parent, this is problematic\r\n return\r\n }\r\n\r\n this.isSmooth =\r\n (this.options.syncTouch && isTouch) ||\r\n (this.options.smoothWheel && isWheel)\r\n\r\n if (!this.isSmooth) {\r\n this.isScrolling = false\r\n this.animate.stop()\r\n return\r\n }\r\n\r\n event.preventDefault()\r\n\r\n let delta = deltaY\r\n if (this.options.gestureOrientation === 'both') {\r\n delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX\r\n } else if (this.options.gestureOrientation === 'horizontal') {\r\n delta = deltaX\r\n }\r\n\r\n const syncTouch = isTouch && this.options.syncTouch\r\n const isTouchEnd = isTouch && event.type === 'touchend'\r\n\r\n const hasTouchInertia = isTouchEnd && Math.abs(delta) > 5\r\n\r\n if (hasTouchInertia) {\r\n delta = this.velocity * this.options.touchInertiaMultiplier\r\n }\r\n\r\n this.scrollTo(this.targetScroll + delta, {\r\n programmatic: false,\r\n ...(syncTouch\r\n ? {\r\n lerp: hasTouchInertia ? this.options.syncTouchLerp : 1,\r\n }\r\n : {\r\n lerp: this.options.lerp,\r\n duration: this.options.duration,\r\n easing: this.options.easing,\r\n }),\r\n })\r\n }\r\n\r\n resize() {\r\n this.dimensions.resize()\r\n }\r\n\r\n private emit() {\r\n this.emitter.emit('scroll', this)\r\n }\r\n\r\n private onNativeScroll = () => {\r\n if (this.__preventNextScrollEvent) return\r\n\r\n if (!this.isScrolling) {\r\n const lastScroll = this.animatedScroll\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.velocity = 0\r\n this.direction = Math.sign(this.animatedScroll - lastScroll)\r\n this.emit()\r\n }\r\n }\r\n\r\n private reset() {\r\n this.isLocked = false\r\n this.isScrolling = false\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.velocity = 0\r\n this.animate.stop()\r\n }\r\n\r\n start() {\r\n if (!this.isStopped) return\r\n this.isStopped = false\r\n\r\n this.reset()\r\n }\r\n\r\n stop() {\r\n if (this.isStopped) return\r\n this.isStopped = true\r\n this.animate.stop()\r\n\r\n this.reset()\r\n }\r\n\r\n raf(time: number) {\r\n const deltaTime = time - (this.time || time)\r\n this.time = time\r\n\r\n this.animate.advance(deltaTime * 0.001)\r\n }\r\n\r\n scrollTo(\r\n target: number | string | HTMLElement,\r\n {\r\n offset = 0,\r\n immediate = false,\r\n lock = false,\r\n duration = this.options.duration,\r\n easing = this.options.easing,\r\n lerp = !duration && this.options.lerp,\r\n onComplete,\r\n force = false, // scroll even if stopped\r\n programmatic = true, // called from outside of the class\r\n }: {\r\n offset?: number\r\n immediate?: boolean\r\n lock?: boolean\r\n duration?: number\r\n easing?: EasingFunction\r\n lerp?: number\r\n onComplete?: (lenis: Lenis) => void\r\n force?: boolean\r\n programmatic?: boolean\r\n } = {}\r\n ) {\r\n if ((this.isStopped || this.isLocked) && !force) return\r\n\r\n // keywords\r\n if (['top', 'left', 'start'].includes(target)) {\r\n target = 0\r\n } else if (['bottom', 'right', 'end'].includes(target)) {\r\n target = this.limit\r\n } else {\r\n let node\r\n\r\n if (typeof target === 'string') {\r\n // CSS selector\r\n node = document.querySelector(target)\r\n } else if (target?.nodeType) {\r\n // Node element\r\n node = target\r\n }\r\n\r\n if (node) {\r\n if (this.options.wrapper !== window) {\r\n // nested scroll offset correction\r\n const wrapperRect = this.options.wrapper.getBoundingClientRect()\r\n offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top\r\n }\r\n\r\n const rect = node.getBoundingClientRect()\r\n\r\n target =\r\n (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll\r\n }\r\n }\r\n\r\n if (typeof target !== 'number') return\r\n\r\n target += offset\r\n target = Math.round(target)\r\n\r\n if (this.options.infinite) {\r\n if (programmatic) {\r\n this.targetScroll = this.animatedScroll = this.scroll\r\n }\r\n } else {\r\n target = clamp(0, target, this.limit)\r\n }\r\n\r\n if (immediate) {\r\n this.animatedScroll = this.targetScroll = target\r\n this.setScroll(this.scroll)\r\n this.reset()\r\n onComplete?.(this)\r\n return\r\n }\r\n\r\n if (!programmatic) {\r\n if (target === this.targetScroll) return\r\n\r\n this.targetScroll = target\r\n }\r\n\r\n this.animate.fromTo(this.animatedScroll, target, {\r\n duration,\r\n easing,\r\n lerp,\r\n onStart: () => {\r\n // started\r\n if (lock) this.isLocked = true\r\n this.isScrolling = true\r\n },\r\n onUpdate: (value: number, completed: boolean) => {\r\n this.isScrolling = true\r\n\r\n // updated\r\n this.velocity = value - this.animatedScroll\r\n this.direction = Math.sign(this.velocity)\r\n\r\n this.animatedScroll = value\r\n this.setScroll(this.scroll)\r\n\r\n if (programmatic) {\r\n // wheel during programmatic should stop it\r\n this.targetScroll = value\r\n }\r\n\r\n if (!completed) this.emit()\r\n\r\n if (completed) {\r\n this.reset()\r\n this.emit()\r\n onComplete?.(this)\r\n\r\n // avoid emitting event twice\r\n this.__preventNextScrollEvent = true\r\n requestAnimationFrame(() => {\r\n delete this.__preventNextScrollEvent\r\n })\r\n }\r\n },\r\n })\r\n }\r\n\r\n get rootElement() {\r\n return this.options.wrapper === window\r\n ? document.documentElement\r\n : this.options.wrapper\r\n }\r\n\r\n get limit() {\r\n if (this.options.__experimental__naiveDimensions) {\r\n if (this.isHorizontal) {\r\n return this.rootElement.scrollWidth - this.rootElement.clientWidth\r\n } else {\r\n return this.rootElement.scrollHeight - this.rootElement.clientHeight\r\n }\r\n } else {\r\n return this.dimensions.limit[this.isHorizontal ? 'x' : 'y']\r\n }\r\n }\r\n\r\n get isHorizontal() {\r\n return this.options.orientation === 'horizontal'\r\n }\r\n\r\n get actualScroll() {\r\n // value browser takes into account\r\n return this.isHorizontal\r\n ? this.rootElement.scrollLeft\r\n : this.rootElement.scrollTop\r\n }\r\n\r\n get scroll() {\r\n return this.options.infinite\r\n ? modulo(this.animatedScroll, this.limit)\r\n : this.animatedScroll\r\n }\r\n\r\n get progress() {\r\n // avoid progress to be NaN\r\n return this.limit === 0 ? 1 : this.scroll / this.limit\r\n }\r\n\r\n get isSmooth() {\r\n return this.__isSmooth\r\n }\r\n\r\n private set isSmooth(value: boolean) {\r\n if (this.__isSmooth !== value) {\r\n this.__isSmooth = value\r\n this.toggleClassName('lenis-smooth', value)\r\n }\r\n }\r\n\r\n get isScrolling() {\r\n return this.__isScrolling\r\n }\r\n\r\n private set isScrolling(value: boolean) {\r\n if (this.__isScrolling !== value) {\r\n this.__isScrolling = value\r\n this.toggleClassName('lenis-scrolling', value)\r\n }\r\n }\r\n\r\n get isStopped() {\r\n return this.__isStopped\r\n }\r\n\r\n private set isStopped(value: boolean) {\r\n if (this.__isStopped !== value) {\r\n this.__isStopped = value\r\n this.toggleClassName('lenis-stopped', value)\r\n }\r\n }\r\n\r\n get isLocked() {\r\n return this.__isLocked\r\n }\r\n\r\n private set isLocked(value: boolean) {\r\n if (this.__isLocked !== value) {\r\n this.__isLocked = value\r\n this.toggleClassName('lenis-locked', value)\r\n }\r\n }\r\n\r\n get className() {\r\n let className = 'lenis'\r\n if (this.isStopped) className += ' lenis-stopped'\r\n if (this.isLocked) className += ' lenis-locked'\r\n if (this.isScrolling) className += ' lenis-scrolling'\r\n if (this.isSmooth) className += ' lenis-smooth'\r\n return className\r\n }\r\n\r\n private toggleClassName(name: string, value: boolean) {\r\n this.rootElement.classList.toggle(name, value)\r\n this.emitter.emit('className change', this)\r\n }\r\n}\r\n"],"names":["clamp","min","input","max","Math","Animate","advance","deltaTime","this","isRunning","completed","lerp","value","x","y","to","lambda","dt","t","exp","round","currentTime","linearProgress","duration","easedProgress","easing","from","onUpdate","stop","fromTo","onStart","Dimensions","constructor","wrapper","content","autoResize","debounce","debounceValue","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","resize","window","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","removeEventListener","onWrapperResize","onContentResize","width","innerWidth","height","innerHeight","clientWidth","clientHeight","scrollHeight","scrollWidth","limit","Emitter","events","emit","event","callbacks","i","length","on","cb","push","filter","off","LINE_HEIGHT","VirtualScroll","element","wheelMultiplier","touchMultiplier","touchStart","emitter","onWindowResize","onWheel","passive","onTouchStart","onTouchMove","onTouchEnd","clientX","clientY","targetTouches","lastDelta","deltaX","deltaY","deltaMode","windowWidth","windowHeight","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","__experimental__naiveDimensions","__isSmooth","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","options","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","isStopped","isLocked","preventDefault","isSmooth","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__preventNextScrollEvent","lastScroll","animatedScroll","actualScroll","direction","sign","lenisVersion","body","dimensions","toggleClassName","virtualScroll","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","time","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","requestAnimationFrame","n","d","progress","className","name","toggle"],"mappings":"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"} \ No newline at end of file diff --git a/packages/lenis/dist/types/index.d.ts b/packages/lenis/dist/types/index.d.ts index 79934c59..8fb7b849 100644 --- a/packages/lenis/dist/types/index.d.ts +++ b/packages/lenis/dist/types/index.d.ts @@ -18,7 +18,6 @@ export type LenisOptions = { gestureOrientation?: GestureOrientation; touchMultiplier?: number; wheelMultiplier?: number; - normalizeWheel?: boolean; autoResize?: boolean; __experimental__naiveDimensions?: boolean; }; @@ -27,7 +26,7 @@ export default class Lenis { __isScrolling: boolean; __isStopped: boolean; __isLocked: boolean; - constructor({ wrapper, content, wheelEventsTarget, eventsTarget, smoothWheel, syncTouch, syncTouchLerp, touchInertiaMultiplier, duration, easing, lerp, infinite, orientation, gestureOrientation, touchMultiplier, wheelMultiplier, normalizeWheel, autoResize, __experimental__naiveDimensions, }?: LenisOptions); + constructor({ wrapper, content, wheelEventsTarget, eventsTarget, smoothWheel, syncTouch, syncTouchLerp, touchInertiaMultiplier, duration, easing, lerp, infinite, orientation, gestureOrientation, touchMultiplier, wheelMultiplier, autoResize, __experimental__naiveDimensions, }?: LenisOptions); destroy(): void; on(event: string, callback: Function): any; off(event: string, callback: Function): any; diff --git a/packages/lenis/dist/types/virtual-scroll.d.ts b/packages/lenis/dist/types/virtual-scroll.d.ts index acb7fbd3..500e6f02 100644 --- a/packages/lenis/dist/types/virtual-scroll.d.ts +++ b/packages/lenis/dist/types/virtual-scroll.d.ts @@ -1,13 +1,11 @@ export class VirtualScroll { - constructor(element: any, { wheelMultiplier, touchMultiplier, normalizeWheel }: { + constructor(element: any, { wheelMultiplier, touchMultiplier }: { wheelMultiplier?: number | undefined; touchMultiplier?: number | undefined; - normalizeWheel?: boolean | undefined; }); element: any; wheelMultiplier: number; touchMultiplier: number; - normalizeWheel: boolean; touchStart: { x: null; y: null; @@ -26,5 +24,8 @@ export class VirtualScroll { onTouchMove: (event: any) => void; onTouchEnd: (event: any) => void; onWheel: (event: any) => void; + onWindowResize: () => void; + windowWidth: number | undefined; + windowHeight: number | undefined; } import { Emitter } from './emitter'; diff --git a/packages/lenis/playground/index.html b/packages/lenis/playground/index.html index 3d084381..d5d8da4c 100644 --- a/packages/lenis/playground/index.html +++ b/packages/lenis/playground/index.html @@ -1,4 +1,4 @@ - + @@ -7,7 +7,91 @@ Vite App -
+
+
+
+ + + + + + +

Hello Vite!

+
+ +
+

Click on the Vite logo to learn more

+
+
+
+ + + + + + +

Hello Vite!

+
+ +
+

Click on the Vite logo to learn more

+
+
+ + + + + + +

Hello Vite!

+
+ +
+

Click on the Vite logo to learn more

+
+
+ + + + + + +

Hello Vite!

+
+ +
+

Click on the Vite logo to learn more

+
+
+
diff --git a/packages/lenis/playground/main.js b/packages/lenis/playground/main.js index 691be124..9e8685a4 100644 --- a/packages/lenis/playground/main.js +++ b/packages/lenis/playground/main.js @@ -1,9 +1,7 @@ import Lenis from '../dist/lenis.mjs' import { setupCounter } from './counter.js' // import './jank.js' -import javascriptLogo from './javascript.svg' import './style.css' -import viteLogo from '/vite.svg' const lenis = new Lenis({ smoothWheel: true, @@ -28,69 +26,4 @@ requestAnimationFrame((deltaTime) => { update(deltaTime) }) -document.querySelector('#app').innerHTML = ` -
-
- - - - - - -

Hello Vite!

-
- -
-

- Click on the Vite logo to learn more -

-
-
- - - - - - -

Hello Vite!

-
- -
-

- Click on the Vite logo to learn more -

-
-
- - - - - - -

Hello Vite!

-
- -
-

- Click on the Vite logo to learn more -

-
-
- - - - - - -

Hello Vite!

-
- -
-

- Click on the Vite logo to learn more -

-
-
-` - setupCounter(document.querySelector('#counter')) diff --git a/packages/lenis/playground/package.json b/packages/lenis/playground/package.json index ec34743b..47e62779 100644 --- a/packages/lenis/playground/package.json +++ b/packages/lenis/playground/package.json @@ -10,5 +10,8 @@ }, "devDependencies": { "vite": "^5.0.8" + }, + "dependencies": { + "gsap": "^3.12.5" } } diff --git a/packages/lenis/playground/style.css b/packages/lenis/playground/style.css index 97fe0dd3..b318cb60 100644 --- a/packages/lenis/playground/style.css +++ b/packages/lenis/playground/style.css @@ -131,3 +131,9 @@ button:focus-visible { min-width: 20vw; } } + +#observer { + height: 50vh; + width: 100%; + background-color: blue; +} diff --git a/packages/lenis/playground/yarn.lock b/packages/lenis/playground/yarn.lock index 81ef0378..d6980a42 100644 --- a/packages/lenis/playground/yarn.lock +++ b/packages/lenis/playground/yarn.lock @@ -216,6 +216,11 @@ fsevents@~2.3.2, fsevents@~2.3.3: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== +gsap@^3.12.5: + version "3.12.5" + resolved "https://registry.yarnpkg.com/gsap/-/gsap-3.12.5.tgz#136c02dad4c673b441bdb1ca00104bfcb4eae7f4" + integrity sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ== + nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" diff --git a/packages/lenis/src/index.ts b/packages/lenis/src/index.ts index 791b05f5..4c6aba95 100644 --- a/packages/lenis/src/index.ts +++ b/packages/lenis/src/index.ts @@ -34,7 +34,6 @@ export type LenisOptions = { gestureOrientation?: GestureOrientation touchMultiplier?: number wheelMultiplier?: number - normalizeWheel?: boolean autoResize?: boolean __experimental__naiveDimensions?: boolean } @@ -62,7 +61,6 @@ export default class Lenis { gestureOrientation = 'vertical', // vertical, horizontal, both touchMultiplier = 1, wheelMultiplier = 1, - normalizeWheel = false, // deprecated autoResize = true, __experimental__naiveDimensions = false, }: LenisOptions = {}) { @@ -90,7 +88,6 @@ export default class Lenis { orientation, touchMultiplier, wheelMultiplier, - normalizeWheel, autoResize, __experimental__naiveDimensions, } @@ -112,7 +109,6 @@ export default class Lenis { this.virtualScroll = new VirtualScroll(eventsTarget, { touchMultiplier, wheelMultiplier, - normalizeWheel, }) this.virtualScroll.on('scroll', this.onVirtualScroll) } diff --git a/packages/lenis/src/virtual-scroll.js b/packages/lenis/src/virtual-scroll.js index 1d8934cd..95f8f04b 100644 --- a/packages/lenis/src/virtual-scroll.js +++ b/packages/lenis/src/virtual-scroll.js @@ -1,15 +1,12 @@ import { Emitter } from './emitter' -import { clamp } from './maths' + +const LINE_HEIGHT = 100 / 6 export class VirtualScroll { - constructor( - element, - { wheelMultiplier = 1, touchMultiplier = 2, normalizeWheel = false } - ) { + constructor(element, { wheelMultiplier = 1, touchMultiplier = 1 }) { this.element = element this.wheelMultiplier = wheelMultiplier this.touchMultiplier = touchMultiplier - this.normalizeWheel = normalizeWheel this.touchStart = { x: null, @@ -17,6 +14,8 @@ export class VirtualScroll { } this.emitter = new Emitter() + window.addEventListener('resize', this.onWindowResize, false) + this.onWindowResize() this.element.addEventListener('wheel', this.onWheel, { passive: false }) this.element.addEventListener('touchstart', this.onTouchStart, { @@ -39,6 +38,8 @@ export class VirtualScroll { destroy() { this.emitter.destroy() + window.removeEventListener('resize', this.onWindowResize, false) + this.element.removeEventListener('wheel', this.onWheel, { passive: false, }) @@ -108,16 +109,24 @@ export class VirtualScroll { // Event handler for 'wheel' event onWheel = (event) => { - let { deltaX, deltaY } = event + let { deltaX, deltaY, deltaMode } = event - if (this.normalizeWheel) { - deltaX = clamp(-100, deltaX, 100) - deltaY = clamp(-100, deltaY, 100) - } + const multiplierX = + deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowWidth : 1 + const multiplierY = + deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowHeight : 1 + + deltaX *= multiplierX + deltaY *= multiplierY deltaX *= this.wheelMultiplier deltaY *= this.wheelMultiplier this.emitter.emit('scroll', { deltaX, deltaY, event }) } + + onWindowResize = () => { + this.windowWidth = window.innerWidth + this.windowHeight = window.innerHeight + } } diff --git a/yarn.lock b/yarn.lock index 3ad801ee..6931f9f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2579,7 +2579,7 @@ yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -zustand@^4.4.7: +zustand@^4.4.7, zustand@^4.5.1: version "4.5.1" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.1.tgz#2088956ee454759fb8b866ca335a2373e76736c5" integrity sha512-XlauQmH64xXSC1qGYNv00ODaQ3B+tNPoy22jv2diYiP4eoDKr9LA+Bh5Bc3gplTrFdb6JVI+N4kc1DZ/tbtfPg==