From c81f4b66750cf5d515d0ffa87ae79d6953daae86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Roche?= Date: Thu, 30 May 2024 14:57:39 +0200 Subject: [PATCH] v1.1.0 build --- README.md | 2 +- dist/lenis.js | 2 +- dist/lenis.min.js | 2 +- dist/lenis.min.js.map | 2 +- dist/lenis.mjs | 2 +- dist/lenis.mjs.map | 2 +- packages/snap/dist/index.d.ts | 8 - packages/snap/dist/lenis-snap.d.ts | 28 ++- packages/snap/dist/lenis-snap.js | 213 +++++++++++++++++------ packages/snap/dist/lenis-snap.js.map | 2 +- packages/snap/dist/lenis-snap.min.js | 2 +- packages/snap/dist/lenis-snap.min.js.map | 2 +- packages/snap/dist/lenis-snap.mjs | 2 +- packages/snap/dist/lenis-snap.mjs.map | 2 +- 14 files changed, 193 insertions(+), 78 deletions(-) delete mode 100644 packages/snap/dist/index.d.ts diff --git a/README.md b/README.md index 05d90f20..5d503689 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ import Lenis from 'lenis' using scripts: ```html - + ``` diff --git a/dist/lenis.js b/dist/lenis.js index ef0a1501..20b4d208 100644 --- a/dist/lenis.js +++ b/dist/lenis.js @@ -4,7 +4,7 @@ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Lenis = factory()); })(this, (function () { 'use strict'; - var version = "1.0.46-dev.0"; + var version = "1.1.0"; // Clamp a value between a minimum and maximum value function clamp(min, input, max) { diff --git a/dist/lenis.min.js b/dist/lenis.min.js index 44345dd8..cf7a7fd8 100644 --- a/dist/lenis.min.js +++ b/dist/lenis.min.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 clamp(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(t){if(!this.isRunning)return;let e=!1;if(this.lerp)this.value=function damp(t,e,i,s){return function lerp(t,e,i){return(1-i)*t+i*e}(t,e,1-Math.exp(-i*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0);else{this.currentTime+=t;const i=clamp(0,this.currentTime/this.duration,1);e=i>=1;const s=e?1:this.easing(i);this.value=this.from+(this.to-this.from)*s}e&&this.stop(),this.onUpdate?.(this.value,e)}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 debounce(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 t=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=e=>{let{deltaX:i,deltaY:s,deltaMode:o}=e;i*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:e})};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: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:u="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:S=!1,__experimental__naiveDimensions:w=!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");this.isTouching="touchstart"===i.type||"touchmove"===i.type;if(this.options.syncTouch&&s&&"touchstart"===i.type&&!this.isStopped&&!this.isLocked)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 this.options.prevent(t)||(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.options.syncTouch&&s||this.options.smoothWheel&&o))return this.isScrolling="native",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(clearTimeout(this.__resetVelocityTimeout),delete this.__resetVelocityTimeout,this.__preventNextNativeScrollEvent)delete this.__preventNextNativeScrollEvent;else if(!1===this.isScrolling||"native"===this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=this.velocity,this.velocity=this.animatedScroll-t,this.direction=Math.sign(this.animatedScroll-t),this.isScrolling=!!this.hasScrolled&&"native",this.emit(),0!==this.velocity&&(this.__resetVelocityTimeout=setTimeout((()=>{this.lastVelocity=this.velocity,this.velocity=0,this.isScrolling=!1,this.emit()}),400))}},window.lenisVersion="1.0.46-dev.0",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:p,orientation:u,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:S,__experimental__naiveDimensions:w},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:g}),this.updateClassName(),this.userData={},this.time=0,this.velocity=this.lastVelocity=0,this.isLocked=!1,this.isStopped=!1,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.cleanUpClassName()}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({userData:t={}}={}){this.userData=t,this.emitter.emit("scroll",this),this.userData={}}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=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(t,{offset:e=0,immediate:i=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:r=!o&&this.options.lerp,onStart:l,onComplete:h,force:a=!1,programmatic:c=!0,userData:d={}}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(t))t=0;else if(["bottom","right","end"].includes(t))t=this.limit;else{let i;if("string"==typeof t?i=document.querySelector(t):(null==t?void 0:t.nodeType)&&(i=t),i){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();e-=this.isHorizontal?t.left:t.top}const s=i.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t){if(t+=e,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),i)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));t!==this.targetScroll&&(c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:r,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==l||l(this)},onUpdate:(t,e)=>{this.isScrolling="smooth",this.lastVelocity=this.velocity,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({userData:d}),e&&(this.reset(),this.emit({userData:d}),null==h||h(this),this.__preventNextNativeScrollEvent=!0)}}))}}}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?function modulo(t,e){return(t%e+e)%e}(this.animatedScroll,this.limit):this.animatedScroll}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.updateClassName())}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.updateClassName())}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.updateClassName())}get isSmooth(){return"smooth"===this.isScrolling}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),"smooth"===this.isScrolling&&(t+=" lenis-smooth"),t}updateClassName(){this.cleanUpClassName(),this.rootElement.className=`${this.rootElement.className} ${this.className}`.trim()}cleanUpClassName(){this.rootElement.className=this.rootElement.className.replace(/lenis(-\w+)?/g,"").trim()}}})); +!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 clamp(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(t){if(!this.isRunning)return;let e=!1;if(this.lerp)this.value=function damp(t,e,i,s){return function lerp(t,e,i){return(1-i)*t+i*e}(t,e,1-Math.exp(-i*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0);else{this.currentTime+=t;const i=clamp(0,this.currentTime/this.duration,1);e=i>=1;const s=e?1:this.easing(i);this.value=this.from+(this.to-this.from)*s}e&&this.stop(),this.onUpdate?.(this.value,e)}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 debounce(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 t=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=e=>{let{deltaX:i,deltaY:s,deltaMode:o}=e;i*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:e})};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: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:u=!1,orientation:d="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:S=!1,__experimental__naiveDimensions:w=!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");this.isTouching="touchstart"===i.type||"touchmove"===i.type;if(this.options.syncTouch&&s&&"touchstart"===i.type&&!this.isStopped&&!this.isLocked)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 this.options.prevent(t)||(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.options.syncTouch&&s||this.options.smoothWheel&&o))return this.isScrolling="native",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(clearTimeout(this.__resetVelocityTimeout),delete this.__resetVelocityTimeout,this.__preventNextNativeScrollEvent)delete this.__preventNextNativeScrollEvent;else if(!1===this.isScrolling||"native"===this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=this.velocity,this.velocity=this.animatedScroll-t,this.direction=Math.sign(this.animatedScroll-t),this.isScrolling=!!this.hasScrolled&&"native",this.emit(),0!==this.velocity&&(this.__resetVelocityTimeout=setTimeout((()=>{this.lastVelocity=this.velocity,this.velocity=0,this.isScrolling=!1,this.emit()}),400))}},window.lenisVersion="1.1.0",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:u,gestureOrientation:p,orientation:d,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:S,__experimental__naiveDimensions:w},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:g}),this.updateClassName(),this.userData={},this.time=0,this.velocity=this.lastVelocity=0,this.isLocked=!1,this.isStopped=!1,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.cleanUpClassName()}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({userData:t={}}={}){this.userData=t,this.emitter.emit("scroll",this),this.userData={}}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=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(t,{offset:e=0,immediate:i=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:r=!o&&this.options.lerp,onStart:l,onComplete:h,force:a=!1,programmatic:c=!0,userData:u={}}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(t))t=0;else if(["bottom","right","end"].includes(t))t=this.limit;else{let i;if("string"==typeof t?i=document.querySelector(t):(null==t?void 0:t.nodeType)&&(i=t),i){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();e-=this.isHorizontal?t.left:t.top}const s=i.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t){if(t+=e,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),i)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));t!==this.targetScroll&&(c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:r,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==l||l(this)},onUpdate:(t,e)=>{this.isScrolling="smooth",this.lastVelocity=this.velocity,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({userData:u}),e&&(this.reset(),this.emit({userData:u}),null==h||h(this),this.__preventNextNativeScrollEvent=!0)}}))}}}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?function modulo(t,e){return(t%e+e)%e}(this.animatedScroll,this.limit):this.animatedScroll}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.updateClassName())}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.updateClassName())}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.updateClassName())}get isSmooth(){return"smooth"===this.isScrolling}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),"smooth"===this.isScrolling&&(t+=" lenis-smooth"),t}updateClassName(){this.cleanUpClassName(),this.rootElement.className=`${this.rootElement.className} ${this.className}`.trim()}cleanUpClassName(){this.rootElement.className=this.rootElement.className.replace(/lenis(-\w+)?/g,"").trim()}}})); //# sourceMappingURL=lenis.min.js.map diff --git a/dist/lenis.min.js.map b/dist/lenis.min.js.map index 4adf34ed..294b6235 100644 --- a/dist/lenis.min.js.map +++ b/dist/lenis.min.js.map @@ -1 +1 @@ -{"version":3,"file":"lenis.min.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 if (completed) {\r\n this.stop()\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\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 prevent?: boolean | ((node: Element) => 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 | 'native' | 'smooth' = 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 time: number\r\n userData: object\r\n lastVelocity: number\r\n velocity: number\r\n direction: 1 | -1 | undefined\r\n options: LenisOptions\r\n targetScroll: number\r\n animatedScroll: number\r\n // animate: Animate\r\n // emitter: Emitter\r\n // dimensions: Dimensions\r\n // virtualScroll: VirtualScroll\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 prevent = false,\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 prevent,\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 this.updateClassName()\r\n\r\n this.userData = {}\r\n this.time = 0\r\n this.velocity = this.lastVelocity = 0\r\n this.isLocked = false\r\n this.isStopped = false\r\n // this.hasScrolled = false\r\n // this.isSmooth = syncTouch || smoothWheel\r\n // this.isSmooth = false\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.cleanUpClassName()\r\n\r\n // this.rootElement.className = ''\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 this.isTouching = event.type === 'touchstart' || event.type === 'touchmove'\r\n // if (event.type === 'touchend') {\r\n // console.log('touchend', this.scroll)\r\n // // this.lastVelocity = this.velocity\r\n // // this.velocity = 0\r\n // // this.isScrolling = false\r\n // this.emit({ type: 'touchend' })\r\n // // alert('touchend')\r\n // return\r\n // }\r\n\r\n const isTapToStop =\r\n this.options.syncTouch &&\r\n isTouch &&\r\n event.type === 'touchstart' &&\r\n !this.isStopped &&\r\n !this.isLocked\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 this.options.prevent(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 const isSmooth =\r\n (this.options.syncTouch && isTouch) ||\r\n (this.options.smoothWheel && isWheel)\r\n\r\n if (!isSmooth) {\r\n this.isScrolling = 'native'\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({ userData = {} } = {}) {\r\n this.userData = userData\r\n this.emitter.emit('scroll', this)\r\n this.userData = {}\r\n }\r\n\r\n private onNativeScroll = () => {\r\n clearTimeout(this.__resetVelocityTimeout)\r\n delete this.__resetVelocityTimeout\r\n\r\n if (this.__preventNextNativeScrollEvent) {\r\n delete this.__preventNextNativeScrollEvent\r\n return\r\n }\r\n\r\n if (this.isScrolling === false || this.isScrolling === 'native') {\r\n const lastScroll = this.animatedScroll\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.lastVelocity = this.velocity\r\n this.velocity = this.animatedScroll - lastScroll\r\n this.direction = Math.sign(this.animatedScroll - lastScroll)\r\n // this.isSmooth = false\r\n this.isScrolling = this.hasScrolled ? 'native' : false\r\n this.emit()\r\n\r\n if (this.velocity !== 0) {\r\n this.__resetVelocityTimeout = setTimeout(() => {\r\n this.lastVelocity = this.velocity\r\n this.velocity = 0\r\n this.isScrolling = false\r\n this.emit()\r\n }, 400)\r\n }\r\n\r\n // this.hasScrolled = true\r\n // }, 50)\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.lastVelocity = 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 onStart,\r\n onComplete,\r\n force = false, // scroll even if stopped\r\n programmatic = true, // called from outside of the class\r\n userData = {},\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 onStart?: (lenis: Lenis) => void\r\n onComplete?: (lenis: Lenis) => void\r\n force?: boolean\r\n programmatic?: boolean\r\n userData?: object\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 (target === this.targetScroll) return\r\n\r\n if (!programmatic) {\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 = 'smooth'\r\n onStart?.(this)\r\n },\r\n onUpdate: (value: number, completed: boolean) => {\r\n this.isScrolling = 'smooth'\r\n\r\n // updated\r\n this.lastVelocity = this.velocity\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({ userData })\r\n\r\n if (completed) {\r\n this.reset()\r\n this.emit({ userData })\r\n onComplete?.(this)\r\n\r\n // avoid emitting event twice\r\n this.__preventNextNativeScrollEvent = true\r\n // requestAnimationFrame(() => {\r\n // delete this.__preventNextNativeScrollEvent\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(): number {\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(): number {\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(): number {\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.updateClassName()\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.updateClassName()\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.updateClassName()\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.updateClassName()\r\n }\r\n }\r\n\r\n get isSmooth() {\r\n return this.isScrolling === 'smooth'\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.isScrolling === 'smooth') className += ' lenis-smooth'\r\n // if (this.isScrolling === 'native') className += ' lenis-native'\r\n // if (this.isSmooth) className += ' lenis-smooth'\r\n return className\r\n }\r\n\r\n private updateClassName() {\r\n this.cleanUpClassName()\r\n\r\n this.rootElement.className =\r\n `${this.rootElement.className} ${this.className}`.trim()\r\n // this.emitter.emit('className change', this)\r\n }\r\n\r\n private cleanUpClassName() {\r\n this.rootElement.className = this.rootElement.className\r\n .replace(/lenis(-\\w+)?/g, '')\r\n .trim()\r\n }\r\n\r\n // private toggleClassName(name: string, value: boolean) {\r\n // // this.rootElement.classList.toggle(name, value)\r\n // this.rootElement.className = this.className\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","damp","x","y","lambda","dt","t","exp","to","round","currentTime","linearProgress","duration","easedProgress","easing","from","stop","onUpdate","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","prevent","__experimental__naiveDimensions","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","isTouching","options","isStopped","isLocked","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","preventDefault","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__resetVelocityTimeout","__preventNextNativeScrollEvent","lastScroll","animatedScroll","actualScroll","lastVelocity","direction","sign","hasScrolled","lenisVersion","body","dimensions","updateClassName","userData","time","virtualScroll","cleanUpClassName","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","modulo","n","d","progress","isSmooth","className","trim","replace"],"mappings":"sOACO,SAASA,MAAMC,EAAKC,EAAOC,GAChC,OAAOC,KAAKD,IAAIF,EAAKG,KAAKH,IAAIC,EAAOC,GACvC,CCAO,MAAME,QAEX,OAAAC,CAAQC,GACN,IAAKC,KAAKC,UAAW,OAErB,IAAIC,GAAY,EAEhB,GAAIF,KAAKG,KACPH,KAAKI,MDKJ,SAASC,KAAKC,EAAGC,EAAGC,EAAQC,GACjC,OANK,SAASN,KAAKG,EAAGC,EAAGG,GACzB,OAAQ,EAAIA,GAAKJ,EAAII,EAAIH,CAC3B,CAISJ,CAAKG,EAAGC,EAAG,EAAIX,KAAKe,KAAKH,EAASC,GAC3C,CCPmBJ,CAAKL,KAAKI,MAAOJ,KAAKY,GAAgB,GAAZZ,KAAKG,KAAWJ,GACnDH,KAAKiB,MAAMb,KAAKI,SAAWJ,KAAKY,KAClCZ,KAAKI,MAAQJ,KAAKY,GAClBV,GAAY,OAET,CACLF,KAAKc,aAAef,EACpB,MAAMgB,EAAiBvB,MAAM,EAAGQ,KAAKc,YAAcd,KAAKgB,SAAU,GAElEd,EAAYa,GAAkB,EAC9B,MAAME,EAAgBf,EAAY,EAAIF,KAAKkB,OAAOH,GAClDf,KAAKI,MAAQJ,KAAKmB,MAAQnB,KAAKY,GAAKZ,KAAKmB,MAAQF,CAClD,CAEGf,GACFF,KAAKoB,OAIPpB,KAAKqB,WAAWrB,KAAKI,MAAOF,EAC7B,CAGD,IAAAkB,GACEpB,KAAKC,WAAY,CAClB,CAID,MAAAqB,CACEH,EACAP,GACAT,KAAEA,EAAO,GAAGa,SAAEA,EAAW,EAACE,OAAEA,EAAS,CAACR,GAAMA,GAACa,QAAEA,EAAOF,SAAEA,IAExDrB,KAAKmB,KAAOnB,KAAKI,MAAQe,EACzBnB,KAAKY,GAAKA,EACVZ,KAAKG,KAAOA,EACZH,KAAKgB,SAAWA,EAChBhB,KAAKkB,OAASA,EACdlB,KAAKc,YAAc,EACnBd,KAAKC,WAAY,EAEjBsB,MACAvB,KAAKqB,SAAWA,CACjB,ECrDI,MAAMG,WACX,WAAAC,EAAYC,QACVA,EAAOC,QACPA,EAAOC,WACPA,GAAa,EACbC,SAAUC,EAAgB,KACxB,IACF9B,KAAK0B,QAAUA,EACf1B,KAAK2B,QAAUA,EAEXC,IACF5B,KAAK+B,gBCbJ,SAASF,SAASG,EAAUC,GACjC,IAAIC,EACJ,OAAO,WACL,IAAIC,EAAOC,UACPC,EAAUrC,KACdsC,aAAaJ,GACbA,EAAQK,YAAW,WACjBP,EAASQ,MAAMH,EAASF,EACzB,GAAEF,EACJ,CACH,CDG6BJ,CAAS7B,KAAKyC,OAAQX,GAEzC9B,KAAK0B,UAAYgB,OACnBA,OAAOC,iBAAiB,SAAU3C,KAAK+B,iBAAiB,IAExD/B,KAAK4C,sBAAwB,IAAIC,eAAe7C,KAAK+B,iBACrD/B,KAAK4C,sBAAsBE,QAAQ9C,KAAK0B,UAG1C1B,KAAK+C,sBAAwB,IAAIF,eAAe7C,KAAK+B,iBACrD/B,KAAK+C,sBAAsBD,QAAQ9C,KAAK2B,UAG1C3B,KAAKyC,QACN,CAED,OAAAO,GACEhD,KAAK4C,uBAAuBK,aAC5BjD,KAAK+C,uBAAuBE,aAC5BP,OAAOQ,oBAAoB,SAAUlD,KAAK+B,iBAAiB,EAC5D,CAEDU,OAAS,KACPzC,KAAKmD,kBACLnD,KAAKoD,iBAAiB,EAGxBD,gBAAkB,KACZnD,KAAK0B,UAAYgB,QACnB1C,KAAKqD,MAAQX,OAAOY,WACpBtD,KAAKuD,OAASb,OAAOc,cAErBxD,KAAKqD,MAAQrD,KAAK0B,QAAQ+B,YAC1BzD,KAAKuD,OAASvD,KAAK0B,QAAQgC,aAC5B,EAGHN,gBAAkB,KACZpD,KAAK0B,UAAYgB,QACnB1C,KAAK2D,aAAe3D,KAAK2B,QAAQgC,aACjC3D,KAAK4D,YAAc5D,KAAK2B,QAAQiC,cAEhC5D,KAAK2D,aAAe3D,KAAK0B,QAAQiC,aACjC3D,KAAK4D,YAAc5D,KAAK0B,QAAQkC,YACjC,EAGH,SAAIC,GACF,MAAO,CACLvD,EAAGN,KAAK4D,YAAc5D,KAAKqD,MAC3B9C,EAAGP,KAAK2D,aAAe3D,KAAKuD,OAE/B,EEjEI,MAAMO,QACX,WAAArC,GACEzB,KAAK+D,OAAS,CAAE,CACjB,CAED,IAAAC,CAAKC,KAAU9B,GACb,IAAI+B,EAAYlE,KAAK+D,OAAOE,IAAU,GACtC,IAAK,IAAIE,EAAI,EAAGC,EAASF,EAAUE,OAAQD,EAAIC,EAAQD,IACrDD,EAAUC,MAAMhC,EAEnB,CAED,EAAAkC,CAAGJ,EAAOK,GAKR,OAHAtE,KAAK+D,OAAOE,IAAQM,KAAKD,KAAQtE,KAAK+D,OAAOE,GAAS,CAACK,IAGhD,KACLtE,KAAK+D,OAAOE,GAASjE,KAAK+D,OAAOE,IAAQO,QAAQL,GAAMG,IAAOH,GAAE,CAEnE,CAED,GAAAM,CAAIR,EAAOjC,GACThC,KAAK+D,OAAOE,GAASjE,KAAK+D,OAAOE,IAAQO,QAAQL,GAAMnC,IAAamC,GACrE,CAED,OAAAnB,GACEhD,KAAK+D,OAAS,CAAE,CACjB,EC1BH,MAAMW,EAAc,IAAM,EAEnB,MAAMC,cACX,WAAAlD,CAAYmD,GAASC,gBAAEA,EAAkB,EAACC,gBAAEA,EAAkB,IAC5D9E,KAAK4E,QAAUA,EACf5E,KAAK6E,gBAAkBA,EACvB7E,KAAK8E,gBAAkBA,EAEvB9E,KAAK+E,WAAa,CAChBzE,EAAG,KACHC,EAAG,MAGLP,KAAKgF,QAAU,IAAIlB,QACnBpB,OAAOC,iBAAiB,SAAU3C,KAAKiF,gBAAgB,GACvDjF,KAAKiF,iBAELjF,KAAK4E,QAAQjC,iBAAiB,QAAS3C,KAAKkF,QAAS,CAAEC,SAAS,IAChEnF,KAAK4E,QAAQjC,iBAAiB,aAAc3C,KAAKoF,aAAc,CAC7DD,SAAS,IAEXnF,KAAK4E,QAAQjC,iBAAiB,YAAa3C,KAAKqF,YAAa,CAC3DF,SAAS,IAEXnF,KAAK4E,QAAQjC,iBAAiB,WAAY3C,KAAKsF,WAAY,CACzDH,SAAS,GAEZ,CAGD,EAAAd,CAAGJ,EAAOjC,GACR,OAAOhC,KAAKgF,QAAQX,GAAGJ,EAAOjC,EAC/B,CAGD,OAAAgB,GACEhD,KAAKgF,QAAQhC,UAEbN,OAAOQ,oBAAoB,SAAUlD,KAAKiF,gBAAgB,GAE1DjF,KAAK4E,QAAQ1B,oBAAoB,QAASlD,KAAKkF,QAAS,CACtDC,SAAS,IAEXnF,KAAK4E,QAAQ1B,oBAAoB,aAAclD,KAAKoF,aAAc,CAChED,SAAS,IAEXnF,KAAK4E,QAAQ1B,oBAAoB,YAAalD,KAAKqF,YAAa,CAC9DF,SAAS,IAEXnF,KAAK4E,QAAQ1B,oBAAoB,WAAYlD,KAAKsF,WAAY,CAC5DH,SAAS,GAEZ,CAGDC,aAAgBnB,IACd,MAAMsB,QAAEA,EAAOC,QAAEA,GAAYvB,EAAMwB,cAC/BxB,EAAMwB,cAAc,GACpBxB,EAEJjE,KAAK+E,WAAWzE,EAAIiF,EACpBvF,KAAK+E,WAAWxE,EAAIiF,EAEpBxF,KAAK0F,UAAY,CACfpF,EAAG,EACHC,EAAG,GAGLP,KAAKgF,QAAQhB,KAAK,SAAU,CAC1B2B,OAAQ,EACRC,OAAQ,EACR3B,SACA,EAIJoB,YAAepB,IACb,MAAMsB,QAAEA,EAAOC,QAAEA,GAAYvB,EAAMwB,cAC/BxB,EAAMwB,cAAc,GACpBxB,EAEE0B,IAAWJ,EAAUvF,KAAK+E,WAAWzE,GAAKN,KAAK8E,gBAC/Cc,IAAWJ,EAAUxF,KAAK+E,WAAWxE,GAAKP,KAAK8E,gBAErD9E,KAAK+E,WAAWzE,EAAIiF,EACpBvF,KAAK+E,WAAWxE,EAAIiF,EAEpBxF,KAAK0F,UAAY,CACfpF,EAAGqF,EACHpF,EAAGqF,GAGL5F,KAAKgF,QAAQhB,KAAK,SAAU,CAC1B2B,SACAC,SACA3B,SACA,EAGJqB,WAAcrB,IACZjE,KAAKgF,QAAQhB,KAAK,SAAU,CAC1B2B,OAAQ3F,KAAK0F,UAAUpF,EACvBsF,OAAQ5F,KAAK0F,UAAUnF,EACvB0D,SACA,EAIJiB,QAAWjB,IACT,IAAI0B,OAAEA,EAAMC,OAAEA,EAAMC,UAAEA,GAAc5B,EAOpC0B,GAJgB,IAAdE,EAAkBnB,EAA4B,IAAdmB,EAAkB7F,KAAK8F,YAAc,EAKvEF,GAHgB,IAAdC,EAAkBnB,EAA4B,IAAdmB,EAAkB7F,KAAK+F,aAAe,EAKxEJ,GAAU3F,KAAK6E,gBACfe,GAAU5F,KAAK6E,gBAEf7E,KAAKgF,QAAQhB,KAAK,SAAU,CAAE2B,SAAQC,SAAQ3B,SAAQ,EAGxDgB,eAAiB,KACfjF,KAAK8F,YAAcpD,OAAOY,WAC1BtD,KAAK+F,aAAerD,OAAOc,WAAW,SCxF5B,MAAOwC,MAmBnB,WAAAvE,EAAYC,QACVA,EAAUgB,OAAMf,QAChBA,EAAUsE,SAASC,gBAAeC,kBAClCA,EAAoBzE,EAAO0E,aAC3BA,EAAeD,EAAiBE,YAChCA,GAAc,EAAIC,UAClBA,GAAY,EAAKC,cACjBA,EAAgB,KAAKC,uBACrBA,EAAyB,GAAExF,SAC3BA,EAAQE,OACRA,EAAS,CAACR,GAAMd,KAAKH,IAAI,EAAG,MAAQG,KAAK6G,IAAI,GAAI,GAAK/F,KAAGP,KACzDA,GAAQa,GAAY,GAAG0F,SACvBA,GAAW,EAAKC,YAChBA,EAAc,WAAUC,mBACxBA,EAAqB,WAAU9B,gBAC/BA,EAAkB,EAACD,gBACnBA,EAAkB,EAACjD,WACnBA,GAAa,EAAIiF,QACjBA,GAAU,EAAKC,gCACfA,GAAkC,GAClB,CAAA,GArClB9G,KAAA+G,eAA+C,EAC/C/G,KAAAgH,aAAuB,EACvBhH,KAAAiH,YAAsB,EAmIdjH,KAAekH,gBAAG,EAAGvB,SAAQC,SAAQ3B,YAE3C,GAAIA,EAAMkD,QAAS,OAEnB,MAAMC,EAAUnD,EAAMoD,KAAKC,SAAS,SAC9BC,EAAUtD,EAAMoD,KAAKC,SAAS,SAEpCtH,KAAKwH,WAA4B,eAAfvD,EAAMoD,MAAwC,cAAfpD,EAAMoD,KAkBvD,GANErH,KAAKyH,QAAQnB,WACbc,GACe,eAAfnD,EAAMoD,OACLrH,KAAK0H,YACL1H,KAAK2H,SAIN,YADA3H,KAAK4H,QAIP,MAAMC,EAAqB,IAAXlC,GAA2B,IAAXC,EAQ1BkC,EACiC,aAApC9H,KAAKyH,QAAQb,oBAAgD,IAAXhB,GACd,eAApC5F,KAAKyH,QAAQb,oBAAkD,IAAXjB,EAEvD,GAAIkC,GAAWC,EAEb,OAIF,IAAIC,EAAe9D,EAAM8D,eAGzB,GAFAA,EAAeA,EAAaC,MAAM,EAAGD,EAAaE,QAAQjI,KAAKkI,cAG3DH,EAAaI,MACZC,kBACC,OAAApI,KAAKyH,QAAQZ,QAAQuB,KACD,QAApBC,EAAAD,EAAKE,oBAAe,IAAAD,OAAA,EAAAA,EAAAE,KAAAH,EAAA,wBACnBhB,IAA+B,QAApBoB,EAAAJ,EAAKE,oBAAe,IAAAE,OAAA,EAAAA,EAAAD,KAAAH,EAAA,8BAC/Bb,IAA+B,QAApBkB,EAAAL,EAAKE,oBAAe,IAAAG,OAAA,EAAAA,EAAAF,KAAAH,EAAA,+BACf,UAAhBA,EAAKM,iBAAW,IAAAC,OAAA,EAAAA,EAAAC,SAAS,aACT,QAAdC,EAAAT,EAAKM,iBAAS,IAAAG,OAAA,EAAAA,EAAED,SAAS,iBAAiB,IAGjD,OAEF,GAAI5I,KAAK0H,WAAa1H,KAAK2H,SAEzB,YADA1D,EAAM6E,iBAQR,KAHG9I,KAAKyH,QAAQnB,WAAac,GAC1BpH,KAAKyH,QAAQpB,aAAekB,GAK7B,OAFAvH,KAAK+I,YAAc,cACnB/I,KAAKgJ,QAAQ5H,OAIf6C,EAAM6E,iBAEN,IAAIG,EAAQrD,EAC4B,SAApC5F,KAAKyH,QAAQb,mBACfqC,EAAQrJ,KAAKsJ,IAAItD,GAAUhG,KAAKsJ,IAAIvD,GAAUC,EAASD,EACV,eAApC3F,KAAKyH,QAAQb,qBACtBqC,EAAQtD,GAGV,MAAMW,EAAYc,GAAWpH,KAAKyH,QAAQnB,UAGpC6C,EAFa/B,GAA0B,aAAfnD,EAAMoD,MAEEzH,KAAKsJ,IAAID,GAAS,EAEpDE,IACFF,EAAQjJ,KAAKoJ,SAAWpJ,KAAKyH,QAAQjB,wBAGvCxG,KAAKqJ,SAASrJ,KAAKsJ,aAAeL,EAAKM,OAAAC,OAAA,CACrCC,cAAc,GACVnD,EACA,CACEnG,KAAMgJ,EAAkBnJ,KAAKyH,QAAQlB,cAAgB,GAEvD,CACEpG,KAAMH,KAAKyH,QAAQtH,KACnBa,SAAUhB,KAAKyH,QAAQzG,SACvBE,OAAQlB,KAAKyH,QAAQvG,SAE3B,EAaIlB,KAAc0J,eAAG,KAIvB,GAHApH,aAAatC,KAAK2J,+BACX3J,KAAK2J,uBAER3J,KAAK4J,sCACA5J,KAAK4J,oCAId,IAAyB,IAArB5J,KAAK+I,aAA8C,WAArB/I,KAAK+I,YAA0B,CAC/D,MAAMc,EAAa7J,KAAK8J,eACxB9J,KAAK8J,eAAiB9J,KAAKsJ,aAAetJ,KAAK+J,aAC/C/J,KAAKgK,aAAehK,KAAKoJ,SACzBpJ,KAAKoJ,SAAWpJ,KAAK8J,eAAiBD,EACtC7J,KAAKiK,UAAYrK,KAAKsK,KAAKlK,KAAK8J,eAAiBD,GAEjD7J,KAAK+I,cAAc/I,KAAKmK,aAAc,SACtCnK,KAAKgE,OAEiB,IAAlBhE,KAAKoJ,WACPpJ,KAAK2J,uBAAyBpH,YAAW,KACvCvC,KAAKgK,aAAehK,KAAKoJ,SACzBpJ,KAAKoJ,SAAW,EAChBpJ,KAAK+I,aAAc,EACnB/I,KAAKgE,MAAM,GACV,KAKN,GAtPDtB,OAAO0H,4BAGH1I,IAAYuE,SAASC,iBAAmBxE,IAAYuE,SAASoE,OAC/D3I,EAAUgB,QAGZ1C,KAAKyH,QAAU,CACb/F,UACAC,UACAwE,oBACAC,eACAC,cACAC,YACAC,gBACAC,yBACAxF,WACAE,SACAf,OACAuG,WACAE,qBACAD,cACA7B,kBACAD,kBACAjD,aACAiF,UACAC,mCAGF9G,KAAKgJ,QAAU,IAAInJ,QACnBG,KAAKgF,QAAU,IAAIlB,QACnB9D,KAAKsK,WAAa,IAAI9I,WAAW,CAAEE,UAASC,UAASC,eAErD5B,KAAKuK,kBAELvK,KAAKwK,SAAW,GAChBxK,KAAKyK,KAAO,EACZzK,KAAKoJ,SAAWpJ,KAAKgK,aAAe,EACpChK,KAAK2H,UAAW,EAChB3H,KAAK0H,WAAY,EAIjB1H,KAAK+I,aAAc,EACnB/I,KAAKsJ,aAAetJ,KAAK8J,eAAiB9J,KAAK+J,aAE/C/J,KAAKyH,QAAQ/F,QAAQiB,iBAAiB,SAAU3C,KAAK0J,gBAAgB,GAErE1J,KAAK0K,cAAgB,IAAI/F,cAAcyB,EAAc,CACnDtB,kBACAD,oBAEF7E,KAAK0K,cAAcrG,GAAG,SAAUrE,KAAKkH,gBACtC,CAED,OAAAlE,GACEhD,KAAKgF,QAAQhC,UAEbhD,KAAKyH,QAAQ/F,QAAQwB,oBACnB,SACAlD,KAAK0J,gBACL,GAGF1J,KAAK0K,cAAc1H,UACnBhD,KAAKsK,WAAWtH,UAEhBhD,KAAK2K,kBASN,CAED,EAAAtG,CAAGJ,EAAejC,GAChB,OAAOhC,KAAKgF,QAAQX,GAAGJ,EAAOjC,EAC/B,CAED,GAAAyC,CAAIR,EAAejC,GACjB,OAAOhC,KAAKgF,QAAQP,IAAIR,EAAOjC,EAChC,CAEO,SAAA4I,CAAUC,GAEZ7K,KAAK8K,aACP9K,KAAKkI,YAAY6C,WAAaF,EAE9B7K,KAAKkI,YAAY8C,UAAYH,CAEhC,CAiHD,MAAApI,GACEzC,KAAKsK,WAAW7H,QACjB,CAEO,IAAAuB,EAAKwG,SAAEA,EAAW,CAAE,GAAK,CAAA,GAC/BxK,KAAKwK,SAAWA,EAChBxK,KAAKgF,QAAQhB,KAAK,SAAUhE,MAC5BA,KAAKwK,SAAW,EACjB,CAmCO,KAAA5C,GACN5H,KAAK2H,UAAW,EAChB3H,KAAK+I,aAAc,EACnB/I,KAAK8J,eAAiB9J,KAAKsJ,aAAetJ,KAAK+J,aAC/C/J,KAAKgK,aAAehK,KAAKoJ,SAAW,EACpCpJ,KAAKgJ,QAAQ5H,MACd,CAED,KAAA6J,GACOjL,KAAK0H,YACV1H,KAAK0H,WAAY,EAEjB1H,KAAK4H,QACN,CAED,IAAAxG,GACMpB,KAAK0H,YACT1H,KAAK0H,WAAY,EACjB1H,KAAKgJ,QAAQ5H,OAEbpB,KAAK4H,QACN,CAED,GAAAsD,CAAIT,GACF,MAAM1K,EAAY0K,GAAQzK,KAAKyK,MAAQA,GACvCzK,KAAKyK,KAAOA,EAEZzK,KAAKgJ,QAAQlJ,QAAoB,KAAZC,EACtB,CAED,QAAAsJ,CACE8B,GACAC,OACEA,EAAS,EAACC,UACVA,GAAY,EAAKC,KACjBA,GAAO,EAAKtK,SACZA,EAAWhB,KAAKyH,QAAQzG,SAAQE,OAChCA,EAASlB,KAAKyH,QAAQvG,OAAMf,KAC5BA,GAAQa,GAAYhB,KAAKyH,QAAQtH,KAAIoB,QACrCA,EAAOgK,WACPA,EAAUC,MACVA,GAAQ,EAAK/B,aACbA,GAAe,EAAIe,SACnBA,EAAW,CAAA,GAaT,IAEJ,IAAKxK,KAAK0H,YAAa1H,KAAK2H,UAAc6D,EAA1C,CAGA,GAAI,CAAC,MAAO,OAAQ,SAASlE,SAAS6D,GACpCA,EAAS,OACJ,GAAI,CAAC,SAAU,QAAS,OAAO7D,SAAS6D,GAC7CA,EAASnL,KAAK6D,UACT,CACL,IAAIuE,EAUJ,GARsB,iBAAX+C,EAET/C,EAAOnC,SAASwF,cAAcN,IACrBA,aAAM,EAANA,EAAQO,YAEjBtD,EAAO+C,GAGL/C,EAAM,CACR,GAAIpI,KAAKyH,QAAQ/F,UAAYgB,OAAQ,CAEnC,MAAMiJ,EAAc3L,KAAKyH,QAAQ/F,QAAQkK,wBACzCR,GAAUpL,KAAK8K,aAAea,EAAYE,KAAOF,EAAYG,GAC9D,CAED,MAAMC,EAAO3D,EAAKwD,wBAElBT,GACGnL,KAAK8K,aAAeiB,EAAKF,KAAOE,EAAKD,KAAO9L,KAAK8J,cACrD,CACF,CAED,GAAsB,iBAAXqB,EAAX,CAaA,GAXAA,GAAUC,EACVD,EAASvL,KAAKiB,MAAMsK,GAEhBnL,KAAKyH,QAAQf,SACX+C,IACFzJ,KAAKsJ,aAAetJ,KAAK8J,eAAiB9J,KAAK6K,QAGjDM,EAAS3L,MAAM,EAAG2L,EAAQnL,KAAK6D,OAG7BwH,EAKF,OAJArL,KAAK8J,eAAiB9J,KAAKsJ,aAAe6B,EAC1CnL,KAAK4K,UAAU5K,KAAK6K,QACpB7K,KAAK4H,aACL2D,SAAAA,EAAavL,OAIXmL,IAAWnL,KAAKsJ,eAEfG,IACHzJ,KAAKsJ,aAAe6B,GAGtBnL,KAAKgJ,QAAQ1H,OAAOtB,KAAK8J,eAAgBqB,EAAQ,CAC/CnK,WACAE,SACAf,OACAoB,QAAS,KAEH+J,IAAMtL,KAAK2H,UAAW,GAC1B3H,KAAK+I,YAAc,SACnBxH,SAAAA,EAAUvB,KAAK,EAEjBqB,SAAU,CAACjB,EAAeF,KACxBF,KAAK+I,YAAc,SAGnB/I,KAAKgK,aAAehK,KAAKoJ,SACzBpJ,KAAKoJ,SAAWhJ,EAAQJ,KAAK8J,eAC7B9J,KAAKiK,UAAYrK,KAAKsK,KAAKlK,KAAKoJ,UAEhCpJ,KAAK8J,eAAiB1J,EACtBJ,KAAK4K,UAAU5K,KAAK6K,QAEhBpB,IAEFzJ,KAAKsJ,aAAelJ,GAGjBF,GAAWF,KAAKgE,KAAK,CAAEwG,aAExBtK,IACFF,KAAK4H,QACL5H,KAAKgE,KAAK,CAAEwG,aACZe,SAAAA,EAAavL,MAGbA,KAAK4J,gCAAiC,EAIvC,IAjEiC,CAhCiB,CAoGxD,CAED,eAAI1B,GACF,OAAOlI,KAAKyH,QAAQ/F,UAAYgB,OAC5BuD,SAASC,gBACTlG,KAAKyH,QAAQ/F,OAClB,CAED,SAAImC,GACF,OAAI7D,KAAKyH,QAAQX,gCACX9G,KAAK8K,aACA9K,KAAKkI,YAAYtE,YAAc5D,KAAKkI,YAAYzE,YAEhDzD,KAAKkI,YAAYvE,aAAe3D,KAAKkI,YAAYxE,aAGnD1D,KAAKsK,WAAWzG,MAAM7D,KAAK8K,aAAe,IAAM,IAE1D,CAED,gBAAIA,GACF,MAAoC,eAA7B9K,KAAKyH,QAAQd,WACrB,CAED,gBAAIoD,GAEF,OAAO/J,KAAK8K,aACR9K,KAAKkI,YAAY6C,WACjB/K,KAAKkI,YAAY8C,SACtB,CAED,UAAIH,GACF,OAAO7K,KAAKyH,QAAQf,SNlfjB,SAASsF,OAAOC,EAAGC,GACxB,OAASD,EAAIC,EAAKA,GAAKA,CACzB,CMifQF,CAAOhM,KAAK8J,eAAgB9J,KAAK6D,OACjC7D,KAAK8J,cACV,CAED,YAAIqC,GAEF,OAAsB,IAAfnM,KAAK6D,MAAc,EAAI7D,KAAK6K,OAAS7K,KAAK6D,KAClD,CAaD,eAAIkF,GACF,OAAO/I,KAAK+G,aACb,CAED,eAAYgC,CAAY3I,GAClBJ,KAAK+G,gBAAkB3G,IACzBJ,KAAK+G,cAAgB3G,EACrBJ,KAAKuK,kBAER,CAED,aAAI7C,GACF,OAAO1H,KAAKgH,WACb,CAED,aAAYU,CAAUtH,GAChBJ,KAAKgH,cAAgB5G,IACvBJ,KAAKgH,YAAc5G,EACnBJ,KAAKuK,kBAER,CAED,YAAI5C,GACF,OAAO3H,KAAKiH,UACb,CAED,YAAYU,CAASvH,GACfJ,KAAKiH,aAAe7G,IACtBJ,KAAKiH,WAAa7G,EAClBJ,KAAKuK,kBAER,CAED,YAAI6B,GACF,MAA4B,WAArBpM,KAAK+I,WACb,CAED,aAAIsD,GACF,IAAIA,EAAY,QAOhB,OANIrM,KAAK0H,YAAW2E,GAAa,kBAC7BrM,KAAK2H,WAAU0E,GAAa,iBAC5BrM,KAAK+I,cAAasD,GAAa,oBACV,WAArBrM,KAAK+I,cAA0BsD,GAAa,iBAGzCA,CACR,CAEO,eAAA9B,GACNvK,KAAK2K,mBAEL3K,KAAKkI,YAAYmE,UACf,GAAGrM,KAAKkI,YAAYmE,aAAarM,KAAKqM,YAAYC,MAErD,CAEO,gBAAA3B,GACN3K,KAAKkI,YAAYmE,UAAYrM,KAAKkI,YAAYmE,UAC3CE,QAAQ,gBAAiB,IACzBD,MACJ"} \ No newline at end of file +{"version":3,"file":"lenis.min.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 if (completed) {\r\n this.stop()\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\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 prevent?: boolean | ((node: Element) => 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 | 'native' | 'smooth' = 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 time: number\r\n userData: object\r\n lastVelocity: number\r\n velocity: number\r\n direction: 1 | -1 | undefined\r\n options: LenisOptions\r\n targetScroll: number\r\n animatedScroll: number\r\n // animate: Animate\r\n // emitter: Emitter\r\n // dimensions: Dimensions\r\n // virtualScroll: VirtualScroll\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 prevent = false,\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 prevent,\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 this.updateClassName()\r\n\r\n this.userData = {}\r\n this.time = 0\r\n this.velocity = this.lastVelocity = 0\r\n this.isLocked = false\r\n this.isStopped = false\r\n // this.hasScrolled = false\r\n // this.isSmooth = syncTouch || smoothWheel\r\n // this.isSmooth = false\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.cleanUpClassName()\r\n\r\n // this.rootElement.className = ''\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 this.isTouching = event.type === 'touchstart' || event.type === 'touchmove'\r\n // if (event.type === 'touchend') {\r\n // console.log('touchend', this.scroll)\r\n // // this.lastVelocity = this.velocity\r\n // // this.velocity = 0\r\n // // this.isScrolling = false\r\n // this.emit({ type: 'touchend' })\r\n // // alert('touchend')\r\n // return\r\n // }\r\n\r\n const isTapToStop =\r\n this.options.syncTouch &&\r\n isTouch &&\r\n event.type === 'touchstart' &&\r\n !this.isStopped &&\r\n !this.isLocked\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 this.options.prevent(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 const isSmooth =\r\n (this.options.syncTouch && isTouch) ||\r\n (this.options.smoothWheel && isWheel)\r\n\r\n if (!isSmooth) {\r\n this.isScrolling = 'native'\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({ userData = {} } = {}) {\r\n this.userData = userData\r\n this.emitter.emit('scroll', this)\r\n this.userData = {}\r\n }\r\n\r\n private onNativeScroll = () => {\r\n clearTimeout(this.__resetVelocityTimeout)\r\n delete this.__resetVelocityTimeout\r\n\r\n if (this.__preventNextNativeScrollEvent) {\r\n delete this.__preventNextNativeScrollEvent\r\n return\r\n }\r\n\r\n if (this.isScrolling === false || this.isScrolling === 'native') {\r\n const lastScroll = this.animatedScroll\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.lastVelocity = this.velocity\r\n this.velocity = this.animatedScroll - lastScroll\r\n this.direction = Math.sign(this.animatedScroll - lastScroll)\r\n // this.isSmooth = false\r\n this.isScrolling = this.hasScrolled ? 'native' : false\r\n this.emit()\r\n\r\n if (this.velocity !== 0) {\r\n this.__resetVelocityTimeout = setTimeout(() => {\r\n this.lastVelocity = this.velocity\r\n this.velocity = 0\r\n this.isScrolling = false\r\n this.emit()\r\n }, 400)\r\n }\r\n\r\n // this.hasScrolled = true\r\n // }, 50)\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.lastVelocity = 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 onStart,\r\n onComplete,\r\n force = false, // scroll even if stopped\r\n programmatic = true, // called from outside of the class\r\n userData = {},\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 onStart?: (lenis: Lenis) => void\r\n onComplete?: (lenis: Lenis) => void\r\n force?: boolean\r\n programmatic?: boolean\r\n userData?: object\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 (target === this.targetScroll) return\r\n\r\n if (!programmatic) {\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 = 'smooth'\r\n onStart?.(this)\r\n },\r\n onUpdate: (value: number, completed: boolean) => {\r\n this.isScrolling = 'smooth'\r\n\r\n // updated\r\n this.lastVelocity = this.velocity\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({ userData })\r\n\r\n if (completed) {\r\n this.reset()\r\n this.emit({ userData })\r\n onComplete?.(this)\r\n\r\n // avoid emitting event twice\r\n this.__preventNextNativeScrollEvent = true\r\n // requestAnimationFrame(() => {\r\n // delete this.__preventNextNativeScrollEvent\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(): number {\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(): number {\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(): number {\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.updateClassName()\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.updateClassName()\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.updateClassName()\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.updateClassName()\r\n }\r\n }\r\n\r\n get isSmooth() {\r\n return this.isScrolling === 'smooth'\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.isScrolling === 'smooth') className += ' lenis-smooth'\r\n // if (this.isScrolling === 'native') className += ' lenis-native'\r\n // if (this.isSmooth) className += ' lenis-smooth'\r\n return className\r\n }\r\n\r\n private updateClassName() {\r\n this.cleanUpClassName()\r\n\r\n this.rootElement.className =\r\n `${this.rootElement.className} ${this.className}`.trim()\r\n // this.emitter.emit('className change', this)\r\n }\r\n\r\n private cleanUpClassName() {\r\n this.rootElement.className = this.rootElement.className\r\n .replace(/lenis(-\\w+)?/g, '')\r\n .trim()\r\n }\r\n\r\n // private toggleClassName(name: string, value: boolean) {\r\n // // this.rootElement.classList.toggle(name, value)\r\n // this.rootElement.className = this.className\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","damp","x","y","lambda","dt","t","exp","to","round","currentTime","linearProgress","duration","easedProgress","easing","from","stop","onUpdate","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","prevent","__experimental__naiveDimensions","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","isTouching","options","isStopped","isLocked","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","preventDefault","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__resetVelocityTimeout","__preventNextNativeScrollEvent","lastScroll","animatedScroll","actualScroll","lastVelocity","direction","sign","hasScrolled","lenisVersion","body","dimensions","updateClassName","userData","time","virtualScroll","cleanUpClassName","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","modulo","n","d","progress","isSmooth","className","trim","replace"],"mappings":"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"} \ No newline at end of file diff --git a/dist/lenis.mjs b/dist/lenis.mjs index 6ecf22e2..d6430de4 100644 --- a/dist/lenis.mjs +++ b/dist/lenis.mjs @@ -1,2 +1,2 @@ -function clamp(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(t){if(!this.isRunning)return;let e=!1;if(this.lerp)this.value=function damp(t,e,i,s){return function lerp(t,e,i){return(1-i)*t+i*e}(t,e,1-Math.exp(-i*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0);else{this.currentTime+=t;const i=clamp(0,this.currentTime/this.duration,1);e=i>=1;const s=e?1:this.easing(i);this.value=this.from+(this.to-this.from)*s}e&&this.stop(),this.onUpdate?.(this.value,e)}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 debounce(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 t=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=e=>{let{deltaX:i,deltaY:s,deltaMode:o}=e;i*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:e})};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:u=!1,orientation:d="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:S=!1,__experimental__naiveDimensions:w=!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");this.isTouching="touchstart"===i.type||"touchmove"===i.type;if(this.options.syncTouch&&s&&"touchstart"===i.type&&!this.isStopped&&!this.isLocked)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 this.options.prevent(t)||(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.options.syncTouch&&s||this.options.smoothWheel&&o))return this.isScrolling="native",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(clearTimeout(this.__resetVelocityTimeout),delete this.__resetVelocityTimeout,this.__preventNextNativeScrollEvent)delete this.__preventNextNativeScrollEvent;else if(!1===this.isScrolling||"native"===this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=this.velocity,this.velocity=this.animatedScroll-t,this.direction=Math.sign(this.animatedScroll-t),this.isScrolling=!!this.hasScrolled&&"native",this.emit(),0!==this.velocity&&(this.__resetVelocityTimeout=setTimeout((()=>{this.lastVelocity=this.velocity,this.velocity=0,this.isScrolling=!1,this.emit()}),400))}},window.lenisVersion="1.0.46-dev.0",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:u,gestureOrientation:p,orientation:d,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:S,__experimental__naiveDimensions:w},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:g}),this.updateClassName(),this.userData={},this.time=0,this.velocity=this.lastVelocity=0,this.isLocked=!1,this.isStopped=!1,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.cleanUpClassName()}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({userData:t={}}={}){this.userData=t,this.emitter.emit("scroll",this),this.userData={}}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=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(t,{offset:e=0,immediate:i=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:r=!o&&this.options.lerp,onStart:l,onComplete:h,force:a=!1,programmatic:c=!0,userData:u={}}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(t))t=0;else if(["bottom","right","end"].includes(t))t=this.limit;else{let i;if("string"==typeof t?i=document.querySelector(t):(null==t?void 0:t.nodeType)&&(i=t),i){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();e-=this.isHorizontal?t.left:t.top}const s=i.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t){if(t+=e,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),i)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));t!==this.targetScroll&&(c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:r,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==l||l(this)},onUpdate:(t,e)=>{this.isScrolling="smooth",this.lastVelocity=this.velocity,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({userData:u}),e&&(this.reset(),this.emit({userData:u}),null==h||h(this),this.__preventNextNativeScrollEvent=!0)}}))}}}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?function modulo(t,e){return(t%e+e)%e}(this.animatedScroll,this.limit):this.animatedScroll}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.updateClassName())}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.updateClassName())}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.updateClassName())}get isSmooth(){return"smooth"===this.isScrolling}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),"smooth"===this.isScrolling&&(t+=" lenis-smooth"),t}updateClassName(){this.cleanUpClassName(),this.rootElement.className=`${this.rootElement.className} ${this.className}`.trim()}cleanUpClassName(){this.rootElement.className=this.rootElement.className.replace(/lenis(-\w+)?/g,"").trim()}}export{Lenis as default}; +function clamp(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(t){if(!this.isRunning)return;let e=!1;if(this.lerp)this.value=function damp(t,e,i,s){return function lerp(t,e,i){return(1-i)*t+i*e}(t,e,1-Math.exp(-i*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0);else{this.currentTime+=t;const i=clamp(0,this.currentTime/this.duration,1);e=i>=1;const s=e?1:this.easing(i);this.value=this.from+(this.to-this.from)*s}e&&this.stop(),this.onUpdate?.(this.value,e)}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 debounce(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 t=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=e=>{let{deltaX:i,deltaY:s,deltaMode:o}=e;i*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:i,deltaY:s,event:e})};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:u=!1,orientation:d="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:S=!1,__experimental__naiveDimensions:w=!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");this.isTouching="touchstart"===i.type||"touchmove"===i.type;if(this.options.syncTouch&&s&&"touchstart"===i.type&&!this.isStopped&&!this.isLocked)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 this.options.prevent(t)||(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.options.syncTouch&&s||this.options.smoothWheel&&o))return this.isScrolling="native",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(clearTimeout(this.__resetVelocityTimeout),delete this.__resetVelocityTimeout,this.__preventNextNativeScrollEvent)delete this.__preventNextNativeScrollEvent;else if(!1===this.isScrolling||"native"===this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=this.velocity,this.velocity=this.animatedScroll-t,this.direction=Math.sign(this.animatedScroll-t),this.isScrolling=!!this.hasScrolled&&"native",this.emit(),0!==this.velocity&&(this.__resetVelocityTimeout=setTimeout((()=>{this.lastVelocity=this.velocity,this.velocity=0,this.isScrolling=!1,this.emit()}),400))}},window.lenisVersion="1.1.0",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:u,gestureOrientation:p,orientation:d,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:S,__experimental__naiveDimensions:w},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:g}),this.updateClassName(),this.userData={},this.time=0,this.velocity=this.lastVelocity=0,this.isLocked=!1,this.isStopped=!1,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.cleanUpClassName()}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({userData:t={}}={}){this.userData=t,this.emitter.emit("scroll",this),this.userData={}}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.lastVelocity=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(t,{offset:e=0,immediate:i=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:r=!o&&this.options.lerp,onStart:l,onComplete:h,force:a=!1,programmatic:c=!0,userData:u={}}={}){if(!this.isStopped&&!this.isLocked||a){if(["top","left","start"].includes(t))t=0;else if(["bottom","right","end"].includes(t))t=this.limit;else{let i;if("string"==typeof t?i=document.querySelector(t):(null==t?void 0:t.nodeType)&&(i=t),i){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();e-=this.isHorizontal?t.left:t.top}const s=i.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t){if(t+=e,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),i)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));t!==this.targetScroll&&(c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:r,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==l||l(this)},onUpdate:(t,e)=>{this.isScrolling="smooth",this.lastVelocity=this.velocity,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({userData:u}),e&&(this.reset(),this.emit({userData:u}),null==h||h(this),this.__preventNextNativeScrollEvent=!0)}}))}}}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?function modulo(t,e){return(t%e+e)%e}(this.animatedScroll,this.limit):this.animatedScroll}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.updateClassName())}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.updateClassName())}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.updateClassName())}get isSmooth(){return"smooth"===this.isScrolling}get className(){let t="lenis";return this.isStopped&&(t+=" lenis-stopped"),this.isLocked&&(t+=" lenis-locked"),this.isScrolling&&(t+=" lenis-scrolling"),"smooth"===this.isScrolling&&(t+=" lenis-smooth"),t}updateClassName(){this.cleanUpClassName(),this.rootElement.className=`${this.rootElement.className} ${this.className}`.trim()}cleanUpClassName(){this.rootElement.className=this.rootElement.className.replace(/lenis(-\w+)?/g,"").trim()}}export{Lenis as default}; //# sourceMappingURL=lenis.mjs.map diff --git a/dist/lenis.mjs.map b/dist/lenis.mjs.map index 9c4dab7b..fedf6fd9 100644 --- a/dist/lenis.mjs.map +++ b/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\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 if (completed) {\r\n this.stop()\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\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 prevent?: boolean | ((node: Element) => 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 | 'native' | 'smooth' = 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 time: number\r\n userData: object\r\n lastVelocity: number\r\n velocity: number\r\n direction: 1 | -1 | undefined\r\n options: LenisOptions\r\n targetScroll: number\r\n animatedScroll: number\r\n // animate: Animate\r\n // emitter: Emitter\r\n // dimensions: Dimensions\r\n // virtualScroll: VirtualScroll\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 prevent = false,\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 prevent,\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 this.updateClassName()\r\n\r\n this.userData = {}\r\n this.time = 0\r\n this.velocity = this.lastVelocity = 0\r\n this.isLocked = false\r\n this.isStopped = false\r\n // this.hasScrolled = false\r\n // this.isSmooth = syncTouch || smoothWheel\r\n // this.isSmooth = false\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.cleanUpClassName()\r\n\r\n // this.rootElement.className = ''\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 this.isTouching = event.type === 'touchstart' || event.type === 'touchmove'\r\n // if (event.type === 'touchend') {\r\n // console.log('touchend', this.scroll)\r\n // // this.lastVelocity = this.velocity\r\n // // this.velocity = 0\r\n // // this.isScrolling = false\r\n // this.emit({ type: 'touchend' })\r\n // // alert('touchend')\r\n // return\r\n // }\r\n\r\n const isTapToStop =\r\n this.options.syncTouch &&\r\n isTouch &&\r\n event.type === 'touchstart' &&\r\n !this.isStopped &&\r\n !this.isLocked\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 this.options.prevent(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 const isSmooth =\r\n (this.options.syncTouch && isTouch) ||\r\n (this.options.smoothWheel && isWheel)\r\n\r\n if (!isSmooth) {\r\n this.isScrolling = 'native'\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({ userData = {} } = {}) {\r\n this.userData = userData\r\n this.emitter.emit('scroll', this)\r\n this.userData = {}\r\n }\r\n\r\n private onNativeScroll = () => {\r\n clearTimeout(this.__resetVelocityTimeout)\r\n delete this.__resetVelocityTimeout\r\n\r\n if (this.__preventNextNativeScrollEvent) {\r\n delete this.__preventNextNativeScrollEvent\r\n return\r\n }\r\n\r\n if (this.isScrolling === false || this.isScrolling === 'native') {\r\n const lastScroll = this.animatedScroll\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.lastVelocity = this.velocity\r\n this.velocity = this.animatedScroll - lastScroll\r\n this.direction = Math.sign(this.animatedScroll - lastScroll)\r\n // this.isSmooth = false\r\n this.isScrolling = this.hasScrolled ? 'native' : false\r\n this.emit()\r\n\r\n if (this.velocity !== 0) {\r\n this.__resetVelocityTimeout = setTimeout(() => {\r\n this.lastVelocity = this.velocity\r\n this.velocity = 0\r\n this.isScrolling = false\r\n this.emit()\r\n }, 400)\r\n }\r\n\r\n // this.hasScrolled = true\r\n // }, 50)\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.lastVelocity = 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 onStart,\r\n onComplete,\r\n force = false, // scroll even if stopped\r\n programmatic = true, // called from outside of the class\r\n userData = {},\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 onStart?: (lenis: Lenis) => void\r\n onComplete?: (lenis: Lenis) => void\r\n force?: boolean\r\n programmatic?: boolean\r\n userData?: object\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 (target === this.targetScroll) return\r\n\r\n if (!programmatic) {\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 = 'smooth'\r\n onStart?.(this)\r\n },\r\n onUpdate: (value: number, completed: boolean) => {\r\n this.isScrolling = 'smooth'\r\n\r\n // updated\r\n this.lastVelocity = this.velocity\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({ userData })\r\n\r\n if (completed) {\r\n this.reset()\r\n this.emit({ userData })\r\n onComplete?.(this)\r\n\r\n // avoid emitting event twice\r\n this.__preventNextNativeScrollEvent = true\r\n // requestAnimationFrame(() => {\r\n // delete this.__preventNextNativeScrollEvent\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(): number {\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(): number {\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(): number {\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.updateClassName()\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.updateClassName()\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.updateClassName()\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.updateClassName()\r\n }\r\n }\r\n\r\n get isSmooth() {\r\n return this.isScrolling === 'smooth'\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.isScrolling === 'smooth') className += ' lenis-smooth'\r\n // if (this.isScrolling === 'native') className += ' lenis-native'\r\n // if (this.isSmooth) className += ' lenis-smooth'\r\n return className\r\n }\r\n\r\n private updateClassName() {\r\n this.cleanUpClassName()\r\n\r\n this.rootElement.className =\r\n `${this.rootElement.className} ${this.className}`.trim()\r\n // this.emitter.emit('className change', this)\r\n }\r\n\r\n private cleanUpClassName() {\r\n this.rootElement.className = this.rootElement.className\r\n .replace(/lenis(-\\w+)?/g, '')\r\n .trim()\r\n }\r\n\r\n // private toggleClassName(name: string, value: boolean) {\r\n // // this.rootElement.classList.toggle(name, value)\r\n // this.rootElement.className = this.className\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","damp","x","y","lambda","dt","t","exp","to","round","currentTime","linearProgress","duration","easedProgress","easing","from","stop","onUpdate","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","prevent","__experimental__naiveDimensions","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","isTouching","options","isStopped","isLocked","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","preventDefault","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__resetVelocityTimeout","__preventNextNativeScrollEvent","lastScroll","animatedScroll","actualScroll","lastVelocity","direction","sign","hasScrolled","lenisVersion","body","dimensions","updateClassName","userData","time","virtualScroll","cleanUpClassName","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","modulo","n","d","progress","isSmooth","className","trim","replace"],"mappings":"AACO,SAASA,MAAMC,EAAKC,EAAOC,GAChC,OAAOC,KAAKD,IAAIF,EAAKG,KAAKH,IAAIC,EAAOC,GACvC,CCAO,MAAME,QAEX,OAAAC,CAAQC,GACN,IAAKC,KAAKC,UAAW,OAErB,IAAIC,GAAY,EAEhB,GAAIF,KAAKG,KACPH,KAAKI,MDKJ,SAASC,KAAKC,EAAGC,EAAGC,EAAQC,GACjC,OANK,SAASN,KAAKG,EAAGC,EAAGG,GACzB,OAAQ,EAAIA,GAAKJ,EAAII,EAAIH,CAC3B,CAISJ,CAAKG,EAAGC,EAAG,EAAIX,KAAKe,KAAKH,EAASC,GAC3C,CCPmBJ,CAAKL,KAAKI,MAAOJ,KAAKY,GAAgB,GAAZZ,KAAKG,KAAWJ,GACnDH,KAAKiB,MAAMb,KAAKI,SAAWJ,KAAKY,KAClCZ,KAAKI,MAAQJ,KAAKY,GAClBV,GAAY,OAET,CACLF,KAAKc,aAAef,EACpB,MAAMgB,EAAiBvB,MAAM,EAAGQ,KAAKc,YAAcd,KAAKgB,SAAU,GAElEd,EAAYa,GAAkB,EAC9B,MAAME,EAAgBf,EAAY,EAAIF,KAAKkB,OAAOH,GAClDf,KAAKI,MAAQJ,KAAKmB,MAAQnB,KAAKY,GAAKZ,KAAKmB,MAAQF,CAClD,CAEGf,GACFF,KAAKoB,OAIPpB,KAAKqB,WAAWrB,KAAKI,MAAOF,EAC7B,CAGD,IAAAkB,GACEpB,KAAKC,WAAY,CAClB,CAID,MAAAqB,CACEH,EACAP,GACAT,KAAEA,EAAO,GAAGa,SAAEA,EAAW,EAACE,OAAEA,EAAS,CAACR,GAAMA,GAACa,QAAEA,EAAOF,SAAEA,IAExDrB,KAAKmB,KAAOnB,KAAKI,MAAQe,EACzBnB,KAAKY,GAAKA,EACVZ,KAAKG,KAAOA,EACZH,KAAKgB,SAAWA,EAChBhB,KAAKkB,OAASA,EACdlB,KAAKc,YAAc,EACnBd,KAAKC,WAAY,EAEjBsB,MACAvB,KAAKqB,SAAWA,CACjB,ECrDI,MAAMG,WACX,WAAAC,EAAYC,QACVA,EAAOC,QACPA,EAAOC,WACPA,GAAa,EACbC,SAAUC,EAAgB,KACxB,IACF9B,KAAK0B,QAAUA,EACf1B,KAAK2B,QAAUA,EAEXC,IACF5B,KAAK+B,gBCbJ,SAASF,SAASG,EAAUC,GACjC,IAAIC,EACJ,OAAO,WACL,IAAIC,EAAOC,UACPC,EAAUrC,KACdsC,aAAaJ,GACbA,EAAQK,YAAW,WACjBP,EAASQ,MAAMH,EAASF,EACzB,GAAEF,EACJ,CACH,CDG6BJ,CAAS7B,KAAKyC,OAAQX,GAEzC9B,KAAK0B,UAAYgB,OACnBA,OAAOC,iBAAiB,SAAU3C,KAAK+B,iBAAiB,IAExD/B,KAAK4C,sBAAwB,IAAIC,eAAe7C,KAAK+B,iBACrD/B,KAAK4C,sBAAsBE,QAAQ9C,KAAK0B,UAG1C1B,KAAK+C,sBAAwB,IAAIF,eAAe7C,KAAK+B,iBACrD/B,KAAK+C,sBAAsBD,QAAQ9C,KAAK2B,UAG1C3B,KAAKyC,QACN,CAED,OAAAO,GACEhD,KAAK4C,uBAAuBK,aAC5BjD,KAAK+C,uBAAuBE,aAC5BP,OAAOQ,oBAAoB,SAAUlD,KAAK+B,iBAAiB,EAC5D,CAEDU,OAAS,KACPzC,KAAKmD,kBACLnD,KAAKoD,iBAAiB,EAGxBD,gBAAkB,KACZnD,KAAK0B,UAAYgB,QACnB1C,KAAKqD,MAAQX,OAAOY,WACpBtD,KAAKuD,OAASb,OAAOc,cAErBxD,KAAKqD,MAAQrD,KAAK0B,QAAQ+B,YAC1BzD,KAAKuD,OAASvD,KAAK0B,QAAQgC,aAC5B,EAGHN,gBAAkB,KACZpD,KAAK0B,UAAYgB,QACnB1C,KAAK2D,aAAe3D,KAAK2B,QAAQgC,aACjC3D,KAAK4D,YAAc5D,KAAK2B,QAAQiC,cAEhC5D,KAAK2D,aAAe3D,KAAK0B,QAAQiC,aACjC3D,KAAK4D,YAAc5D,KAAK0B,QAAQkC,YACjC,EAGH,SAAIC,GACF,MAAO,CACLvD,EAAGN,KAAK4D,YAAc5D,KAAKqD,MAC3B9C,EAAGP,KAAK2D,aAAe3D,KAAKuD,OAE/B,EEjEI,MAAMO,QACX,WAAArC,GACEzB,KAAK+D,OAAS,CAAE,CACjB,CAED,IAAAC,CAAKC,KAAU9B,GACb,IAAI+B,EAAYlE,KAAK+D,OAAOE,IAAU,GACtC,IAAK,IAAIE,EAAI,EAAGC,EAASF,EAAUE,OAAQD,EAAIC,EAAQD,IACrDD,EAAUC,MAAMhC,EAEnB,CAED,EAAAkC,CAAGJ,EAAOK,GAKR,OAHAtE,KAAK+D,OAAOE,IAAQM,KAAKD,KAAQtE,KAAK+D,OAAOE,GAAS,CAACK,IAGhD,KACLtE,KAAK+D,OAAOE,GAASjE,KAAK+D,OAAOE,IAAQO,QAAQL,GAAMG,IAAOH,GAAE,CAEnE,CAED,GAAAM,CAAIR,EAAOjC,GACThC,KAAK+D,OAAOE,GAASjE,KAAK+D,OAAOE,IAAQO,QAAQL,GAAMnC,IAAamC,GACrE,CAED,OAAAnB,GACEhD,KAAK+D,OAAS,CAAE,CACjB,EC1BH,MAAMW,EAAc,IAAM,EAEnB,MAAMC,cACX,WAAAlD,CAAYmD,GAASC,gBAAEA,EAAkB,EAACC,gBAAEA,EAAkB,IAC5D9E,KAAK4E,QAAUA,EACf5E,KAAK6E,gBAAkBA,EACvB7E,KAAK8E,gBAAkBA,EAEvB9E,KAAK+E,WAAa,CAChBzE,EAAG,KACHC,EAAG,MAGLP,KAAKgF,QAAU,IAAIlB,QACnBpB,OAAOC,iBAAiB,SAAU3C,KAAKiF,gBAAgB,GACvDjF,KAAKiF,iBAELjF,KAAK4E,QAAQjC,iBAAiB,QAAS3C,KAAKkF,QAAS,CAAEC,SAAS,IAChEnF,KAAK4E,QAAQjC,iBAAiB,aAAc3C,KAAKoF,aAAc,CAC7DD,SAAS,IAEXnF,KAAK4E,QAAQjC,iBAAiB,YAAa3C,KAAKqF,YAAa,CAC3DF,SAAS,IAEXnF,KAAK4E,QAAQjC,iBAAiB,WAAY3C,KAAKsF,WAAY,CACzDH,SAAS,GAEZ,CAGD,EAAAd,CAAGJ,EAAOjC,GACR,OAAOhC,KAAKgF,QAAQX,GAAGJ,EAAOjC,EAC/B,CAGD,OAAAgB,GACEhD,KAAKgF,QAAQhC,UAEbN,OAAOQ,oBAAoB,SAAUlD,KAAKiF,gBAAgB,GAE1DjF,KAAK4E,QAAQ1B,oBAAoB,QAASlD,KAAKkF,QAAS,CACtDC,SAAS,IAEXnF,KAAK4E,QAAQ1B,oBAAoB,aAAclD,KAAKoF,aAAc,CAChED,SAAS,IAEXnF,KAAK4E,QAAQ1B,oBAAoB,YAAalD,KAAKqF,YAAa,CAC9DF,SAAS,IAEXnF,KAAK4E,QAAQ1B,oBAAoB,WAAYlD,KAAKsF,WAAY,CAC5DH,SAAS,GAEZ,CAGDC,aAAgBnB,IACd,MAAMsB,QAAEA,EAAOC,QAAEA,GAAYvB,EAAMwB,cAC/BxB,EAAMwB,cAAc,GACpBxB,EAEJjE,KAAK+E,WAAWzE,EAAIiF,EACpBvF,KAAK+E,WAAWxE,EAAIiF,EAEpBxF,KAAK0F,UAAY,CACfpF,EAAG,EACHC,EAAG,GAGLP,KAAKgF,QAAQhB,KAAK,SAAU,CAC1B2B,OAAQ,EACRC,OAAQ,EACR3B,SACA,EAIJoB,YAAepB,IACb,MAAMsB,QAAEA,EAAOC,QAAEA,GAAYvB,EAAMwB,cAC/BxB,EAAMwB,cAAc,GACpBxB,EAEE0B,IAAWJ,EAAUvF,KAAK+E,WAAWzE,GAAKN,KAAK8E,gBAC/Cc,IAAWJ,EAAUxF,KAAK+E,WAAWxE,GAAKP,KAAK8E,gBAErD9E,KAAK+E,WAAWzE,EAAIiF,EACpBvF,KAAK+E,WAAWxE,EAAIiF,EAEpBxF,KAAK0F,UAAY,CACfpF,EAAGqF,EACHpF,EAAGqF,GAGL5F,KAAKgF,QAAQhB,KAAK,SAAU,CAC1B2B,SACAC,SACA3B,SACA,EAGJqB,WAAcrB,IACZjE,KAAKgF,QAAQhB,KAAK,SAAU,CAC1B2B,OAAQ3F,KAAK0F,UAAUpF,EACvBsF,OAAQ5F,KAAK0F,UAAUnF,EACvB0D,SACA,EAIJiB,QAAWjB,IACT,IAAI0B,OAAEA,EAAMC,OAAEA,EAAMC,UAAEA,GAAc5B,EAOpC0B,GAJgB,IAAdE,EAAkBnB,EAA4B,IAAdmB,EAAkB7F,KAAK8F,YAAc,EAKvEF,GAHgB,IAAdC,EAAkBnB,EAA4B,IAAdmB,EAAkB7F,KAAK+F,aAAe,EAKxEJ,GAAU3F,KAAK6E,gBACfe,GAAU5F,KAAK6E,gBAEf7E,KAAKgF,QAAQhB,KAAK,SAAU,CAAE2B,SAAQC,SAAQ3B,SAAQ,EAGxDgB,eAAiB,KACfjF,KAAK8F,YAAcpD,OAAOY,WAC1BtD,KAAK+F,aAAerD,OAAOc,WAAW,ECxF5B,MAAOwC,MAmBnB,WAAAvE,EAAYC,QACVA,EAAUgB,OAAMf,QAChBA,EAAUsE,SAASC,gBAAeC,kBAClCA,EAAoBzE,EAAO0E,aAC3BA,EAAeD,EAAiBE,YAChCA,GAAc,EAAIC,UAClBA,GAAY,EAAKC,cACjBA,EAAgB,KAAKC,uBACrBA,EAAyB,GAAExF,SAC3BA,EAAQE,OACRA,EAAS,CAACR,GAAMd,KAAKH,IAAI,EAAG,MAAQG,KAAK6G,IAAI,GAAI,GAAK/F,KAAGP,KACzDA,GAAQa,GAAY,GAAG0F,SACvBA,GAAW,EAAKC,YAChBA,EAAc,WAAUC,mBACxBA,EAAqB,WAAU9B,gBAC/BA,EAAkB,EAACD,gBACnBA,EAAkB,EAACjD,WACnBA,GAAa,EAAIiF,QACjBA,GAAU,EAAKC,gCACfA,GAAkC,GAClB,CAAA,GArClB9G,KAAA+G,eAA+C,EAC/C/G,KAAAgH,aAAuB,EACvBhH,KAAAiH,YAAsB,EAmIdjH,KAAekH,gBAAG,EAAGvB,SAAQC,SAAQ3B,YAE3C,GAAIA,EAAMkD,QAAS,OAEnB,MAAMC,EAAUnD,EAAMoD,KAAKC,SAAS,SAC9BC,EAAUtD,EAAMoD,KAAKC,SAAS,SAEpCtH,KAAKwH,WAA4B,eAAfvD,EAAMoD,MAAwC,cAAfpD,EAAMoD,KAkBvD,GANErH,KAAKyH,QAAQnB,WACbc,GACe,eAAfnD,EAAMoD,OACLrH,KAAK0H,YACL1H,KAAK2H,SAIN,YADA3H,KAAK4H,QAIP,MAAMC,EAAqB,IAAXlC,GAA2B,IAAXC,EAQ1BkC,EACiC,aAApC9H,KAAKyH,QAAQb,oBAAgD,IAAXhB,GACd,eAApC5F,KAAKyH,QAAQb,oBAAkD,IAAXjB,EAEvD,GAAIkC,GAAWC,EAEb,OAIF,IAAIC,EAAe9D,EAAM8D,eAGzB,GAFAA,EAAeA,EAAaC,MAAM,EAAGD,EAAaE,QAAQjI,KAAKkI,cAG3DH,EAAaI,MACZC,kBACC,OAAApI,KAAKyH,QAAQZ,QAAQuB,KACD,QAApBC,EAAAD,EAAKE,oBAAe,IAAAD,OAAA,EAAAA,EAAAE,KAAAH,EAAA,wBACnBhB,IAA+B,QAApBoB,EAAAJ,EAAKE,oBAAe,IAAAE,OAAA,EAAAA,EAAAD,KAAAH,EAAA,8BAC/Bb,IAA+B,QAApBkB,EAAAL,EAAKE,oBAAe,IAAAG,OAAA,EAAAA,EAAAF,KAAAH,EAAA,+BACf,UAAhBA,EAAKM,iBAAW,IAAAC,OAAA,EAAAA,EAAAC,SAAS,aACT,QAAdC,EAAAT,EAAKM,iBAAS,IAAAG,OAAA,EAAAA,EAAED,SAAS,iBAAiB,IAGjD,OAEF,GAAI5I,KAAK0H,WAAa1H,KAAK2H,SAEzB,YADA1D,EAAM6E,iBAQR,KAHG9I,KAAKyH,QAAQnB,WAAac,GAC1BpH,KAAKyH,QAAQpB,aAAekB,GAK7B,OAFAvH,KAAK+I,YAAc,cACnB/I,KAAKgJ,QAAQ5H,OAIf6C,EAAM6E,iBAEN,IAAIG,EAAQrD,EAC4B,SAApC5F,KAAKyH,QAAQb,mBACfqC,EAAQrJ,KAAKsJ,IAAItD,GAAUhG,KAAKsJ,IAAIvD,GAAUC,EAASD,EACV,eAApC3F,KAAKyH,QAAQb,qBACtBqC,EAAQtD,GAGV,MAAMW,EAAYc,GAAWpH,KAAKyH,QAAQnB,UAGpC6C,EAFa/B,GAA0B,aAAfnD,EAAMoD,MAEEzH,KAAKsJ,IAAID,GAAS,EAEpDE,IACFF,EAAQjJ,KAAKoJ,SAAWpJ,KAAKyH,QAAQjB,wBAGvCxG,KAAKqJ,SAASrJ,KAAKsJ,aAAeL,EAAKM,OAAAC,OAAA,CACrCC,cAAc,GACVnD,EACA,CACEnG,KAAMgJ,EAAkBnJ,KAAKyH,QAAQlB,cAAgB,GAEvD,CACEpG,KAAMH,KAAKyH,QAAQtH,KACnBa,SAAUhB,KAAKyH,QAAQzG,SACvBE,OAAQlB,KAAKyH,QAAQvG,SAE3B,EAaIlB,KAAc0J,eAAG,KAIvB,GAHApH,aAAatC,KAAK2J,+BACX3J,KAAK2J,uBAER3J,KAAK4J,sCACA5J,KAAK4J,oCAId,IAAyB,IAArB5J,KAAK+I,aAA8C,WAArB/I,KAAK+I,YAA0B,CAC/D,MAAMc,EAAa7J,KAAK8J,eACxB9J,KAAK8J,eAAiB9J,KAAKsJ,aAAetJ,KAAK+J,aAC/C/J,KAAKgK,aAAehK,KAAKoJ,SACzBpJ,KAAKoJ,SAAWpJ,KAAK8J,eAAiBD,EACtC7J,KAAKiK,UAAYrK,KAAKsK,KAAKlK,KAAK8J,eAAiBD,GAEjD7J,KAAK+I,cAAc/I,KAAKmK,aAAc,SACtCnK,KAAKgE,OAEiB,IAAlBhE,KAAKoJ,WACPpJ,KAAK2J,uBAAyBpH,YAAW,KACvCvC,KAAKgK,aAAehK,KAAKoJ,SACzBpJ,KAAKoJ,SAAW,EAChBpJ,KAAK+I,aAAc,EACnB/I,KAAKgE,MAAM,GACV,KAKN,GAtPDtB,OAAO0H,4BAGH1I,IAAYuE,SAASC,iBAAmBxE,IAAYuE,SAASoE,OAC/D3I,EAAUgB,QAGZ1C,KAAKyH,QAAU,CACb/F,UACAC,UACAwE,oBACAC,eACAC,cACAC,YACAC,gBACAC,yBACAxF,WACAE,SACAf,OACAuG,WACAE,qBACAD,cACA7B,kBACAD,kBACAjD,aACAiF,UACAC,mCAGF9G,KAAKgJ,QAAU,IAAInJ,QACnBG,KAAKgF,QAAU,IAAIlB,QACnB9D,KAAKsK,WAAa,IAAI9I,WAAW,CAAEE,UAASC,UAASC,eAErD5B,KAAKuK,kBAELvK,KAAKwK,SAAW,GAChBxK,KAAKyK,KAAO,EACZzK,KAAKoJ,SAAWpJ,KAAKgK,aAAe,EACpChK,KAAK2H,UAAW,EAChB3H,KAAK0H,WAAY,EAIjB1H,KAAK+I,aAAc,EACnB/I,KAAKsJ,aAAetJ,KAAK8J,eAAiB9J,KAAK+J,aAE/C/J,KAAKyH,QAAQ/F,QAAQiB,iBAAiB,SAAU3C,KAAK0J,gBAAgB,GAErE1J,KAAK0K,cAAgB,IAAI/F,cAAcyB,EAAc,CACnDtB,kBACAD,oBAEF7E,KAAK0K,cAAcrG,GAAG,SAAUrE,KAAKkH,gBACtC,CAED,OAAAlE,GACEhD,KAAKgF,QAAQhC,UAEbhD,KAAKyH,QAAQ/F,QAAQwB,oBACnB,SACAlD,KAAK0J,gBACL,GAGF1J,KAAK0K,cAAc1H,UACnBhD,KAAKsK,WAAWtH,UAEhBhD,KAAK2K,kBASN,CAED,EAAAtG,CAAGJ,EAAejC,GAChB,OAAOhC,KAAKgF,QAAQX,GAAGJ,EAAOjC,EAC/B,CAED,GAAAyC,CAAIR,EAAejC,GACjB,OAAOhC,KAAKgF,QAAQP,IAAIR,EAAOjC,EAChC,CAEO,SAAA4I,CAAUC,GAEZ7K,KAAK8K,aACP9K,KAAKkI,YAAY6C,WAAaF,EAE9B7K,KAAKkI,YAAY8C,UAAYH,CAEhC,CAiHD,MAAApI,GACEzC,KAAKsK,WAAW7H,QACjB,CAEO,IAAAuB,EAAKwG,SAAEA,EAAW,CAAE,GAAK,CAAA,GAC/BxK,KAAKwK,SAAWA,EAChBxK,KAAKgF,QAAQhB,KAAK,SAAUhE,MAC5BA,KAAKwK,SAAW,EACjB,CAmCO,KAAA5C,GACN5H,KAAK2H,UAAW,EAChB3H,KAAK+I,aAAc,EACnB/I,KAAK8J,eAAiB9J,KAAKsJ,aAAetJ,KAAK+J,aAC/C/J,KAAKgK,aAAehK,KAAKoJ,SAAW,EACpCpJ,KAAKgJ,QAAQ5H,MACd,CAED,KAAA6J,GACOjL,KAAK0H,YACV1H,KAAK0H,WAAY,EAEjB1H,KAAK4H,QACN,CAED,IAAAxG,GACMpB,KAAK0H,YACT1H,KAAK0H,WAAY,EACjB1H,KAAKgJ,QAAQ5H,OAEbpB,KAAK4H,QACN,CAED,GAAAsD,CAAIT,GACF,MAAM1K,EAAY0K,GAAQzK,KAAKyK,MAAQA,GACvCzK,KAAKyK,KAAOA,EAEZzK,KAAKgJ,QAAQlJ,QAAoB,KAAZC,EACtB,CAED,QAAAsJ,CACE8B,GACAC,OACEA,EAAS,EAACC,UACVA,GAAY,EAAKC,KACjBA,GAAO,EAAKtK,SACZA,EAAWhB,KAAKyH,QAAQzG,SAAQE,OAChCA,EAASlB,KAAKyH,QAAQvG,OAAMf,KAC5BA,GAAQa,GAAYhB,KAAKyH,QAAQtH,KAAIoB,QACrCA,EAAOgK,WACPA,EAAUC,MACVA,GAAQ,EAAK/B,aACbA,GAAe,EAAIe,SACnBA,EAAW,CAAA,GAaT,IAEJ,IAAKxK,KAAK0H,YAAa1H,KAAK2H,UAAc6D,EAA1C,CAGA,GAAI,CAAC,MAAO,OAAQ,SAASlE,SAAS6D,GACpCA,EAAS,OACJ,GAAI,CAAC,SAAU,QAAS,OAAO7D,SAAS6D,GAC7CA,EAASnL,KAAK6D,UACT,CACL,IAAIuE,EAUJ,GARsB,iBAAX+C,EAET/C,EAAOnC,SAASwF,cAAcN,IACrBA,aAAM,EAANA,EAAQO,YAEjBtD,EAAO+C,GAGL/C,EAAM,CACR,GAAIpI,KAAKyH,QAAQ/F,UAAYgB,OAAQ,CAEnC,MAAMiJ,EAAc3L,KAAKyH,QAAQ/F,QAAQkK,wBACzCR,GAAUpL,KAAK8K,aAAea,EAAYE,KAAOF,EAAYG,GAC9D,CAED,MAAMC,EAAO3D,EAAKwD,wBAElBT,GACGnL,KAAK8K,aAAeiB,EAAKF,KAAOE,EAAKD,KAAO9L,KAAK8J,cACrD,CACF,CAED,GAAsB,iBAAXqB,EAAX,CAaA,GAXAA,GAAUC,EACVD,EAASvL,KAAKiB,MAAMsK,GAEhBnL,KAAKyH,QAAQf,SACX+C,IACFzJ,KAAKsJ,aAAetJ,KAAK8J,eAAiB9J,KAAK6K,QAGjDM,EAAS3L,MAAM,EAAG2L,EAAQnL,KAAK6D,OAG7BwH,EAKF,OAJArL,KAAK8J,eAAiB9J,KAAKsJ,aAAe6B,EAC1CnL,KAAK4K,UAAU5K,KAAK6K,QACpB7K,KAAK4H,aACL2D,SAAAA,EAAavL,OAIXmL,IAAWnL,KAAKsJ,eAEfG,IACHzJ,KAAKsJ,aAAe6B,GAGtBnL,KAAKgJ,QAAQ1H,OAAOtB,KAAK8J,eAAgBqB,EAAQ,CAC/CnK,WACAE,SACAf,OACAoB,QAAS,KAEH+J,IAAMtL,KAAK2H,UAAW,GAC1B3H,KAAK+I,YAAc,SACnBxH,SAAAA,EAAUvB,KAAK,EAEjBqB,SAAU,CAACjB,EAAeF,KACxBF,KAAK+I,YAAc,SAGnB/I,KAAKgK,aAAehK,KAAKoJ,SACzBpJ,KAAKoJ,SAAWhJ,EAAQJ,KAAK8J,eAC7B9J,KAAKiK,UAAYrK,KAAKsK,KAAKlK,KAAKoJ,UAEhCpJ,KAAK8J,eAAiB1J,EACtBJ,KAAK4K,UAAU5K,KAAK6K,QAEhBpB,IAEFzJ,KAAKsJ,aAAelJ,GAGjBF,GAAWF,KAAKgE,KAAK,CAAEwG,aAExBtK,IACFF,KAAK4H,QACL5H,KAAKgE,KAAK,CAAEwG,aACZe,SAAAA,EAAavL,MAGbA,KAAK4J,gCAAiC,EAIvC,IAjEiC,CAhCiB,CAoGxD,CAED,eAAI1B,GACF,OAAOlI,KAAKyH,QAAQ/F,UAAYgB,OAC5BuD,SAASC,gBACTlG,KAAKyH,QAAQ/F,OAClB,CAED,SAAImC,GACF,OAAI7D,KAAKyH,QAAQX,gCACX9G,KAAK8K,aACA9K,KAAKkI,YAAYtE,YAAc5D,KAAKkI,YAAYzE,YAEhDzD,KAAKkI,YAAYvE,aAAe3D,KAAKkI,YAAYxE,aAGnD1D,KAAKsK,WAAWzG,MAAM7D,KAAK8K,aAAe,IAAM,IAE1D,CAED,gBAAIA,GACF,MAAoC,eAA7B9K,KAAKyH,QAAQd,WACrB,CAED,gBAAIoD,GAEF,OAAO/J,KAAK8K,aACR9K,KAAKkI,YAAY6C,WACjB/K,KAAKkI,YAAY8C,SACtB,CAED,UAAIH,GACF,OAAO7K,KAAKyH,QAAQf,SNlfjB,SAASsF,OAAOC,EAAGC,GACxB,OAASD,EAAIC,EAAKA,GAAKA,CACzB,CMifQF,CAAOhM,KAAK8J,eAAgB9J,KAAK6D,OACjC7D,KAAK8J,cACV,CAED,YAAIqC,GAEF,OAAsB,IAAfnM,KAAK6D,MAAc,EAAI7D,KAAK6K,OAAS7K,KAAK6D,KAClD,CAaD,eAAIkF,GACF,OAAO/I,KAAK+G,aACb,CAED,eAAYgC,CAAY3I,GAClBJ,KAAK+G,gBAAkB3G,IACzBJ,KAAK+G,cAAgB3G,EACrBJ,KAAKuK,kBAER,CAED,aAAI7C,GACF,OAAO1H,KAAKgH,WACb,CAED,aAAYU,CAAUtH,GAChBJ,KAAKgH,cAAgB5G,IACvBJ,KAAKgH,YAAc5G,EACnBJ,KAAKuK,kBAER,CAED,YAAI5C,GACF,OAAO3H,KAAKiH,UACb,CAED,YAAYU,CAASvH,GACfJ,KAAKiH,aAAe7G,IACtBJ,KAAKiH,WAAa7G,EAClBJ,KAAKuK,kBAER,CAED,YAAI6B,GACF,MAA4B,WAArBpM,KAAK+I,WACb,CAED,aAAIsD,GACF,IAAIA,EAAY,QAOhB,OANIrM,KAAK0H,YAAW2E,GAAa,kBAC7BrM,KAAK2H,WAAU0E,GAAa,iBAC5BrM,KAAK+I,cAAasD,GAAa,oBACV,WAArBrM,KAAK+I,cAA0BsD,GAAa,iBAGzCA,CACR,CAEO,eAAA9B,GACNvK,KAAK2K,mBAEL3K,KAAKkI,YAAYmE,UACf,GAAGrM,KAAKkI,YAAYmE,aAAarM,KAAKqM,YAAYC,MAErD,CAEO,gBAAA3B,GACN3K,KAAKkI,YAAYmE,UAAYrM,KAAKkI,YAAYmE,UAC3CE,QAAQ,gBAAiB,IACzBD,MACJ"} \ 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 if (completed) {\r\n this.stop()\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\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 prevent?: boolean | ((node: Element) => 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 | 'native' | 'smooth' = 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 time: number\r\n userData: object\r\n lastVelocity: number\r\n velocity: number\r\n direction: 1 | -1 | undefined\r\n options: LenisOptions\r\n targetScroll: number\r\n animatedScroll: number\r\n // animate: Animate\r\n // emitter: Emitter\r\n // dimensions: Dimensions\r\n // virtualScroll: VirtualScroll\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 prevent = false,\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 prevent,\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 this.updateClassName()\r\n\r\n this.userData = {}\r\n this.time = 0\r\n this.velocity = this.lastVelocity = 0\r\n this.isLocked = false\r\n this.isStopped = false\r\n // this.hasScrolled = false\r\n // this.isSmooth = syncTouch || smoothWheel\r\n // this.isSmooth = false\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.cleanUpClassName()\r\n\r\n // this.rootElement.className = ''\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 this.isTouching = event.type === 'touchstart' || event.type === 'touchmove'\r\n // if (event.type === 'touchend') {\r\n // console.log('touchend', this.scroll)\r\n // // this.lastVelocity = this.velocity\r\n // // this.velocity = 0\r\n // // this.isScrolling = false\r\n // this.emit({ type: 'touchend' })\r\n // // alert('touchend')\r\n // return\r\n // }\r\n\r\n const isTapToStop =\r\n this.options.syncTouch &&\r\n isTouch &&\r\n event.type === 'touchstart' &&\r\n !this.isStopped &&\r\n !this.isLocked\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 this.options.prevent(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 const isSmooth =\r\n (this.options.syncTouch && isTouch) ||\r\n (this.options.smoothWheel && isWheel)\r\n\r\n if (!isSmooth) {\r\n this.isScrolling = 'native'\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({ userData = {} } = {}) {\r\n this.userData = userData\r\n this.emitter.emit('scroll', this)\r\n this.userData = {}\r\n }\r\n\r\n private onNativeScroll = () => {\r\n clearTimeout(this.__resetVelocityTimeout)\r\n delete this.__resetVelocityTimeout\r\n\r\n if (this.__preventNextNativeScrollEvent) {\r\n delete this.__preventNextNativeScrollEvent\r\n return\r\n }\r\n\r\n if (this.isScrolling === false || this.isScrolling === 'native') {\r\n const lastScroll = this.animatedScroll\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.lastVelocity = this.velocity\r\n this.velocity = this.animatedScroll - lastScroll\r\n this.direction = Math.sign(this.animatedScroll - lastScroll)\r\n // this.isSmooth = false\r\n this.isScrolling = this.hasScrolled ? 'native' : false\r\n this.emit()\r\n\r\n if (this.velocity !== 0) {\r\n this.__resetVelocityTimeout = setTimeout(() => {\r\n this.lastVelocity = this.velocity\r\n this.velocity = 0\r\n this.isScrolling = false\r\n this.emit()\r\n }, 400)\r\n }\r\n\r\n // this.hasScrolled = true\r\n // }, 50)\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.lastVelocity = 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 onStart,\r\n onComplete,\r\n force = false, // scroll even if stopped\r\n programmatic = true, // called from outside of the class\r\n userData = {},\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 onStart?: (lenis: Lenis) => void\r\n onComplete?: (lenis: Lenis) => void\r\n force?: boolean\r\n programmatic?: boolean\r\n userData?: object\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 (target === this.targetScroll) return\r\n\r\n if (!programmatic) {\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 = 'smooth'\r\n onStart?.(this)\r\n },\r\n onUpdate: (value: number, completed: boolean) => {\r\n this.isScrolling = 'smooth'\r\n\r\n // updated\r\n this.lastVelocity = this.velocity\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({ userData })\r\n\r\n if (completed) {\r\n this.reset()\r\n this.emit({ userData })\r\n onComplete?.(this)\r\n\r\n // avoid emitting event twice\r\n this.__preventNextNativeScrollEvent = true\r\n // requestAnimationFrame(() => {\r\n // delete this.__preventNextNativeScrollEvent\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(): number {\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(): number {\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(): number {\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.updateClassName()\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.updateClassName()\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.updateClassName()\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.updateClassName()\r\n }\r\n }\r\n\r\n get isSmooth() {\r\n return this.isScrolling === 'smooth'\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.isScrolling === 'smooth') className += ' lenis-smooth'\r\n // if (this.isScrolling === 'native') className += ' lenis-native'\r\n // if (this.isSmooth) className += ' lenis-smooth'\r\n return className\r\n }\r\n\r\n private updateClassName() {\r\n this.cleanUpClassName()\r\n\r\n this.rootElement.className =\r\n `${this.rootElement.className} ${this.className}`.trim()\r\n // this.emitter.emit('className change', this)\r\n }\r\n\r\n private cleanUpClassName() {\r\n this.rootElement.className = this.rootElement.className\r\n .replace(/lenis(-\\w+)?/g, '')\r\n .trim()\r\n }\r\n\r\n // private toggleClassName(name: string, value: boolean) {\r\n // // this.rootElement.classList.toggle(name, value)\r\n // this.rootElement.className = this.className\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","damp","x","y","lambda","dt","t","exp","to","round","currentTime","linearProgress","duration","easedProgress","easing","from","stop","onUpdate","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","prevent","__experimental__naiveDimensions","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","isTouching","options","isStopped","isLocked","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","preventDefault","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__resetVelocityTimeout","__preventNextNativeScrollEvent","lastScroll","animatedScroll","actualScroll","lastVelocity","direction","sign","hasScrolled","lenisVersion","body","dimensions","updateClassName","userData","time","virtualScroll","cleanUpClassName","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","modulo","n","d","progress","isSmooth","className","trim","replace"],"mappings":"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"} \ No newline at end of file diff --git a/packages/snap/dist/index.d.ts b/packages/snap/dist/index.d.ts deleted file mode 100644 index 54b856d0..00000000 --- a/packages/snap/dist/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default class Snap { - constructor(lenis: any); - destroy(): void; - add(element: any, options?: {}): void; - remove(element: any): void; - onWindowResize: () => void; - onScroll: (e: any) => void; -} diff --git a/packages/snap/dist/lenis-snap.d.ts b/packages/snap/dist/lenis-snap.d.ts index 4c15dec7..ccfedf40 100644 --- a/packages/snap/dist/lenis-snap.d.ts +++ b/packages/snap/dist/lenis-snap.d.ts @@ -1,10 +1,30 @@ declare class Snap { - constructor(lenis: any); + constructor(lenis: any, { type, lerp, easing, duration, velocityThreshold, onSnapStart, onSnapComplete, }?: { + type?: string; + lerp: any; + easing: any; + duration: any; + velocityThreshold?: number; + onSnapStart: any; + onSnapComplete: any; + }); destroy(): void; - add(element: any, options?: {}): void; - remove(element: any): void; + start(): void; + stop(): void; + add(value: any): () => void; + remove(id: any): void; + addElement(element: any, options?: {}): () => void; + removeElement(id: any): void; onWindowResize: () => void; - onScroll: (e: any) => void; + onScroll: ({ scroll, limit, lastVelocity, velocity, isScrolling, isTouching, userData, }: { + scroll: any; + limit: any; + lastVelocity: any; + velocity: any; + isScrolling: any; + isTouching: any; + userData: any; + }) => void; } export { Snap as default }; diff --git a/packages/snap/dist/lenis-snap.js b/packages/snap/dist/lenis-snap.js index f8518ea5..59369f7f 100644 --- a/packages/snap/dist/lenis-snap.js +++ b/packages/snap/dist/lenis-snap.js @@ -22,13 +22,28 @@ function addParentSticky(element) { if (element?.dataset?.sticky === 'true') { element.style.removeProperty('position'); - element.dataset.sticky = 'true'; delete element.dataset.sticky; } - if (element.parentNode) { - addParentSticky(element.parentNode); + if (element.offsetParent) { + addParentSticky(element.offsetParent); + } + } + + function offsetTop(element, accumulator = 0) { + const top = accumulator + element.offsetTop; + if (element.offsetParent) { + return offsetTop(element.offsetParent, top) } + return top + } + + function offsetLeft(element, accumulator = 0) { + const left = accumulator + element.offsetLeft; + if (element.offsetParent) { + return offsetLeft(element.offsetParent, left) + } + return left } function scrollTop(element, accumulator = 0) { @@ -48,10 +63,16 @@ } class Slide { - constructor(element, { align = 'start', type = 'mandatory' } = {}) { + constructor( + element, + { align = ['start'], ignoreSticky = true, ignoreTransform = false } = {} + ) { this.element = element; - this.align = align; - this.type = type; + + this.ignoreSticky = ignoreSticky; + this.ignoreTransform = ignoreTransform; + + this.align = [align].flat(); this.rect = {}; @@ -96,13 +117,16 @@ onWrapperResize = () => { let top, left; - removeParentSticky(this.element); - { + if (this.ignoreSticky) removeParentSticky(this.element); + if (this.ignoreTransform) { + top = offsetTop(this.element); + left = offsetLeft(this.element); + } else { const rect = this.element.getBoundingClientRect(); top = rect.top + scrollTop(this.element); left = rect.left + scrollLeft(this.element); } - addParentSticky(this.element); + if (this.ignoreSticky) addParentSticky(this.element); this.setRect({ top, left }); } @@ -115,46 +139,98 @@ } } - var Snap = /** @class */ (function () { - function Snap(lenis) { - var _this = this; - this.onWindowResize = function () { - _this.viewport.width = window.innerWidth; - _this.viewport.height = window.innerHeight; + // TODO: + // - horizontal + // - fix trackpad snapping too soon due to velocity (fuck Apple) + // - fix wheel scrolling after limits (see console scroll to) + // - fix touch scroll, do not snap when not released + class Snap { + constructor(lenis, { type = 'mandatory', lerp, easing, duration, velocityThreshold = 1, onSnapStart, onSnapComplete, } = {}) { + this.onWindowResize = () => { + this.viewport.width = window.innerWidth; + this.viewport.height = window.innerHeight; }; - this.onScroll = function (e) { - console.log(e.isNativeScroll, e.velocity); - // console.log('scroll', e.isScrolling) - // console.log('scroll', e.scroll, e.velocity, e.isScrolling) - if (e.velocity === 0) { - // console.log('not scrolling anymore') - _this.elements.forEach(function (_a) { - var rect = _a.rect; _a.type; var align = _a.align; - var snap; - if (align === 'start') { - snap = rect.top; - } - else if (align === 'center') { - snap = rect.top + rect.height / 2 - _this.viewport.height / 2; - } - else if (align === 'end') { - snap = rect.top + rect.height - _this.viewport.height; - } - console.log('snap', snap); - // setTimeout(() => { - // console.log('scroll to', slide.rect.top + slide.rect.height / 2) - // }, 0) - // console.log( - // e.scroll, - // slide.type, - // slide.align, - // slide.rect.top + slide.rect.height / 2 - // ) + this.onScroll = ({ scroll, limit, lastVelocity, velocity, isScrolling, isTouching, userData, }) => { + if (this.isStopped) + return; + // console.log(scroll, velocity, type) + // return + const isDecelerating = Math.abs(lastVelocity) > Math.abs(velocity); + const isTurningBack = Math.sign(lastVelocity) !== Math.sign(velocity) && velocity !== 0; + // console.log({ lastVelocity, velocity, isTurningBack, isDecelerating }) + // console.log('onScroll') + if (Math.abs(velocity) < this.velocityThreshold && + // !isTouching && + isDecelerating && + !isTurningBack && + (userData === null || userData === void 0 ? void 0 : userData.initiator) !== 'snap') { + scroll = Math.ceil(scroll); + let snaps = [0, ...this.snaps.values(), limit]; + this.elements.forEach(({ rect, align }) => { + let snap; + align.forEach((align) => { + if (align === 'start') { + snap = rect.top; + } + else if (align === 'center') { + snap = rect.top + rect.height / 2 - this.viewport.height / 2; + } + else if (align === 'end') { + snap = rect.top + rect.height - this.viewport.height; + } + if (snap !== undefined) { + snaps.push(Math.ceil(snap)); + } + }); }); + snaps = snaps.sort((a, b) => Math.abs(a) - Math.abs(b)); + let prevSnap = snaps.findLast((snap) => snap <= scroll); + if (prevSnap === undefined) + prevSnap = snaps[0]; + const distanceToPrevSnap = Math.abs(scroll - prevSnap); + let nextSnap = snaps.find((snap) => snap >= scroll); + if (nextSnap === undefined) + nextSnap = snaps[snaps.length - 1]; + const distanceToNextSnap = Math.abs(scroll - nextSnap); + const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap; + const distance = Math.abs(scroll - snap); + if (this.type === 'mandatory' || + (this.type === 'proximity' && distance <= this.viewport.height)) { + // this.__isScrolling = true + // this.onSnapStart?.(snap) + // console.log('scroll to') + this.lenis.scrollTo(snap, { + lerp: this.options.lerp, + easing: this.options.easing, + duration: this.options.duration, + userData: { initiator: 'snap' }, + onStart: () => { + var _a; + (_a = this.onSnapStart) === null || _a === void 0 ? void 0 : _a.call(this, snap); + }, + onComplete: () => { + var _a; + (_a = this.onSnapComplete) === null || _a === void 0 ? void 0 : _a.call(this, snap); + }, + }); + } + // console.timeEnd('scroll') } }; this.lenis = lenis; + this.options = { + type, + lerp, + easing, + duration, + velocityThreshold, + }; + this.type = type; this.elements = new Map(); + this.snaps = new Map(); + this.velocityThreshold = velocityThreshold; + this.onSnapStart = onSnapStart; + this.onSnapComplete = onSnapComplete; this.viewport = { width: window.innerWidth, height: window.innerHeight, @@ -163,20 +239,47 @@ window.addEventListener('resize', this.onWindowResize); this.lenis.on('scroll', this.onScroll); } - Snap.prototype.destroy = function () { + // debug() { + // const element = document.createElement('div') + // element.style.cssText = ` + // position: fixed; + // background: red; + // border-bottom: 1px solid red; + // left: 0; + // right: 0; + // top: 0; + // z-index: 9999; + // ` + // document.body.appendChild(element) + // } + destroy() { this.lenis.off('scroll', this.onScroll); window.removeEventListener('resize', this.onWindowResize); - this.elements.forEach(function (slide) { return slide.destroy(); }); - }; - Snap.prototype.add = function (element, options) { - if (options === void 0) { options = {}; } - this.elements.set(element, new Slide(element, options)); - }; - Snap.prototype.remove = function (element) { - this.elements.delete(element); - }; - return Snap; - }()); + this.elements.forEach((slide) => slide.destroy()); + } + start() { + this.isStopped = false; + } + stop() { + this.isStopped = true; + } + add(value) { + const id = crypto.randomUUID(); + this.snaps.set(id, value); + return () => this.remove(id); + } + remove(id) { + this.snaps.delete(id); + } + addElement(element, options = {}) { + const id = crypto.randomUUID(); + this.elements.set(id, new Slide(element, options)); + return () => this.removeElement(id); + } + removeElement(id) { + this.elements.delete(id); + } + } return Snap; diff --git a/packages/snap/dist/lenis-snap.js.map b/packages/snap/dist/lenis-snap.js.map index 9c5239d7..581699e0 100644 --- a/packages/snap/dist/lenis-snap.js.map +++ b/packages/snap/dist/lenis-snap.js.map @@ -1 +1 @@ -{"version":3,"file":"lenis-snap.js","sources":["../src/slide.js","../src/index.ts"],"sourcesContent":["function removeParentSticky(element) {\r\n const position = getComputedStyle(element).position\r\n\r\n const isSticky = position === 'sticky'\r\n\r\n if (isSticky) {\r\n element.style.setProperty('position', 'static')\r\n element.dataset.sticky = 'true'\r\n }\r\n\r\n if (element.offsetParent) {\r\n removeParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element) {\r\n if (element?.dataset?.sticky === 'true') {\r\n element.style.removeProperty('position')\r\n element.dataset.sticky = 'true'\r\n delete element.dataset.sticky\r\n }\r\n\r\n if (element.parentNode) {\r\n addParentSticky(element.parentNode)\r\n }\r\n}\r\n\r\nfunction offsetTop(element, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nconst ignoreSticky = true\r\nconst ignoreTransform = false\r\n\r\nexport default class Slide {\r\n constructor(element, { align = 'start', type = 'mandatory' } = {}) {\r\n this.element = element\r\n this.align = align\r\n this.type = type\r\n\r\n this.rect = {}\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({ top, left, width, height, element }) {\r\n top = top ?? this.rect.top\r\n left = left ?? this.rect.left\r\n width = width ?? this.rect.width\r\n height = height ?? this.rect.height\r\n element = element ?? this.rect.element\r\n\r\n if (\r\n top === this.rect.top &&\r\n left === this.rect.left &&\r\n width === this.rect.width &&\r\n height === this.rect.height &&\r\n element === this.rect.element\r\n )\r\n return\r\n\r\n this.rect.top = top\r\n this.rect.y = top\r\n this.rect.width = width\r\n this.rect.height = height\r\n this.rect.left = left\r\n this.rect.x = left\r\n this.rect.bottom = top + height\r\n this.rect.right = left + width\r\n }\r\n\r\n onWrapperResize = () => {\r\n let top, left\r\n\r\n if (ignoreSticky) removeParentSticky(this.element)\r\n if (ignoreTransform) {\r\n top = offsetTop(this.element)\r\n left = offsetLeft(this.element)\r\n } else {\r\n const rect = this.element.getBoundingClientRect()\r\n top = rect.top + scrollTop(this.element)\r\n left = rect.left + scrollLeft(this.element)\r\n }\r\n if (ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]) => {\r\n const width = entry.borderBoxSize[0].inlineSize\r\n const height = entry.borderBoxSize[0].blockSize\r\n\r\n this.setRect({ width, height })\r\n }\r\n}\r\n","import Slide from './slide'\r\n\r\nexport default class Snap {\r\n constructor(lenis) {\r\n this.lenis = lenis\r\n this.elements = new Map()\r\n\r\n this.viewport = {\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n }\r\n this.onWindowResize()\r\n window.addEventListener('resize', this.onWindowResize)\r\n\r\n this.lenis.on('scroll', this.onScroll)\r\n }\r\n\r\n destroy() {\r\n this.lenis.off('scroll', this.onScroll)\r\n window.removeEventListener('resize', this.onWindowResize)\r\n this.elements.forEach((slide) => slide.destroy())\r\n }\r\n\r\n add(element, options = {}) {\r\n this.elements.set(element, new Slide(element, options))\r\n }\r\n\r\n remove(element) {\r\n this.elements.delete(element)\r\n }\r\n\r\n onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n onScroll = (e) => {\r\n console.log(e.isNativeScroll, e.velocity)\r\n // console.log('scroll', e.isScrolling)\r\n\r\n // console.log('scroll', e.scroll, e.velocity, e.isScrolling)\r\n\r\n if (e.velocity === 0) {\r\n // console.log('not scrolling anymore')\r\n\r\n this.elements.forEach(({ rect, type, align }) => {\r\n let snap\r\n\r\n if (align === 'start') {\r\n snap = rect.top\r\n } else if (align === 'center') {\r\n snap = rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n snap = rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n console.log('snap', snap)\r\n\r\n if (\r\n snap !== undefined\r\n // && e.scroll > snap - this.viewport.height / 2 &&\r\n // e.scroll < snap + this.viewport.height / 2\r\n ) {\r\n // this.lenis.scrollTo(snap)\r\n }\r\n\r\n // setTimeout(() => {\r\n // console.log('scroll to', slide.rect.top + slide.rect.height / 2)\r\n\r\n // }, 0)\r\n // console.log(\r\n // e.scroll,\r\n // slide.type,\r\n // slide.align,\r\n // slide.rect.top + slide.rect.height / 2\r\n // )\r\n })\r\n }\r\n }\r\n}\r\n"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"lenis-snap.js","sources":["../src/slide.js","../src/index.ts"],"sourcesContent":["function removeParentSticky(element) {\r\n const position = getComputedStyle(element).position\r\n\r\n const isSticky = position === 'sticky'\r\n\r\n if (isSticky) {\r\n element.style.setProperty('position', 'static')\r\n element.dataset.sticky = 'true'\r\n }\r\n\r\n if (element.offsetParent) {\r\n removeParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element) {\r\n if (element?.dataset?.sticky === 'true') {\r\n element.style.removeProperty('position')\r\n delete element.dataset.sticky\r\n }\r\n\r\n if (element.offsetParent) {\r\n addParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction offsetTop(element, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport default class Slide {\r\n constructor(\r\n element,\r\n { align = ['start'], ignoreSticky = true, ignoreTransform = false } = {}\r\n ) {\r\n this.element = element\r\n\r\n this.ignoreSticky = ignoreSticky\r\n this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n this.rect = {}\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({ top, left, width, height, element }) {\r\n top = top ?? this.rect.top\r\n left = left ?? this.rect.left\r\n width = width ?? this.rect.width\r\n height = height ?? this.rect.height\r\n element = element ?? this.rect.element\r\n\r\n if (\r\n top === this.rect.top &&\r\n left === this.rect.left &&\r\n width === this.rect.width &&\r\n height === this.rect.height &&\r\n element === this.rect.element\r\n )\r\n return\r\n\r\n this.rect.top = top\r\n this.rect.y = top\r\n this.rect.width = width\r\n this.rect.height = height\r\n this.rect.left = left\r\n this.rect.x = left\r\n this.rect.bottom = top + height\r\n this.rect.right = left + width\r\n }\r\n\r\n onWrapperResize = () => {\r\n let top, left\r\n\r\n if (this.ignoreSticky) removeParentSticky(this.element)\r\n if (this.ignoreTransform) {\r\n top = offsetTop(this.element)\r\n left = offsetLeft(this.element)\r\n } else {\r\n const rect = this.element.getBoundingClientRect()\r\n top = rect.top + scrollTop(this.element)\r\n left = rect.left + scrollLeft(this.element)\r\n }\r\n if (this.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]) => {\r\n const width = entry.borderBoxSize[0].inlineSize\r\n const height = entry.borderBoxSize[0].blockSize\r\n\r\n this.setRect({ width, height })\r\n }\r\n}\r\n","import Slide from './slide'\r\n\r\n// TODO:\r\n// - horizontal\r\n// - fix trackpad snapping too soon due to velocity (fuck Apple)\r\n// - fix wheel scrolling after limits (see console scroll to)\r\n// - fix touch scroll, do not snap when not released\r\n\r\nexport default class Snap {\r\n constructor(\r\n lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n onSnapStart,\r\n onSnapComplete,\r\n } = {}\r\n ) {\r\n this.lenis = lenis\r\n\r\n this.options = {\r\n type,\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold,\r\n }\r\n\r\n this.type = type\r\n this.elements = new Map()\r\n this.snaps = new Map()\r\n\r\n this.velocityThreshold = velocityThreshold\r\n this.onSnapStart = onSnapStart\r\n this.onSnapComplete = onSnapComplete\r\n\r\n this.viewport = {\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n }\r\n this.onWindowResize()\r\n window.addEventListener('resize', this.onWindowResize)\r\n\r\n this.lenis.on('scroll', this.onScroll)\r\n }\r\n\r\n // debug() {\r\n // const element = document.createElement('div')\r\n // element.style.cssText = `\r\n // position: fixed;\r\n // background: red;\r\n // border-bottom: 1px solid red;\r\n // left: 0;\r\n // right: 0;\r\n // top: 0;\r\n // z-index: 9999;\r\n // `\r\n // document.body.appendChild(element)\r\n // }\r\n\r\n destroy() {\r\n this.lenis.off('scroll', this.onScroll)\r\n window.removeEventListener('resize', this.onWindowResize)\r\n this.elements.forEach((slide) => slide.destroy())\r\n }\r\n\r\n start() {\r\n this.isStopped = false\r\n }\r\n\r\n stop() {\r\n this.isStopped = true\r\n }\r\n\r\n add(value) {\r\n const id = crypto.randomUUID()\r\n\r\n this.snaps.set(id, value)\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element, options = {}) {\r\n const id = crypto.randomUUID()\r\n\r\n this.elements.set(id, new Slide(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id) {\r\n this.elements.delete(id)\r\n }\r\n\r\n onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n onScroll = ({\r\n scroll,\r\n limit,\r\n lastVelocity,\r\n velocity,\r\n isScrolling,\r\n isTouching,\r\n userData,\r\n }) => {\r\n if (this.isStopped) return\r\n // console.log(scroll, velocity, type)\r\n\r\n // return\r\n const isDecelerating = Math.abs(lastVelocity) > Math.abs(velocity)\r\n const isTurningBack =\r\n Math.sign(lastVelocity) !== Math.sign(velocity) && velocity !== 0\r\n\r\n // console.log({ lastVelocity, velocity, isTurningBack, isDecelerating })\r\n\r\n // console.log('onScroll')\r\n\r\n if (\r\n Math.abs(velocity) < this.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n scroll = Math.ceil(scroll)\r\n\r\n let snaps = [0, ...this.snaps.values(), limit]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let snap\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n snap = rect.top\r\n } else if (align === 'center') {\r\n snap = rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n snap = rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (snap !== undefined) {\r\n snaps.push(Math.ceil(snap))\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a) - Math.abs(b))\r\n\r\n let prevSnap = snaps.findLast((snap) => snap <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap)\r\n\r\n let nextSnap = snaps.find((snap) => snap >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap)\r\n\r\n if (\r\n this.type === 'mandatory' ||\r\n (this.type === 'proximity' && distance <= this.viewport.height)\r\n ) {\r\n // this.__isScrolling = true\r\n // this.onSnapStart?.(snap)\r\n\r\n // console.log('scroll to')\r\n\r\n this.lenis.scrollTo(snap, {\r\n lerp: this.options.lerp,\r\n easing: this.options.easing,\r\n duration: this.options.duration,\r\n userData: { initiator: 'snap' },\r\n onStart: () => {\r\n this.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\r\n }\r\n }\r\n}\r\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/snap/dist/lenis-snap.min.js b/packages/snap/dist/lenis-snap.min.js index 3acd81c8..472496fc 100644 --- a/packages/snap/dist/lenis-snap.min.js +++ b/packages/snap/dist/lenis-snap.min.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Lenis=t()}(this,(function(){"use strict";function removeParentSticky(e){"sticky"===getComputedStyle(e).position&&(e.style.setProperty("position","static"),e.dataset.sticky="true"),e.offsetParent&&removeParentSticky(e.offsetParent)}function addParentSticky(e){"true"===e?.dataset?.sticky&&(e.style.removeProperty("position"),e.dataset.sticky="true",delete e.dataset.sticky),e.parentNode&&addParentSticky(e.parentNode)}function scrollTop(e,t=0){const i=t+e.scrollTop;return e.offsetParent?scrollTop(e.offsetParent,i):i+window.scrollY}function scrollLeft(e,t=0){const i=t+e.scrollLeft;return e.offsetParent?scrollLeft(e.offsetParent,i):i+window.scrollX}class Slide{constructor(e,{align:t="start",type:i="mandatory"}={}){this.element=e,this.align=t,this.type=i,this.rect={},this.wrapperResizeObserver=new ResizeObserver(this.onWrapperResize),this.wrapperResizeObserver.observe(document.body),this.resizeObserver=new ResizeObserver(this.onResize),this.resizeObserver.observe(this.element)}destroy(){this.wrapperResizeObserver.disconnect(),this.resizeObserver.disconnect()}setRect({top:e,left:t,width:i,height:s,element:o}){e=e??this.rect.top,t=t??this.rect.left,i=i??this.rect.width,s=s??this.rect.height,o=o??this.rect.element,e===this.rect.top&&t===this.rect.left&&i===this.rect.width&&s===this.rect.height&&o===this.rect.element||(this.rect.top=e,this.rect.y=e,this.rect.width=i,this.rect.height=s,this.rect.left=t,this.rect.x=t,this.rect.bottom=e+s,this.rect.right=t+i)}onWrapperResize=()=>{let e,t;removeParentSticky(this.element);{const i=this.element.getBoundingClientRect();e=i.top+scrollTop(this.element),t=i.left+scrollLeft(this.element)}addParentSticky(this.element),this.setRect({top:e,left:t})};onResize=([e])=>{const t=e.borderBoxSize[0].inlineSize,i=e.borderBoxSize[0].blockSize;this.setRect({width:t,height:i})}}return function(){function Snap(e){var t=this;this.onWindowResize=function(){t.viewport.width=window.innerWidth,t.viewport.height=window.innerHeight},this.onScroll=function(e){console.log(e.isNativeScroll,e.velocity),0===e.velocity&&t.elements.forEach((function(e){var i=e.rect;e.type;var s,o=e.align;"start"===o?s=i.top:"center"===o?s=i.top+i.height/2-t.viewport.height/2:"end"===o&&(s=i.top+i.height-t.viewport.height),console.log("snap",s)}))},this.lenis=e,this.elements=new Map,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize),this.lenis.on("scroll",this.onScroll)}return Snap.prototype.destroy=function(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize),this.elements.forEach((function(e){return e.destroy()}))},Snap.prototype.add=function(e,t){void 0===t&&(t={}),this.elements.set(e,new Slide(e,t))},Snap.prototype.remove=function(e){this.elements.delete(e)},Snap}()})); +!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 removeParentSticky(t){"sticky"===getComputedStyle(t).position&&(t.style.setProperty("position","static"),t.dataset.sticky="true"),t.offsetParent&&removeParentSticky(t.offsetParent)}function addParentSticky(t){"true"===t?.dataset?.sticky&&(t.style.removeProperty("position"),delete t.dataset.sticky),t.offsetParent&&addParentSticky(t.offsetParent)}function offsetTop(t,e=0){const i=e+t.offsetTop;return t.offsetParent?offsetTop(t.offsetParent,i):i}function offsetLeft(t,e=0){const i=e+t.offsetLeft;return t.offsetParent?offsetLeft(t.offsetParent,i):i}function scrollTop(t,e=0){const i=e+t.scrollTop;return t.offsetParent?scrollTop(t.offsetParent,i):i+window.scrollY}function scrollLeft(t,e=0){const i=e+t.scrollLeft;return t.offsetParent?scrollLeft(t.offsetParent,i):i+window.scrollX}class Slide{constructor(t,{align:e=["start"],ignoreSticky:i=!0,ignoreTransform:s=!1}={}){this.element=t,this.ignoreSticky=i,this.ignoreTransform=s,this.align=[e].flat(),this.rect={},this.wrapperResizeObserver=new ResizeObserver(this.onWrapperResize),this.wrapperResizeObserver.observe(document.body),this.resizeObserver=new ResizeObserver(this.onResize),this.resizeObserver.observe(this.element)}destroy(){this.wrapperResizeObserver.disconnect(),this.resizeObserver.disconnect()}setRect({top:t,left:e,width:i,height:s,element:o}){t=t??this.rect.top,e=e??this.rect.left,i=i??this.rect.width,s=s??this.rect.height,o=o??this.rect.element,t===this.rect.top&&e===this.rect.left&&i===this.rect.width&&s===this.rect.height&&o===this.rect.element||(this.rect.top=t,this.rect.y=t,this.rect.width=i,this.rect.height=s,this.rect.left=e,this.rect.x=e,this.rect.bottom=t+s,this.rect.right=e+i)}onWrapperResize=()=>{let t,e;if(this.ignoreSticky&&removeParentSticky(this.element),this.ignoreTransform)t=offsetTop(this.element),e=offsetLeft(this.element);else{const i=this.element.getBoundingClientRect();t=i.top+scrollTop(this.element),e=i.left+scrollLeft(this.element)}this.ignoreSticky&&addParentSticky(this.element),this.setRect({top:t,left:e})};onResize=([t])=>{const e=t.borderBoxSize[0].inlineSize,i=t.borderBoxSize[0].blockSize;this.setRect({width:e,height:i})}}return class Snap{constructor(t,{type:e="mandatory",lerp:i,easing:s,duration:o,velocityThreshold:n=1,onSnapStart:r,onSnapComplete:h}={}){this.onWindowResize=()=>{this.viewport.width=window.innerWidth,this.viewport.height=window.innerHeight},this.onScroll=({scroll:t,limit:e,lastVelocity:i,velocity:s,isScrolling:o,isTouching:n,userData:r})=>{if(this.isStopped)return;const h=Math.abs(i)>Math.abs(s),l=Math.sign(i)!==Math.sign(s)&&0!==s;if(Math.abs(s){let s;e.forEach((e=>{"start"===e?s=t.top:"center"===e?s=t.top+t.height/2-this.viewport.height/2:"end"===e&&(s=t.top+t.height-this.viewport.height),void 0!==s&&i.push(Math.ceil(s))}))})),i=i.sort(((t,e)=>Math.abs(t)-Math.abs(e)));let s=i.findLast((e=>e<=t));void 0===s&&(s=i[0]);const o=Math.abs(t-s);let n=i.find((e=>e>=t));void 0===n&&(n=i[i.length-1]);const r=o{var t;null===(t=this.onSnapStart)||void 0===t||t.call(this,r)},onComplete:()=>{var t;null===(t=this.onSnapComplete)||void 0===t||t.call(this,r)}})}},this.lenis=t,this.options={type:e,lerp:i,easing:s,duration:o,velocityThreshold:n},this.type=e,this.elements=new Map,this.snaps=new Map,this.velocityThreshold=n,this.onSnapStart=r,this.onSnapComplete=h,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize),this.lenis.on("scroll",this.onScroll)}destroy(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize),this.elements.forEach((t=>t.destroy()))}start(){this.isStopped=!1}stop(){this.isStopped=!0}add(t){const e=crypto.randomUUID();return this.snaps.set(e,t),()=>this.remove(e)}remove(t){this.snaps.delete(t)}addElement(t,e={}){const i=crypto.randomUUID();return this.elements.set(i,new Slide(t,e)),()=>this.removeElement(i)}removeElement(t){this.elements.delete(t)}}})); //# sourceMappingURL=lenis-snap.min.js.map diff --git a/packages/snap/dist/lenis-snap.min.js.map b/packages/snap/dist/lenis-snap.min.js.map index 109c9806..d1e8bbc8 100644 --- a/packages/snap/dist/lenis-snap.min.js.map +++ b/packages/snap/dist/lenis-snap.min.js.map @@ -1 +1 @@ -{"version":3,"file":"lenis-snap.min.js","sources":["../src/slide.js","../src/index.ts"],"sourcesContent":["function removeParentSticky(element) {\r\n const position = getComputedStyle(element).position\r\n\r\n const isSticky = position === 'sticky'\r\n\r\n if (isSticky) {\r\n element.style.setProperty('position', 'static')\r\n element.dataset.sticky = 'true'\r\n }\r\n\r\n if (element.offsetParent) {\r\n removeParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element) {\r\n if (element?.dataset?.sticky === 'true') {\r\n element.style.removeProperty('position')\r\n element.dataset.sticky = 'true'\r\n delete element.dataset.sticky\r\n }\r\n\r\n if (element.parentNode) {\r\n addParentSticky(element.parentNode)\r\n }\r\n}\r\n\r\nfunction offsetTop(element, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nconst ignoreSticky = true\r\nconst ignoreTransform = false\r\n\r\nexport default class Slide {\r\n constructor(element, { align = 'start', type = 'mandatory' } = {}) {\r\n this.element = element\r\n this.align = align\r\n this.type = type\r\n\r\n this.rect = {}\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({ top, left, width, height, element }) {\r\n top = top ?? this.rect.top\r\n left = left ?? this.rect.left\r\n width = width ?? this.rect.width\r\n height = height ?? this.rect.height\r\n element = element ?? this.rect.element\r\n\r\n if (\r\n top === this.rect.top &&\r\n left === this.rect.left &&\r\n width === this.rect.width &&\r\n height === this.rect.height &&\r\n element === this.rect.element\r\n )\r\n return\r\n\r\n this.rect.top = top\r\n this.rect.y = top\r\n this.rect.width = width\r\n this.rect.height = height\r\n this.rect.left = left\r\n this.rect.x = left\r\n this.rect.bottom = top + height\r\n this.rect.right = left + width\r\n }\r\n\r\n onWrapperResize = () => {\r\n let top, left\r\n\r\n if (ignoreSticky) removeParentSticky(this.element)\r\n if (ignoreTransform) {\r\n top = offsetTop(this.element)\r\n left = offsetLeft(this.element)\r\n } else {\r\n const rect = this.element.getBoundingClientRect()\r\n top = rect.top + scrollTop(this.element)\r\n left = rect.left + scrollLeft(this.element)\r\n }\r\n if (ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]) => {\r\n const width = entry.borderBoxSize[0].inlineSize\r\n const height = entry.borderBoxSize[0].blockSize\r\n\r\n this.setRect({ width, height })\r\n }\r\n}\r\n","import Slide from './slide'\r\n\r\nexport default class Snap {\r\n constructor(lenis) {\r\n this.lenis = lenis\r\n this.elements = new Map()\r\n\r\n this.viewport = {\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n }\r\n this.onWindowResize()\r\n window.addEventListener('resize', this.onWindowResize)\r\n\r\n this.lenis.on('scroll', this.onScroll)\r\n }\r\n\r\n destroy() {\r\n this.lenis.off('scroll', this.onScroll)\r\n window.removeEventListener('resize', this.onWindowResize)\r\n this.elements.forEach((slide) => slide.destroy())\r\n }\r\n\r\n add(element, options = {}) {\r\n this.elements.set(element, new Slide(element, options))\r\n }\r\n\r\n remove(element) {\r\n this.elements.delete(element)\r\n }\r\n\r\n onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n onScroll = (e) => {\r\n console.log(e.isNativeScroll, e.velocity)\r\n // console.log('scroll', e.isScrolling)\r\n\r\n // console.log('scroll', e.scroll, e.velocity, e.isScrolling)\r\n\r\n if (e.velocity === 0) {\r\n // console.log('not scrolling anymore')\r\n\r\n this.elements.forEach(({ rect, type, align }) => {\r\n let snap\r\n\r\n if (align === 'start') {\r\n snap = rect.top\r\n } else if (align === 'center') {\r\n snap = rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n snap = rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n console.log('snap', snap)\r\n\r\n if (\r\n snap !== undefined\r\n // && e.scroll > snap - this.viewport.height / 2 &&\r\n // e.scroll < snap + this.viewport.height / 2\r\n ) {\r\n // this.lenis.scrollTo(snap)\r\n }\r\n\r\n // setTimeout(() => {\r\n // console.log('scroll to', slide.rect.top + slide.rect.height / 2)\r\n\r\n // }, 0)\r\n // console.log(\r\n // e.scroll,\r\n // slide.type,\r\n // slide.align,\r\n // slide.rect.top + slide.rect.height / 2\r\n // )\r\n })\r\n }\r\n }\r\n}\r\n"],"names":["removeParentSticky","element","getComputedStyle","position","style","setProperty","dataset","sticky","offsetParent","addParentSticky","removeProperty","parentNode","scrollTop","accumulator","top","window","scrollY","scrollLeft","left","scrollX","Slide","constructor","align","type","this","rect","wrapperResizeObserver","ResizeObserver","onWrapperResize","observe","document","body","resizeObserver","onResize","destroy","disconnect","setRect","width","height","y","x","bottom","right","getBoundingClientRect","entry","borderBoxSize","inlineSize","blockSize","Snap","lenis","_this","onWindowResize","viewport","innerWidth","innerHeight","onScroll","e","console","log","isNativeScroll","velocity","elements","forEach","_a","snap","Map","addEventListener","on","prototype","off","removeEventListener","slide","add","options","set","remove","delete"],"mappings":"sOAAA,SAASA,mBAAmBC,GAGI,WAFbC,iBAAiBD,GAASE,WAKzCF,EAAQG,MAAMC,YAAY,WAAY,UACtCJ,EAAQK,QAAQC,OAAS,QAGvBN,EAAQO,cACVR,mBAAmBC,EAAQO,aAE/B,CAEA,SAASC,gBAAgBR,GACU,SAA7BA,GAASK,SAASC,SACpBN,EAAQG,MAAMM,eAAe,YAC7BT,EAAQK,QAAQC,OAAS,cAClBN,EAAQK,QAAQC,QAGrBN,EAAQU,YACVF,gBAAgBR,EAAQU,WAE5B,CAkBA,SAASC,UAAUX,EAASY,EAAc,GACxC,MAAMC,EAAMD,EAAcZ,EAAQW,UAClC,OAAIX,EAAQO,aACHI,UAAUX,EAAQO,aAAcM,GAElCA,EAAMC,OAAOC,OACtB,CAEA,SAASC,WAAWhB,EAASY,EAAc,GACzC,MAAMK,EAAOL,EAAcZ,EAAQgB,WACnC,OAAIhB,EAAQO,aACHS,WAAWhB,EAAQO,aAAcU,GAEnCA,EAAOH,OAAOI,OACvB,CAKe,MAAMC,MACnB,WAAAC,CAAYpB,GAASqB,MAAEA,EAAQ,QAAOC,KAAEA,EAAO,aAAgB,IAC7DC,KAAKvB,QAAUA,EACfuB,KAAKF,MAAQA,EACbE,KAAKD,KAAOA,EAEZC,KAAKC,KAAO,CAAE,EAEdD,KAAKE,sBAAwB,IAAIC,eAAeH,KAAKI,iBACrDJ,KAAKE,sBAAsBG,QAAQC,SAASC,MAE5CP,KAAKQ,eAAiB,IAAIL,eAAeH,KAAKS,UAC9CT,KAAKQ,eAAeH,QAAQL,KAAKvB,QAClC,CAED,OAAAiC,GACEV,KAAKE,sBAAsBS,aAC3BX,KAAKQ,eAAeG,YACrB,CAED,OAAAC,EAAQtB,IAAEA,EAAGI,KAAEA,EAAImB,MAAEA,EAAKC,OAAEA,EAAMrC,QAAEA,IAClCa,EAAMA,GAAOU,KAAKC,KAAKX,IACvBI,EAAOA,GAAQM,KAAKC,KAAKP,KACzBmB,EAAQA,GAASb,KAAKC,KAAKY,MAC3BC,EAASA,GAAUd,KAAKC,KAAKa,OAC7BrC,EAAUA,GAAWuB,KAAKC,KAAKxB,QAG7Ba,IAAQU,KAAKC,KAAKX,KAClBI,IAASM,KAAKC,KAAKP,MACnBmB,IAAUb,KAAKC,KAAKY,OACpBC,IAAWd,KAAKC,KAAKa,QACrBrC,IAAYuB,KAAKC,KAAKxB,UAIxBuB,KAAKC,KAAKX,IAAMA,EAChBU,KAAKC,KAAKc,EAAIzB,EACdU,KAAKC,KAAKY,MAAQA,EAClBb,KAAKC,KAAKa,OAASA,EACnBd,KAAKC,KAAKP,KAAOA,EACjBM,KAAKC,KAAKe,EAAItB,EACdM,KAAKC,KAAKgB,OAAS3B,EAAMwB,EACzBd,KAAKC,KAAKiB,MAAQxB,EAAOmB,EAC1B,CAEDT,gBAAkB,KAChB,IAAId,EAAKI,EAESlB,mBAAmBwB,KAAKvB,SAInC,CACL,MAAMwB,EAAOD,KAAKvB,QAAQ0C,wBAC1B7B,EAAMW,EAAKX,IAAMF,UAAUY,KAAKvB,SAChCiB,EAAOO,EAAKP,KAAOD,WAAWO,KAAKvB,QACpC,CACiBQ,gBAAgBe,KAAKvB,SAEvCuB,KAAKY,QAAQ,CAAEtB,MAAKI,QAAO,EAG7Be,SAAW,EAAEW,MACX,MAAMP,EAAQO,EAAMC,cAAc,GAAGC,WAC/BR,EAASM,EAAMC,cAAc,GAAGE,UAEtCvB,KAAKY,QAAQ,CAAEC,QAAOC,UAAS,SC/HnC,WACE,SAAAU,KAAYC,GAAZ,IAYCC,EAAA1B,KAgBDA,KAAA2B,eAAiB,WACfD,EAAKE,SAASf,MAAQtB,OAAOsC,WAC7BH,EAAKE,SAASd,OAASvB,OAAOuC,WAChC,EAEA9B,KAAQ+B,SAAG,SAACC,GACVC,QAAQC,IAAIF,EAAEG,eAAgBH,EAAEI,UAKb,IAAfJ,EAAEI,UAGJV,EAAKW,SAASC,SAAQ,SAACC,GAAE,IAAAtC,SAAUsC,EAAAxC,KAAA,IAC7ByC,EAD+B1C,EAAKyC,EAAAzC,MAG1B,UAAVA,EACF0C,EAAOvC,EAAKX,IACO,WAAVQ,EACT0C,EAAOvC,EAAKX,IAAMW,EAAKa,OAAS,EAAIY,EAAKE,SAASd,OAAS,EACxC,QAAVhB,IACT0C,EAAOvC,EAAKX,IAAMW,EAAKa,OAASY,EAAKE,SAASd,QAGhDmB,QAAQC,IAAI,OAAQM,EAoBtB,GAEJ,EA1EExC,KAAKyB,MAAQA,EACbzB,KAAKqC,SAAW,IAAII,IAEpBzC,KAAK4B,SAAW,CACdf,MAAOtB,OAAOsC,WACdf,OAAQvB,OAAOuC,aAEjB9B,KAAK2B,iBACLpC,OAAOmD,iBAAiB,SAAU1C,KAAK2B,gBAEvC3B,KAAKyB,MAAMkB,GAAG,SAAU3C,KAAK+B,SAC9B,CAgEH,OA9DEP,KAAAoB,UAAAlC,QAAA,WACEV,KAAKyB,MAAMoB,IAAI,SAAU7C,KAAK+B,UAC9BxC,OAAOuD,oBAAoB,SAAU9C,KAAK2B,gBAC1C3B,KAAKqC,SAASC,SAAQ,SAACS,GAAU,OAAAA,EAAMrC,SAAN,KAGnCc,KAAAoB,UAAAI,IAAA,SAAIvE,EAASwE,QAAA,IAAAA,IAAAA,EAAY,CAAA,GACvBjD,KAAKqC,SAASa,IAAIzE,EAAS,IAAImB,MAAMnB,EAASwE,KAGhDzB,KAAMoB,UAAAO,OAAN,SAAO1E,GACLuB,KAAKqC,SAASe,OAAO3E,IAmDxB+C,IAAD"} \ No newline at end of file +{"version":3,"file":"lenis-snap.min.js","sources":["../src/slide.js","../src/index.ts"],"sourcesContent":["function removeParentSticky(element) {\r\n const position = getComputedStyle(element).position\r\n\r\n const isSticky = position === 'sticky'\r\n\r\n if (isSticky) {\r\n element.style.setProperty('position', 'static')\r\n element.dataset.sticky = 'true'\r\n }\r\n\r\n if (element.offsetParent) {\r\n removeParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element) {\r\n if (element?.dataset?.sticky === 'true') {\r\n element.style.removeProperty('position')\r\n delete element.dataset.sticky\r\n }\r\n\r\n if (element.offsetParent) {\r\n addParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction offsetTop(element, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport default class Slide {\r\n constructor(\r\n element,\r\n { align = ['start'], ignoreSticky = true, ignoreTransform = false } = {}\r\n ) {\r\n this.element = element\r\n\r\n this.ignoreSticky = ignoreSticky\r\n this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n this.rect = {}\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({ top, left, width, height, element }) {\r\n top = top ?? this.rect.top\r\n left = left ?? this.rect.left\r\n width = width ?? this.rect.width\r\n height = height ?? this.rect.height\r\n element = element ?? this.rect.element\r\n\r\n if (\r\n top === this.rect.top &&\r\n left === this.rect.left &&\r\n width === this.rect.width &&\r\n height === this.rect.height &&\r\n element === this.rect.element\r\n )\r\n return\r\n\r\n this.rect.top = top\r\n this.rect.y = top\r\n this.rect.width = width\r\n this.rect.height = height\r\n this.rect.left = left\r\n this.rect.x = left\r\n this.rect.bottom = top + height\r\n this.rect.right = left + width\r\n }\r\n\r\n onWrapperResize = () => {\r\n let top, left\r\n\r\n if (this.ignoreSticky) removeParentSticky(this.element)\r\n if (this.ignoreTransform) {\r\n top = offsetTop(this.element)\r\n left = offsetLeft(this.element)\r\n } else {\r\n const rect = this.element.getBoundingClientRect()\r\n top = rect.top + scrollTop(this.element)\r\n left = rect.left + scrollLeft(this.element)\r\n }\r\n if (this.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]) => {\r\n const width = entry.borderBoxSize[0].inlineSize\r\n const height = entry.borderBoxSize[0].blockSize\r\n\r\n this.setRect({ width, height })\r\n }\r\n}\r\n","import Slide from './slide'\r\n\r\n// TODO:\r\n// - horizontal\r\n// - fix trackpad snapping too soon due to velocity (fuck Apple)\r\n// - fix wheel scrolling after limits (see console scroll to)\r\n// - fix touch scroll, do not snap when not released\r\n\r\nexport default class Snap {\r\n constructor(\r\n lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n onSnapStart,\r\n onSnapComplete,\r\n } = {}\r\n ) {\r\n this.lenis = lenis\r\n\r\n this.options = {\r\n type,\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold,\r\n }\r\n\r\n this.type = type\r\n this.elements = new Map()\r\n this.snaps = new Map()\r\n\r\n this.velocityThreshold = velocityThreshold\r\n this.onSnapStart = onSnapStart\r\n this.onSnapComplete = onSnapComplete\r\n\r\n this.viewport = {\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n }\r\n this.onWindowResize()\r\n window.addEventListener('resize', this.onWindowResize)\r\n\r\n this.lenis.on('scroll', this.onScroll)\r\n }\r\n\r\n // debug() {\r\n // const element = document.createElement('div')\r\n // element.style.cssText = `\r\n // position: fixed;\r\n // background: red;\r\n // border-bottom: 1px solid red;\r\n // left: 0;\r\n // right: 0;\r\n // top: 0;\r\n // z-index: 9999;\r\n // `\r\n // document.body.appendChild(element)\r\n // }\r\n\r\n destroy() {\r\n this.lenis.off('scroll', this.onScroll)\r\n window.removeEventListener('resize', this.onWindowResize)\r\n this.elements.forEach((slide) => slide.destroy())\r\n }\r\n\r\n start() {\r\n this.isStopped = false\r\n }\r\n\r\n stop() {\r\n this.isStopped = true\r\n }\r\n\r\n add(value) {\r\n const id = crypto.randomUUID()\r\n\r\n this.snaps.set(id, value)\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element, options = {}) {\r\n const id = crypto.randomUUID()\r\n\r\n this.elements.set(id, new Slide(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id) {\r\n this.elements.delete(id)\r\n }\r\n\r\n onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n onScroll = ({\r\n scroll,\r\n limit,\r\n lastVelocity,\r\n velocity,\r\n isScrolling,\r\n isTouching,\r\n userData,\r\n }) => {\r\n if (this.isStopped) return\r\n // console.log(scroll, velocity, type)\r\n\r\n // return\r\n const isDecelerating = Math.abs(lastVelocity) > Math.abs(velocity)\r\n const isTurningBack =\r\n Math.sign(lastVelocity) !== Math.sign(velocity) && velocity !== 0\r\n\r\n // console.log({ lastVelocity, velocity, isTurningBack, isDecelerating })\r\n\r\n // console.log('onScroll')\r\n\r\n if (\r\n Math.abs(velocity) < this.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n scroll = Math.ceil(scroll)\r\n\r\n let snaps = [0, ...this.snaps.values(), limit]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let snap\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n snap = rect.top\r\n } else if (align === 'center') {\r\n snap = rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n snap = rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (snap !== undefined) {\r\n snaps.push(Math.ceil(snap))\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a) - Math.abs(b))\r\n\r\n let prevSnap = snaps.findLast((snap) => snap <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap)\r\n\r\n let nextSnap = snaps.find((snap) => snap >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap)\r\n\r\n if (\r\n this.type === 'mandatory' ||\r\n (this.type === 'proximity' && distance <= this.viewport.height)\r\n ) {\r\n // this.__isScrolling = true\r\n // this.onSnapStart?.(snap)\r\n\r\n // console.log('scroll to')\r\n\r\n this.lenis.scrollTo(snap, {\r\n lerp: this.options.lerp,\r\n easing: this.options.easing,\r\n duration: this.options.duration,\r\n userData: { initiator: 'snap' },\r\n onStart: () => {\r\n this.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\r\n }\r\n }\r\n}\r\n"],"names":["removeParentSticky","element","getComputedStyle","position","style","setProperty","dataset","sticky","offsetParent","addParentSticky","removeProperty","offsetTop","accumulator","top","offsetLeft","left","scrollTop","window","scrollY","scrollLeft","scrollX","Slide","constructor","align","ignoreSticky","ignoreTransform","this","flat","rect","wrapperResizeObserver","ResizeObserver","onWrapperResize","observe","document","body","resizeObserver","onResize","destroy","disconnect","setRect","width","height","y","x","bottom","right","getBoundingClientRect","entry","borderBoxSize","inlineSize","blockSize","Snap","lenis","type","lerp","easing","duration","velocityThreshold","onSnapStart","onSnapComplete","onWindowResize","viewport","innerWidth","innerHeight","onScroll","scroll","limit","lastVelocity","velocity","isScrolling","isTouching","userData","isStopped","isDecelerating","Math","abs","isTurningBack","sign","initiator","ceil","snaps","values","elements","forEach","snap","undefined","push","sort","a","b","prevSnap","findLast","distanceToPrevSnap","nextSnap","find","length","distance","scrollTo","options","onStart","_a","call","onComplete","Map","addEventListener","on","off","removeEventListener","slide","start","stop","add","value","id","crypto","randomUUID","set","remove","delete","addElement","removeElement"],"mappings":"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"} \ No newline at end of file diff --git a/packages/snap/dist/lenis-snap.mjs b/packages/snap/dist/lenis-snap.mjs index 54e7f7e9..bdc920d2 100644 --- a/packages/snap/dist/lenis-snap.mjs +++ b/packages/snap/dist/lenis-snap.mjs @@ -1,2 +1,2 @@ -function removeParentSticky(e){"sticky"===getComputedStyle(e).position&&(e.style.setProperty("position","static"),e.dataset.sticky="true"),e.offsetParent&&removeParentSticky(e.offsetParent)}function addParentSticky(e){"true"===e?.dataset?.sticky&&(e.style.removeProperty("position"),e.dataset.sticky="true",delete e.dataset.sticky),e.parentNode&&addParentSticky(e.parentNode)}function scrollTop(e,t=0){const i=t+e.scrollTop;return e.offsetParent?scrollTop(e.offsetParent,i):i+window.scrollY}function scrollLeft(e,t=0){const i=t+e.scrollLeft;return e.offsetParent?scrollLeft(e.offsetParent,i):i+window.scrollX}class Slide{constructor(e,{align:t="start",type:i="mandatory"}={}){this.element=e,this.align=t,this.type=i,this.rect={},this.wrapperResizeObserver=new ResizeObserver(this.onWrapperResize),this.wrapperResizeObserver.observe(document.body),this.resizeObserver=new ResizeObserver(this.onResize),this.resizeObserver.observe(this.element)}destroy(){this.wrapperResizeObserver.disconnect(),this.resizeObserver.disconnect()}setRect({top:e,left:t,width:i,height:s,element:r}){e=e??this.rect.top,t=t??this.rect.left,i=i??this.rect.width,s=s??this.rect.height,r=r??this.rect.element,e===this.rect.top&&t===this.rect.left&&i===this.rect.width&&s===this.rect.height&&r===this.rect.element||(this.rect.top=e,this.rect.y=e,this.rect.width=i,this.rect.height=s,this.rect.left=t,this.rect.x=t,this.rect.bottom=e+s,this.rect.right=t+i)}onWrapperResize=()=>{let e,t;removeParentSticky(this.element);{const i=this.element.getBoundingClientRect();e=i.top+scrollTop(this.element),t=i.left+scrollLeft(this.element)}addParentSticky(this.element),this.setRect({top:e,left:t})};onResize=([e])=>{const t=e.borderBoxSize[0].inlineSize,i=e.borderBoxSize[0].blockSize;this.setRect({width:t,height:i})}}var e=function(){function Snap(e){var t=this;this.onWindowResize=function(){t.viewport.width=window.innerWidth,t.viewport.height=window.innerHeight},this.onScroll=function(e){console.log(e.isNativeScroll,e.velocity),0===e.velocity&&t.elements.forEach((function(e){var i=e.rect;e.type;var s,r=e.align;"start"===r?s=i.top:"center"===r?s=i.top+i.height/2-t.viewport.height/2:"end"===r&&(s=i.top+i.height-t.viewport.height),console.log("snap",s)}))},this.lenis=e,this.elements=new Map,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize),this.lenis.on("scroll",this.onScroll)}return Snap.prototype.destroy=function(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize),this.elements.forEach((function(e){return e.destroy()}))},Snap.prototype.add=function(e,t){void 0===t&&(t={}),this.elements.set(e,new Slide(e,t))},Snap.prototype.remove=function(e){this.elements.delete(e)},Snap}();export{e as default}; +function removeParentSticky(t){"sticky"===getComputedStyle(t).position&&(t.style.setProperty("position","static"),t.dataset.sticky="true"),t.offsetParent&&removeParentSticky(t.offsetParent)}function addParentSticky(t){"true"===t?.dataset?.sticky&&(t.style.removeProperty("position"),delete t.dataset.sticky),t.offsetParent&&addParentSticky(t.offsetParent)}function offsetTop(t,e=0){const i=e+t.offsetTop;return t.offsetParent?offsetTop(t.offsetParent,i):i}function offsetLeft(t,e=0){const i=e+t.offsetLeft;return t.offsetParent?offsetLeft(t.offsetParent,i):i}function scrollTop(t,e=0){const i=e+t.scrollTop;return t.offsetParent?scrollTop(t.offsetParent,i):i+window.scrollY}function scrollLeft(t,e=0){const i=e+t.scrollLeft;return t.offsetParent?scrollLeft(t.offsetParent,i):i+window.scrollX}class Slide{constructor(t,{align:e=["start"],ignoreSticky:i=!0,ignoreTransform:s=!1}={}){this.element=t,this.ignoreSticky=i,this.ignoreTransform=s,this.align=[e].flat(),this.rect={},this.wrapperResizeObserver=new ResizeObserver(this.onWrapperResize),this.wrapperResizeObserver.observe(document.body),this.resizeObserver=new ResizeObserver(this.onResize),this.resizeObserver.observe(this.element)}destroy(){this.wrapperResizeObserver.disconnect(),this.resizeObserver.disconnect()}setRect({top:t,left:e,width:i,height:s,element:o}){t=t??this.rect.top,e=e??this.rect.left,i=i??this.rect.width,s=s??this.rect.height,o=o??this.rect.element,t===this.rect.top&&e===this.rect.left&&i===this.rect.width&&s===this.rect.height&&o===this.rect.element||(this.rect.top=t,this.rect.y=t,this.rect.width=i,this.rect.height=s,this.rect.left=e,this.rect.x=e,this.rect.bottom=t+s,this.rect.right=e+i)}onWrapperResize=()=>{let t,e;if(this.ignoreSticky&&removeParentSticky(this.element),this.ignoreTransform)t=offsetTop(this.element),e=offsetLeft(this.element);else{const i=this.element.getBoundingClientRect();t=i.top+scrollTop(this.element),e=i.left+scrollLeft(this.element)}this.ignoreSticky&&addParentSticky(this.element),this.setRect({top:t,left:e})};onResize=([t])=>{const e=t.borderBoxSize[0].inlineSize,i=t.borderBoxSize[0].blockSize;this.setRect({width:e,height:i})}}class Snap{constructor(t,{type:e="mandatory",lerp:i,easing:s,duration:o,velocityThreshold:n=1,onSnapStart:r,onSnapComplete:h}={}){this.onWindowResize=()=>{this.viewport.width=window.innerWidth,this.viewport.height=window.innerHeight},this.onScroll=({scroll:t,limit:e,lastVelocity:i,velocity:s,isScrolling:o,isTouching:n,userData:r})=>{if(this.isStopped)return;const h=Math.abs(i)>Math.abs(s),l=Math.sign(i)!==Math.sign(s)&&0!==s;if(Math.abs(s){let s;e.forEach((e=>{"start"===e?s=t.top:"center"===e?s=t.top+t.height/2-this.viewport.height/2:"end"===e&&(s=t.top+t.height-this.viewport.height),void 0!==s&&i.push(Math.ceil(s))}))})),i=i.sort(((t,e)=>Math.abs(t)-Math.abs(e)));let s=i.findLast((e=>e<=t));void 0===s&&(s=i[0]);const o=Math.abs(t-s);let n=i.find((e=>e>=t));void 0===n&&(n=i[i.length-1]);const r=o{var t;null===(t=this.onSnapStart)||void 0===t||t.call(this,r)},onComplete:()=>{var t;null===(t=this.onSnapComplete)||void 0===t||t.call(this,r)}})}},this.lenis=t,this.options={type:e,lerp:i,easing:s,duration:o,velocityThreshold:n},this.type=e,this.elements=new Map,this.snaps=new Map,this.velocityThreshold=n,this.onSnapStart=r,this.onSnapComplete=h,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize),this.lenis.on("scroll",this.onScroll)}destroy(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize),this.elements.forEach((t=>t.destroy()))}start(){this.isStopped=!1}stop(){this.isStopped=!0}add(t){const e=crypto.randomUUID();return this.snaps.set(e,t),()=>this.remove(e)}remove(t){this.snaps.delete(t)}addElement(t,e={}){const i=crypto.randomUUID();return this.elements.set(i,new Slide(t,e)),()=>this.removeElement(i)}removeElement(t){this.elements.delete(t)}}export{Snap as default}; //# sourceMappingURL=lenis-snap.mjs.map diff --git a/packages/snap/dist/lenis-snap.mjs.map b/packages/snap/dist/lenis-snap.mjs.map index d5a28620..94325811 100644 --- a/packages/snap/dist/lenis-snap.mjs.map +++ b/packages/snap/dist/lenis-snap.mjs.map @@ -1 +1 @@ -{"version":3,"file":"lenis-snap.mjs","sources":["../src/slide.js","../src/index.ts"],"sourcesContent":["function removeParentSticky(element) {\r\n const position = getComputedStyle(element).position\r\n\r\n const isSticky = position === 'sticky'\r\n\r\n if (isSticky) {\r\n element.style.setProperty('position', 'static')\r\n element.dataset.sticky = 'true'\r\n }\r\n\r\n if (element.offsetParent) {\r\n removeParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element) {\r\n if (element?.dataset?.sticky === 'true') {\r\n element.style.removeProperty('position')\r\n element.dataset.sticky = 'true'\r\n delete element.dataset.sticky\r\n }\r\n\r\n if (element.parentNode) {\r\n addParentSticky(element.parentNode)\r\n }\r\n}\r\n\r\nfunction offsetTop(element, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nconst ignoreSticky = true\r\nconst ignoreTransform = false\r\n\r\nexport default class Slide {\r\n constructor(element, { align = 'start', type = 'mandatory' } = {}) {\r\n this.element = element\r\n this.align = align\r\n this.type = type\r\n\r\n this.rect = {}\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({ top, left, width, height, element }) {\r\n top = top ?? this.rect.top\r\n left = left ?? this.rect.left\r\n width = width ?? this.rect.width\r\n height = height ?? this.rect.height\r\n element = element ?? this.rect.element\r\n\r\n if (\r\n top === this.rect.top &&\r\n left === this.rect.left &&\r\n width === this.rect.width &&\r\n height === this.rect.height &&\r\n element === this.rect.element\r\n )\r\n return\r\n\r\n this.rect.top = top\r\n this.rect.y = top\r\n this.rect.width = width\r\n this.rect.height = height\r\n this.rect.left = left\r\n this.rect.x = left\r\n this.rect.bottom = top + height\r\n this.rect.right = left + width\r\n }\r\n\r\n onWrapperResize = () => {\r\n let top, left\r\n\r\n if (ignoreSticky) removeParentSticky(this.element)\r\n if (ignoreTransform) {\r\n top = offsetTop(this.element)\r\n left = offsetLeft(this.element)\r\n } else {\r\n const rect = this.element.getBoundingClientRect()\r\n top = rect.top + scrollTop(this.element)\r\n left = rect.left + scrollLeft(this.element)\r\n }\r\n if (ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]) => {\r\n const width = entry.borderBoxSize[0].inlineSize\r\n const height = entry.borderBoxSize[0].blockSize\r\n\r\n this.setRect({ width, height })\r\n }\r\n}\r\n","import Slide from './slide'\r\n\r\nexport default class Snap {\r\n constructor(lenis) {\r\n this.lenis = lenis\r\n this.elements = new Map()\r\n\r\n this.viewport = {\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n }\r\n this.onWindowResize()\r\n window.addEventListener('resize', this.onWindowResize)\r\n\r\n this.lenis.on('scroll', this.onScroll)\r\n }\r\n\r\n destroy() {\r\n this.lenis.off('scroll', this.onScroll)\r\n window.removeEventListener('resize', this.onWindowResize)\r\n this.elements.forEach((slide) => slide.destroy())\r\n }\r\n\r\n add(element, options = {}) {\r\n this.elements.set(element, new Slide(element, options))\r\n }\r\n\r\n remove(element) {\r\n this.elements.delete(element)\r\n }\r\n\r\n onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n onScroll = (e) => {\r\n console.log(e.isNativeScroll, e.velocity)\r\n // console.log('scroll', e.isScrolling)\r\n\r\n // console.log('scroll', e.scroll, e.velocity, e.isScrolling)\r\n\r\n if (e.velocity === 0) {\r\n // console.log('not scrolling anymore')\r\n\r\n this.elements.forEach(({ rect, type, align }) => {\r\n let snap\r\n\r\n if (align === 'start') {\r\n snap = rect.top\r\n } else if (align === 'center') {\r\n snap = rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n snap = rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n console.log('snap', snap)\r\n\r\n if (\r\n snap !== undefined\r\n // && e.scroll > snap - this.viewport.height / 2 &&\r\n // e.scroll < snap + this.viewport.height / 2\r\n ) {\r\n // this.lenis.scrollTo(snap)\r\n }\r\n\r\n // setTimeout(() => {\r\n // console.log('scroll to', slide.rect.top + slide.rect.height / 2)\r\n\r\n // }, 0)\r\n // console.log(\r\n // e.scroll,\r\n // slide.type,\r\n // slide.align,\r\n // slide.rect.top + slide.rect.height / 2\r\n // )\r\n })\r\n }\r\n }\r\n}\r\n"],"names":["removeParentSticky","element","getComputedStyle","position","style","setProperty","dataset","sticky","offsetParent","addParentSticky","removeProperty","parentNode","scrollTop","accumulator","top","window","scrollY","scrollLeft","left","scrollX","Slide","constructor","align","type","this","rect","wrapperResizeObserver","ResizeObserver","onWrapperResize","observe","document","body","resizeObserver","onResize","destroy","disconnect","setRect","width","height","y","x","bottom","right","getBoundingClientRect","entry","borderBoxSize","inlineSize","blockSize","Snap","lenis","_this","onWindowResize","viewport","innerWidth","innerHeight","onScroll","e","console","log","isNativeScroll","velocity","elements","forEach","_a","snap","Map","addEventListener","on","prototype","off","removeEventListener","slide","add","options","set","remove","delete"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"lenis-snap.mjs","sources":["../src/slide.js","../src/index.ts"],"sourcesContent":["function removeParentSticky(element) {\r\n const position = getComputedStyle(element).position\r\n\r\n const isSticky = position === 'sticky'\r\n\r\n if (isSticky) {\r\n element.style.setProperty('position', 'static')\r\n element.dataset.sticky = 'true'\r\n }\r\n\r\n if (element.offsetParent) {\r\n removeParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element) {\r\n if (element?.dataset?.sticky === 'true') {\r\n element.style.removeProperty('position')\r\n delete element.dataset.sticky\r\n }\r\n\r\n if (element.offsetParent) {\r\n addParentSticky(element.offsetParent)\r\n }\r\n}\r\n\r\nfunction offsetTop(element, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport default class Slide {\r\n constructor(\r\n element,\r\n { align = ['start'], ignoreSticky = true, ignoreTransform = false } = {}\r\n ) {\r\n this.element = element\r\n\r\n this.ignoreSticky = ignoreSticky\r\n this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n this.rect = {}\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({ top, left, width, height, element }) {\r\n top = top ?? this.rect.top\r\n left = left ?? this.rect.left\r\n width = width ?? this.rect.width\r\n height = height ?? this.rect.height\r\n element = element ?? this.rect.element\r\n\r\n if (\r\n top === this.rect.top &&\r\n left === this.rect.left &&\r\n width === this.rect.width &&\r\n height === this.rect.height &&\r\n element === this.rect.element\r\n )\r\n return\r\n\r\n this.rect.top = top\r\n this.rect.y = top\r\n this.rect.width = width\r\n this.rect.height = height\r\n this.rect.left = left\r\n this.rect.x = left\r\n this.rect.bottom = top + height\r\n this.rect.right = left + width\r\n }\r\n\r\n onWrapperResize = () => {\r\n let top, left\r\n\r\n if (this.ignoreSticky) removeParentSticky(this.element)\r\n if (this.ignoreTransform) {\r\n top = offsetTop(this.element)\r\n left = offsetLeft(this.element)\r\n } else {\r\n const rect = this.element.getBoundingClientRect()\r\n top = rect.top + scrollTop(this.element)\r\n left = rect.left + scrollLeft(this.element)\r\n }\r\n if (this.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]) => {\r\n const width = entry.borderBoxSize[0].inlineSize\r\n const height = entry.borderBoxSize[0].blockSize\r\n\r\n this.setRect({ width, height })\r\n }\r\n}\r\n","import Slide from './slide'\r\n\r\n// TODO:\r\n// - horizontal\r\n// - fix trackpad snapping too soon due to velocity (fuck Apple)\r\n// - fix wheel scrolling after limits (see console scroll to)\r\n// - fix touch scroll, do not snap when not released\r\n\r\nexport default class Snap {\r\n constructor(\r\n lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n onSnapStart,\r\n onSnapComplete,\r\n } = {}\r\n ) {\r\n this.lenis = lenis\r\n\r\n this.options = {\r\n type,\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold,\r\n }\r\n\r\n this.type = type\r\n this.elements = new Map()\r\n this.snaps = new Map()\r\n\r\n this.velocityThreshold = velocityThreshold\r\n this.onSnapStart = onSnapStart\r\n this.onSnapComplete = onSnapComplete\r\n\r\n this.viewport = {\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n }\r\n this.onWindowResize()\r\n window.addEventListener('resize', this.onWindowResize)\r\n\r\n this.lenis.on('scroll', this.onScroll)\r\n }\r\n\r\n // debug() {\r\n // const element = document.createElement('div')\r\n // element.style.cssText = `\r\n // position: fixed;\r\n // background: red;\r\n // border-bottom: 1px solid red;\r\n // left: 0;\r\n // right: 0;\r\n // top: 0;\r\n // z-index: 9999;\r\n // `\r\n // document.body.appendChild(element)\r\n // }\r\n\r\n destroy() {\r\n this.lenis.off('scroll', this.onScroll)\r\n window.removeEventListener('resize', this.onWindowResize)\r\n this.elements.forEach((slide) => slide.destroy())\r\n }\r\n\r\n start() {\r\n this.isStopped = false\r\n }\r\n\r\n stop() {\r\n this.isStopped = true\r\n }\r\n\r\n add(value) {\r\n const id = crypto.randomUUID()\r\n\r\n this.snaps.set(id, value)\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element, options = {}) {\r\n const id = crypto.randomUUID()\r\n\r\n this.elements.set(id, new Slide(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id) {\r\n this.elements.delete(id)\r\n }\r\n\r\n onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n onScroll = ({\r\n scroll,\r\n limit,\r\n lastVelocity,\r\n velocity,\r\n isScrolling,\r\n isTouching,\r\n userData,\r\n }) => {\r\n if (this.isStopped) return\r\n // console.log(scroll, velocity, type)\r\n\r\n // return\r\n const isDecelerating = Math.abs(lastVelocity) > Math.abs(velocity)\r\n const isTurningBack =\r\n Math.sign(lastVelocity) !== Math.sign(velocity) && velocity !== 0\r\n\r\n // console.log({ lastVelocity, velocity, isTurningBack, isDecelerating })\r\n\r\n // console.log('onScroll')\r\n\r\n if (\r\n Math.abs(velocity) < this.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n scroll = Math.ceil(scroll)\r\n\r\n let snaps = [0, ...this.snaps.values(), limit]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let snap\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n snap = rect.top\r\n } else if (align === 'center') {\r\n snap = rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n snap = rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (snap !== undefined) {\r\n snaps.push(Math.ceil(snap))\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a) - Math.abs(b))\r\n\r\n let prevSnap = snaps.findLast((snap) => snap <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap)\r\n\r\n let nextSnap = snaps.find((snap) => snap >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap)\r\n\r\n if (\r\n this.type === 'mandatory' ||\r\n (this.type === 'proximity' && distance <= this.viewport.height)\r\n ) {\r\n // this.__isScrolling = true\r\n // this.onSnapStart?.(snap)\r\n\r\n // console.log('scroll to')\r\n\r\n this.lenis.scrollTo(snap, {\r\n lerp: this.options.lerp,\r\n easing: this.options.easing,\r\n duration: this.options.duration,\r\n userData: { initiator: 'snap' },\r\n onStart: () => {\r\n this.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\r\n }\r\n }\r\n}\r\n"],"names":["removeParentSticky","element","getComputedStyle","position","style","setProperty","dataset","sticky","offsetParent","addParentSticky","removeProperty","offsetTop","accumulator","top","offsetLeft","left","scrollTop","window","scrollY","scrollLeft","scrollX","Slide","constructor","align","ignoreSticky","ignoreTransform","this","flat","rect","wrapperResizeObserver","ResizeObserver","onWrapperResize","observe","document","body","resizeObserver","onResize","destroy","disconnect","setRect","width","height","y","x","bottom","right","getBoundingClientRect","entry","borderBoxSize","inlineSize","blockSize","Snap","lenis","type","lerp","easing","duration","velocityThreshold","onSnapStart","onSnapComplete","onWindowResize","viewport","innerWidth","innerHeight","onScroll","scroll","limit","lastVelocity","velocity","isScrolling","isTouching","userData","isStopped","isDecelerating","Math","abs","isTurningBack","sign","initiator","ceil","snaps","values","elements","forEach","snap","undefined","push","sort","a","b","prevSnap","findLast","distanceToPrevSnap","nextSnap","find","length","distance","scrollTo","options","onStart","_a","call","onComplete","Map","addEventListener","on","off","removeEventListener","slide","start","stop","add","value","id","crypto","randomUUID","set","remove","delete","addElement","removeElement"],"mappings":"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"} \ No newline at end of file