UNPKG

@studio-freight/lenis

Version:

Lenis is a smooth scroll library to normalize and smooth the scrolling experience across devices

1 lines 38.7 kB
{"version":3,"file":"lenis.mjs","sources":["../src/maths.js","../src/animate.js","../src/dimensions.js","../src/debounce.js","../src/emitter.js","../src/virtual-scroll.js","../../src/index.ts"],"sourcesContent":["// Clamp a value between a minimum and maximum value\r\nexport function clamp(min, input, max) {\r\n return Math.max(min, Math.min(input, max))\r\n}\r\n\r\n// Truncate a floating-point number to a specified number of decimal places\r\nexport function truncate(value, decimals = 0) {\r\n return parseFloat(value.toFixed(decimals))\r\n}\r\n\r\n// Linearly interpolate between two values using an amount (0 <= t <= 1)\r\nexport function lerp(x, y, t) {\r\n return (1 - t) * x + t * y\r\n}\r\n\r\n// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/\r\nexport function damp(x, y, lambda, dt) {\r\n return lerp(x, y, 1 - Math.exp(-lambda * dt))\r\n}\r\n\r\n// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor\r\n// https://anguscroll.com/just/just-modulo\r\nexport function modulo(n, d) {\r\n return ((n % d) + d) % d\r\n}\r\n","import { clamp, damp } from './maths'\r\n\r\n// Animate class to handle value animations with lerping or easing\r\nexport class Animate {\r\n // Advance the animation by the given delta time\r\n advance(deltaTime) {\r\n if (!this.isRunning) return\r\n\r\n let completed = false\r\n\r\n if (this.lerp) {\r\n this.value = damp(this.value, this.to, this.lerp * 60, deltaTime)\r\n if (Math.round(this.value) === this.to) {\r\n this.value = this.to\r\n completed = true\r\n }\r\n } else {\r\n this.currentTime += deltaTime\r\n const linearProgress = clamp(0, this.currentTime / this.duration, 1)\r\n\r\n completed = linearProgress >= 1\r\n const easedProgress = completed ? 1 : this.easing(linearProgress)\r\n this.value = this.from + (this.to - this.from) * easedProgress\r\n }\r\n\r\n // Call the onUpdate callback with the current value and completed status\r\n this.onUpdate?.(this.value, completed)\r\n\r\n if (completed) {\r\n this.stop()\r\n }\r\n }\r\n\r\n // Stop the animation\r\n stop() {\r\n this.isRunning = false\r\n }\r\n\r\n // Set up the animation from a starting value to an ending value\r\n // with optional parameters for lerping, duration, easing, and onUpdate callback\r\n fromTo(\r\n from,\r\n to,\r\n { lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }\r\n ) {\r\n this.from = this.value = from\r\n this.to = to\r\n this.lerp = lerp\r\n this.duration = duration\r\n this.easing = easing\r\n this.currentTime = 0\r\n this.isRunning = true\r\n\r\n onStart?.()\r\n this.onUpdate = onUpdate\r\n }\r\n}\r\n","import { debounce } from './debounce'\r\n\r\nexport class Dimensions {\r\n constructor({\r\n wrapper,\r\n content,\r\n autoResize = true,\r\n debounce: debounceValue = 250,\r\n } = {}) {\r\n this.wrapper = wrapper\r\n this.content = content\r\n\r\n if (autoResize) {\r\n this.debouncedResize = debounce(this.resize, debounceValue)\r\n\r\n if (this.wrapper === window) {\r\n window.addEventListener('resize', this.debouncedResize, false)\r\n } else {\r\n this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize)\r\n this.wrapperResizeObserver.observe(this.wrapper)\r\n }\r\n\r\n this.contentResizeObserver = new ResizeObserver(this.debouncedResize)\r\n this.contentResizeObserver.observe(this.content)\r\n }\r\n\r\n this.resize()\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver?.disconnect()\r\n this.contentResizeObserver?.disconnect()\r\n window.removeEventListener('resize', this.debouncedResize, false)\r\n }\r\n\r\n resize = () => {\r\n this.onWrapperResize()\r\n this.onContentResize()\r\n }\r\n\r\n onWrapperResize = () => {\r\n if (this.wrapper === window) {\r\n this.width = window.innerWidth\r\n this.height = window.innerHeight\r\n } else {\r\n this.width = this.wrapper.clientWidth\r\n this.height = this.wrapper.clientHeight\r\n }\r\n }\r\n\r\n onContentResize = () => {\r\n if (this.wrapper === window) {\r\n this.scrollHeight = this.content.scrollHeight\r\n this.scrollWidth = this.content.scrollWidth\r\n } else {\r\n this.scrollHeight = this.wrapper.scrollHeight\r\n this.scrollWidth = this.wrapper.scrollWidth\r\n }\r\n }\r\n\r\n get limit() {\r\n return {\r\n x: this.scrollWidth - this.width,\r\n y: this.scrollHeight - this.height,\r\n }\r\n }\r\n}\r\n","export function debounce(callback, delay) {\r\n let timer\r\n return function () {\r\n let args = arguments\r\n let context = this\r\n clearTimeout(timer)\r\n timer = setTimeout(function () {\r\n callback.apply(context, args)\r\n }, delay)\r\n }\r\n}\r\n","export class Emitter {\r\n constructor() {\r\n this.events = {}\r\n }\r\n\r\n emit(event, ...args) {\r\n let callbacks = this.events[event] || []\r\n for (let i = 0, length = callbacks.length; i < length; i++) {\r\n callbacks[i](...args)\r\n }\r\n }\r\n\r\n on(event, cb) {\r\n // Add the callback to the event's callback list, or create a new list with the callback\r\n this.events[event]?.push(cb) || (this.events[event] = [cb])\r\n\r\n // Return an unsubscribe function\r\n return () => {\r\n this.events[event] = this.events[event]?.filter((i) => cb !== i)\r\n }\r\n }\r\n\r\n off(event, callback) {\r\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\r\n }\r\n\r\n destroy() {\r\n this.events = {}\r\n }\r\n}\r\n","import { Emitter } from './emitter'\r\n\r\nconst LINE_HEIGHT = 100 / 6\r\n\r\nexport class VirtualScroll {\r\n constructor(element, { wheelMultiplier = 1, touchMultiplier = 1 }) {\r\n this.element = element\r\n this.wheelMultiplier = wheelMultiplier\r\n this.touchMultiplier = touchMultiplier\r\n\r\n this.touchStart = {\r\n x: null,\r\n y: null,\r\n }\r\n\r\n this.emitter = new Emitter()\r\n window.addEventListener('resize', this.onWindowResize, false)\r\n this.onWindowResize()\r\n\r\n this.element.addEventListener('wheel', this.onWheel, { passive: false })\r\n this.element.addEventListener('touchstart', this.onTouchStart, {\r\n passive: false,\r\n })\r\n this.element.addEventListener('touchmove', this.onTouchMove, {\r\n passive: false,\r\n })\r\n this.element.addEventListener('touchend', this.onTouchEnd, {\r\n passive: false,\r\n })\r\n }\r\n\r\n // Add an event listener for the given event and callback\r\n on(event, callback) {\r\n return this.emitter.on(event, callback)\r\n }\r\n\r\n // Remove all event listeners and clean up\r\n destroy() {\r\n this.emitter.destroy()\r\n\r\n window.removeEventListener('resize', this.onWindowResize, false)\r\n\r\n this.element.removeEventListener('wheel', this.onWheel, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchstart', this.onTouchStart, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchmove', this.onTouchMove, {\r\n passive: false,\r\n })\r\n this.element.removeEventListener('touchend', this.onTouchEnd, {\r\n passive: false,\r\n })\r\n }\r\n\r\n // Event handler for 'touchstart' event\r\n onTouchStart = (event) => {\r\n const { clientX, clientY } = event.targetTouches\r\n ? event.targetTouches[0]\r\n : event\r\n\r\n this.touchStart.x = clientX\r\n this.touchStart.y = clientY\r\n\r\n this.lastDelta = {\r\n x: 0,\r\n y: 0,\r\n }\r\n\r\n this.emitter.emit('scroll', {\r\n deltaX: 0,\r\n deltaY: 0,\r\n event,\r\n })\r\n }\r\n\r\n // Event handler for 'touchmove' event\r\n onTouchMove = (event) => {\r\n const { clientX, clientY } = event.targetTouches\r\n ? event.targetTouches[0]\r\n : event\r\n\r\n const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier\r\n const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier\r\n\r\n this.touchStart.x = clientX\r\n this.touchStart.y = clientY\r\n\r\n this.lastDelta = {\r\n x: deltaX,\r\n y: deltaY,\r\n }\r\n\r\n this.emitter.emit('scroll', {\r\n deltaX,\r\n deltaY,\r\n event,\r\n })\r\n }\r\n\r\n onTouchEnd = (event) => {\r\n this.emitter.emit('scroll', {\r\n deltaX: this.lastDelta.x,\r\n deltaY: this.lastDelta.y,\r\n event,\r\n })\r\n }\r\n\r\n // Event handler for 'wheel' event\r\n onWheel = (event) => {\r\n let { deltaX, deltaY, deltaMode } = event\r\n\r\n const multiplierX =\r\n deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowWidth : 1\r\n const multiplierY =\r\n deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowHeight : 1\r\n\r\n deltaX *= multiplierX\r\n deltaY *= multiplierY\r\n\r\n deltaX *= this.wheelMultiplier\r\n deltaY *= this.wheelMultiplier\r\n\r\n this.emitter.emit('scroll', { deltaX, deltaY, event })\r\n }\r\n\r\n onWindowResize = () => {\r\n this.windowWidth = window.innerWidth\r\n this.windowHeight = window.innerHeight\r\n }\r\n}\r\n","import { version } from '../package.json'\r\nimport { Animate } from './animate'\r\nimport { Dimensions } from './dimensions'\r\nimport { Emitter } from './emitter'\r\nimport { clamp, modulo } from './maths'\r\nimport { VirtualScroll } from './virtual-scroll'\r\n\r\n// Technical explanation\r\n// - listen to 'wheel' events\r\n// - prevent 'wheel' event to prevent scroll\r\n// - normalize wheel delta\r\n// - add delta to targetScroll\r\n// - animate scroll to targetScroll (smooth context)\r\n// - if animation is not running, listen to 'scroll' events (native context)\r\n\r\ntype EasingFunction = (t: number) => number\r\ntype Orientation = 'vertical' | 'horizontal'\r\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\r\n\r\nexport type LenisOptions = {\r\n wrapper?: Window | HTMLElement\r\n content?: HTMLElement\r\n wheelEventsTarget?: Window | HTMLElement\r\n eventsTarget?: Window | HTMLElement\r\n smoothWheel?: boolean\r\n syncTouch?: boolean\r\n syncTouchLerp?: number\r\n touchInertiaMultiplier?: number\r\n duration?: number\r\n easing?: EasingFunction\r\n lerp?: number\r\n infinite?: boolean\r\n orientation?: Orientation\r\n gestureOrientation?: GestureOrientation\r\n touchMultiplier?: number\r\n wheelMultiplier?: number\r\n autoResize?: boolean\r\n __experimental__naiveDimensions?: boolean\r\n}\r\n\r\nexport default class Lenis {\r\n __isSmooth: boolean = false // true if scroll should be animated\r\n __isScrolling: boolean = false // true when scroll is animating\r\n __isStopped: boolean = false // true if user should not be able to scroll - enable/disable programmatically\r\n __isLocked: boolean = false // same as isStopped but enabled/disabled when scroll reaches target\r\n\r\n constructor({\r\n wrapper = window,\r\n content = document.documentElement,\r\n wheelEventsTarget = wrapper, // deprecated\r\n eventsTarget = wheelEventsTarget,\r\n smoothWheel = true,\r\n syncTouch = false,\r\n syncTouchLerp = 0.075,\r\n touchInertiaMultiplier = 35,\r\n duration, // in seconds\r\n easing = (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),\r\n lerp = !duration && 0.1,\r\n infinite = false,\r\n orientation = 'vertical', // vertical, horizontal\r\n gestureOrientation = 'vertical', // vertical, horizontal, both\r\n touchMultiplier = 1,\r\n wheelMultiplier = 1,\r\n autoResize = true,\r\n __experimental__naiveDimensions = false,\r\n }: LenisOptions = {}) {\r\n window.lenisVersion = version\r\n\r\n // if wrapper is html or body, fallback to window\r\n if (wrapper === document.documentElement || wrapper === document.body) {\r\n wrapper = window\r\n }\r\n\r\n this.options = {\r\n wrapper,\r\n content,\r\n wheelEventsTarget,\r\n eventsTarget,\r\n smoothWheel,\r\n syncTouch,\r\n syncTouchLerp,\r\n touchInertiaMultiplier,\r\n duration,\r\n easing,\r\n lerp,\r\n infinite,\r\n gestureOrientation,\r\n orientation,\r\n touchMultiplier,\r\n wheelMultiplier,\r\n autoResize,\r\n __experimental__naiveDimensions,\r\n }\r\n\r\n this.animate = new Animate()\r\n this.emitter = new Emitter()\r\n this.dimensions = new Dimensions({ wrapper, content, autoResize })\r\n this.toggleClassName('lenis', true)\r\n\r\n this.velocity = 0\r\n this.isLocked = false\r\n this.isStopped = false\r\n this.isSmooth = syncTouch || smoothWheel\r\n this.isScrolling = false\r\n this.targetScroll = this.animatedScroll = this.actualScroll\r\n\r\n this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false)\r\n\r\n this.virtualScroll = new VirtualScroll(eventsTarget, {\r\n touchMultiplier,\r\n wheelMultiplier,\r\n })\r\n this.virtualScroll.on('scroll', this.onVirtualScroll)\r\n }\r\n\r\n destroy() {\r\n this.emitter.destroy()\r\n\r\n this.options.wrapper.removeEventListener(\r\n 'scroll',\r\n this.onNativeScroll,\r\n false\r\n )\r\n\r\n this.virtualScroll.destroy()\r\n this.dimensions.destroy()\r\n\r\n this.toggleClassName('lenis', false)\r\n this.toggleClassName('lenis-smooth', false)\r\n this.toggleClassName('lenis-scrolling', false)\r\n this.toggleClassName('lenis-stopped', false)\r\n this.toggleClassName('lenis-locked', false)\r\n }\r\n\r\n on(event: string, callback: Function) {\r\n return this.emitter.on(event, callback)\r\n }\r\n\r\n off(event: string, callback: Function) {\r\n return this.emitter.off(event, callback)\r\n }\r\n\r\n private setScroll(scroll) {\r\n // apply scroll value immediately\r\n if (this.isHorizontal) {\r\n this.rootElement.scrollLeft = scroll\r\n } else {\r\n this.rootElement.scrollTop = scroll\r\n }\r\n }\r\n\r\n private onVirtualScroll = ({ deltaX, deltaY, event }) => {\r\n // keep zoom feature\r\n if (event.ctrlKey) return\r\n\r\n const isTouch = event.type.includes('touch')\r\n const isWheel = event.type.includes('wheel')\r\n\r\n const isTapToStop =\r\n this.options.syncTouch &&\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 node.hasAttribute?.('data-lenis-prevent') ||\r\n (isTouch && node.hasAttribute?.('data-lenis-prevent-touch')) ||\r\n (isWheel && node.hasAttribute?.('data-lenis-prevent-wheel')) ||\r\n (node.classList?.contains('lenis') &&\r\n !node.classList?.contains('lenis-stopped')) // nested lenis instance\r\n )\r\n )\r\n return\r\n\r\n if (this.isStopped || this.isLocked) {\r\n event.preventDefault() // this will stop forwarding the event to the parent, this is problematic\r\n return\r\n }\r\n\r\n this.isSmooth =\r\n (this.options.syncTouch && isTouch) ||\r\n (this.options.smoothWheel && isWheel)\r\n\r\n if (!this.isSmooth) {\r\n this.isScrolling = false\r\n this.animate.stop()\r\n return\r\n }\r\n\r\n event.preventDefault()\r\n\r\n let delta = deltaY\r\n if (this.options.gestureOrientation === 'both') {\r\n delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX\r\n } else if (this.options.gestureOrientation === 'horizontal') {\r\n delta = deltaX\r\n }\r\n\r\n const syncTouch = isTouch && this.options.syncTouch\r\n const isTouchEnd = isTouch && event.type === 'touchend'\r\n\r\n const hasTouchInertia = isTouchEnd && Math.abs(delta) > 5\r\n\r\n if (hasTouchInertia) {\r\n delta = this.velocity * this.options.touchInertiaMultiplier\r\n }\r\n\r\n this.scrollTo(this.targetScroll + delta, {\r\n programmatic: false,\r\n ...(syncTouch\r\n ? {\r\n lerp: hasTouchInertia ? this.options.syncTouchLerp : 1,\r\n }\r\n : {\r\n lerp: this.options.lerp,\r\n duration: this.options.duration,\r\n easing: this.options.easing,\r\n }),\r\n })\r\n }\r\n\r\n resize() {\r\n this.dimensions.resize()\r\n }\r\n\r\n private emit() {\r\n this.emitter.emit('scroll', this)\r\n }\r\n\r\n private onNativeScroll = () => {\r\n if (this.__preventNextScrollEvent) return\r\n\r\n if (!this.isScrolling) {\r\n const lastScroll = this.animatedScroll\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.velocity = 0\r\n this.direction = Math.sign(this.animatedScroll - lastScroll)\r\n this.emit()\r\n }\r\n }\r\n\r\n private reset() {\r\n this.isLocked = false\r\n this.isScrolling = false\r\n this.animatedScroll = this.targetScroll = this.actualScroll\r\n this.velocity = 0\r\n this.animate.stop()\r\n }\r\n\r\n start() {\r\n if (!this.isStopped) return\r\n this.isStopped = false\r\n\r\n this.reset()\r\n }\r\n\r\n stop() {\r\n if (this.isStopped) return\r\n this.isStopped = true\r\n this.animate.stop()\r\n\r\n this.reset()\r\n }\r\n\r\n raf(time: number) {\r\n const deltaTime = time - (this.time || time)\r\n this.time = time\r\n\r\n this.animate.advance(deltaTime * 0.001)\r\n }\r\n\r\n scrollTo(\r\n target: number | string | HTMLElement,\r\n {\r\n offset = 0,\r\n immediate = false,\r\n lock = false,\r\n duration = this.options.duration,\r\n easing = this.options.easing,\r\n lerp = !duration && this.options.lerp,\r\n onComplete,\r\n force = false, // scroll even if stopped\r\n programmatic = true, // called from outside of the class\r\n }: {\r\n offset?: number\r\n immediate?: boolean\r\n lock?: boolean\r\n duration?: number\r\n easing?: EasingFunction\r\n lerp?: number\r\n onComplete?: (lenis: Lenis) => void\r\n force?: boolean\r\n programmatic?: boolean\r\n } = {}\r\n ) {\r\n if ((this.isStopped || this.isLocked) && !force) return\r\n\r\n // keywords\r\n if (['top', 'left', 'start'].includes(target)) {\r\n target = 0\r\n } else if (['bottom', 'right', 'end'].includes(target)) {\r\n target = this.limit\r\n } else {\r\n let node\r\n\r\n if (typeof target === 'string') {\r\n // CSS selector\r\n node = document.querySelector(target)\r\n } else if (target?.nodeType) {\r\n // Node element\r\n node = target\r\n }\r\n\r\n if (node) {\r\n if (this.options.wrapper !== window) {\r\n // nested scroll offset correction\r\n const wrapperRect = this.options.wrapper.getBoundingClientRect()\r\n offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top\r\n }\r\n\r\n const rect = node.getBoundingClientRect()\r\n\r\n target =\r\n (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll\r\n }\r\n }\r\n\r\n if (typeof target !== 'number') return\r\n\r\n target += offset\r\n target = Math.round(target)\r\n\r\n if (this.options.infinite) {\r\n if (programmatic) {\r\n this.targetScroll = this.animatedScroll = this.scroll\r\n }\r\n } else {\r\n target = clamp(0, target, this.limit)\r\n }\r\n\r\n if (immediate) {\r\n this.animatedScroll = this.targetScroll = target\r\n this.setScroll(this.scroll)\r\n this.reset()\r\n onComplete?.(this)\r\n return\r\n }\r\n\r\n if (!programmatic) {\r\n if (target === this.targetScroll) return\r\n\r\n this.targetScroll = target\r\n }\r\n\r\n this.animate.fromTo(this.animatedScroll, target, {\r\n duration,\r\n easing,\r\n lerp,\r\n onStart: () => {\r\n // started\r\n if (lock) this.isLocked = true\r\n this.isScrolling = true\r\n },\r\n onUpdate: (value: number, completed: boolean) => {\r\n this.isScrolling = true\r\n\r\n // updated\r\n this.velocity = value - this.animatedScroll\r\n this.direction = Math.sign(this.velocity)\r\n\r\n this.animatedScroll = value\r\n this.setScroll(this.scroll)\r\n\r\n if (programmatic) {\r\n // wheel during programmatic should stop it\r\n this.targetScroll = value\r\n }\r\n\r\n if (!completed) this.emit()\r\n\r\n if (completed) {\r\n this.reset()\r\n this.emit()\r\n onComplete?.(this)\r\n\r\n // avoid emitting event twice\r\n this.__preventNextScrollEvent = true\r\n requestAnimationFrame(() => {\r\n delete this.__preventNextScrollEvent\r\n })\r\n }\r\n },\r\n })\r\n }\r\n\r\n get rootElement() {\r\n return this.options.wrapper === window\r\n ? document.documentElement\r\n : this.options.wrapper\r\n }\r\n\r\n get limit() {\r\n if (this.options.__experimental__naiveDimensions) {\r\n if (this.isHorizontal) {\r\n return this.rootElement.scrollWidth - this.rootElement.clientWidth\r\n } else {\r\n return this.rootElement.scrollHeight - this.rootElement.clientHeight\r\n }\r\n } else {\r\n return this.dimensions.limit[this.isHorizontal ? 'x' : 'y']\r\n }\r\n }\r\n\r\n get isHorizontal() {\r\n return this.options.orientation === 'horizontal'\r\n }\r\n\r\n get actualScroll() {\r\n // value browser takes into account\r\n return this.isHorizontal\r\n ? this.rootElement.scrollLeft\r\n : this.rootElement.scrollTop\r\n }\r\n\r\n get scroll() {\r\n return this.options.infinite\r\n ? modulo(this.animatedScroll, this.limit)\r\n : this.animatedScroll\r\n }\r\n\r\n get progress() {\r\n // avoid progress to be NaN\r\n return this.limit === 0 ? 1 : this.scroll / this.limit\r\n }\r\n\r\n get isSmooth() {\r\n return this.__isSmooth\r\n }\r\n\r\n private set isSmooth(value: boolean) {\r\n if (this.__isSmooth !== value) {\r\n this.__isSmooth = value\r\n this.toggleClassName('lenis-smooth', value)\r\n }\r\n }\r\n\r\n get isScrolling() {\r\n return this.__isScrolling\r\n }\r\n\r\n private set isScrolling(value: boolean) {\r\n if (this.__isScrolling !== value) {\r\n this.__isScrolling = value\r\n this.toggleClassName('lenis-scrolling', value)\r\n }\r\n }\r\n\r\n get isStopped() {\r\n return this.__isStopped\r\n }\r\n\r\n private set isStopped(value: boolean) {\r\n if (this.__isStopped !== value) {\r\n this.__isStopped = value\r\n this.toggleClassName('lenis-stopped', value)\r\n }\r\n }\r\n\r\n get isLocked() {\r\n return this.__isLocked\r\n }\r\n\r\n private set isLocked(value: boolean) {\r\n if (this.__isLocked !== value) {\r\n this.__isLocked = value\r\n this.toggleClassName('lenis-locked', value)\r\n }\r\n }\r\n\r\n get className() {\r\n let className = 'lenis'\r\n if (this.isStopped) className += ' lenis-stopped'\r\n if (this.isLocked) className += ' lenis-locked'\r\n if (this.isScrolling) className += ' lenis-scrolling'\r\n if (this.isSmooth) className += ' lenis-smooth'\r\n return className\r\n }\r\n\r\n private toggleClassName(name: string, value: boolean) {\r\n this.rootElement.classList.toggle(name, value)\r\n this.emitter.emit('className change', this)\r\n }\r\n}\r\n"],"names":["clamp","min","input","max","Math","Animate","advance","deltaTime","this","isRunning","completed","lerp","value","x","y","to","lambda","dt","t","exp","round","currentTime","linearProgress","duration","easedProgress","easing","from","onUpdate","stop","fromTo","onStart","Dimensions","constructor","wrapper","content","autoResize","debounce","debounceValue","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","resize","window","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","removeEventListener","onWrapperResize","onContentResize","width","innerWidth","height","innerHeight","clientWidth","clientHeight","scrollHeight","scrollWidth","limit","Emitter","events","emit","event","callbacks","i","length","on","cb","push","filter","off","LINE_HEIGHT","VirtualScroll","element","wheelMultiplier","touchMultiplier","touchStart","emitter","onWindowResize","onWheel","passive","onTouchStart","onTouchMove","onTouchEnd","clientX","clientY","targetTouches","lastDelta","deltaX","deltaY","deltaMode","windowWidth","windowHeight","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","__experimental__naiveDimensions","__isSmooth","__isScrolling","__isStopped","__isLocked","onVirtualScroll","ctrlKey","isTouch","type","includes","isWheel","options","isStopped","isLocked","reset","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","_a","hasAttribute","call","_b","_c","classList","_d","contains","_e","preventDefault","isSmooth","isScrolling","animate","delta","abs","hasTouchInertia","velocity","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__preventNextScrollEvent","lastScroll","animatedScroll","actualScroll","direction","sign","lenisVersion","body","dimensions","toggleClassName","virtualScroll","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","time","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","requestAnimationFrame","n","d","progress","className","name","toggle"],"mappings":"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"}