lenis 1.1.6-dev.0 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -192,7 +192,10 @@
192
192
  const distance = Math.abs(scroll - snap.value);
193
193
  if (this.options.type === 'mandatory' ||
194
194
  (this.options.type === 'proximity' &&
195
- distance <= this.lenis.dimensions.height)) {
195
+ distance <=
196
+ (isHorizontal
197
+ ? this.lenis.dimensions.width
198
+ : this.lenis.dimensions.height))) {
196
199
  this.lenis.scrollTo(snap.value, {
197
200
  lerp: this.options.lerp,
198
201
  easing: this.options.easing,
@@ -1 +1 @@
1
- {"version":3,"file":"lenis-snap.js","sources":["../src/debounce.js","../../src/element.ts","../../src/uid.ts","../../src/index.ts"],"sourcesContent":["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","function removeParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction offsetTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport type SnapElementOptions = {\r\n align?: string[]\r\n ignoreSticky?: boolean\r\n ignoreTransform?: boolean\r\n}\r\n\r\ntype Rect = {\r\n top: number\r\n left: number\r\n width: number\r\n height: number\r\n x: number\r\n y: number\r\n bottom: number\r\n right: number\r\n element: HTMLElement\r\n}\r\n\r\nexport class SnapElement {\r\n element: HTMLElement\r\n options: SnapElementOptions\r\n align: string[]\r\n // @ts-ignore\r\n rect: Rect = {}\r\n wrapperResizeObserver: ResizeObserver\r\n resizeObserver: ResizeObserver\r\n\r\n constructor(\r\n element: HTMLElement,\r\n {\r\n align = ['start'],\r\n ignoreSticky = true,\r\n ignoreTransform = false,\r\n }: SnapElementOptions = {}\r\n ) {\r\n this.element = element\r\n\r\n this.options = { align, ignoreSticky, ignoreTransform }\r\n\r\n // this.ignoreSticky = ignoreSticky\r\n // this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n // TODO: assing rect immediately\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n this.onWrapperResize()\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n this.setRect({\r\n width: this.element.offsetWidth,\r\n height: this.element.offsetHeight,\r\n })\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({\r\n top,\r\n left,\r\n width,\r\n height,\r\n element,\r\n }: {\r\n top?: number\r\n left?: number\r\n width?: number\r\n height?: number\r\n element?: HTMLElement\r\n } = {}) {\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.options.ignoreSticky) removeParentSticky(this.element)\r\n if (this.options.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.options.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]: ResizeObserverEntry[]) => {\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","let index = 0\r\n\r\nexport type UID = number\r\n\r\nexport function uid(): UID {\r\n return index++\r\n}\r\n","import Lenis from 'lenis'\r\nimport { debounce } from './debounce'\r\nimport { SnapElement, SnapElementOptions } from './element'\r\nimport { UID, uid } from './uid'\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// - arrow, spacebar\r\n\r\ntype Viewport = {\r\n width: number\r\n height: number\r\n}\r\n\r\ntype SnapItem = {\r\n value: number\r\n userData: object\r\n}\r\n\r\nexport type SnapOptions = {\r\n type?: 'mandatory' | 'proximity'\r\n lerp?: number\r\n easing?: (t: number) => number\r\n duration?: number\r\n velocityThreshold?: number\r\n debounce?: number\r\n onSnapStart?: (t: SnapItem) => void\r\n onSnapComplete?: (t: SnapItem) => void\r\n}\r\n\r\nexport default class Snap {\r\n lenis: Lenis\r\n options: SnapOptions\r\n elements: Map<UID, SnapElement>\r\n snaps: Map<UID, SnapItem>\r\n viewport: Viewport\r\n isStopped: Boolean = false\r\n onSnapDebounced: Function\r\n\r\n constructor(\r\n lenis: Lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n debounce: debounceDelay = 0,\r\n onSnapStart,\r\n onSnapComplete,\r\n }: SnapOptions = {}\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 debounce: debounceDelay,\r\n onSnapStart,\r\n onSnapComplete,\r\n } as SnapOptions\r\n\r\n this.elements = new Map()\r\n this.snaps = 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, false)\r\n\r\n this.onSnapDebounced = debounce(this.onSnap, this.options.debounce)\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, false)\r\n this.elements.forEach((element) => element.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: number, userData: object = {}) {\r\n const id = uid()\r\n\r\n this.snaps.set(id, { value, userData })\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id: UID) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element: HTMLElement, options = {} as SnapElementOptions) {\r\n const id = uid()\r\n\r\n this.elements.set(id, new SnapElement(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id: UID) {\r\n this.elements.delete(id)\r\n }\r\n\r\n private onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n private onScroll = ({\r\n // scroll,\r\n // limit,\r\n lastVelocity,\r\n velocity,\r\n // isScrolling,\r\n userData,\r\n }: // isHorizontal,\r\n Lenis) => {\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.options.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n this.onSnapDebounced()\r\n }\r\n }\r\n\r\n private onSnap = () => {\r\n let { scroll, isHorizontal } = this.lenis\r\n scroll = Math.ceil(this.lenis.scroll)\r\n\r\n let snaps = [...this.snaps.values()] as SnapItem[]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let value: number | undefined\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n value = rect.top\r\n } else if (align === 'center') {\r\n value = isHorizontal\r\n ? rect.left + rect.width / 2 - this.viewport.width / 2\r\n : rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n value = isHorizontal\r\n ? rect.left + rect.width - this.viewport.width\r\n : rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (typeof value === 'number') {\r\n snaps.push({ value: Math.ceil(value), userData: {} })\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a.value) - Math.abs(b.value))\r\n\r\n let prevSnap = snaps.findLast(({ value }) => value <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap.value)\r\n\r\n let nextSnap = snaps.find(({ value }) => value >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap.value)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap.value)\r\n\r\n if (\r\n this.options.type === 'mandatory' ||\r\n (this.options.type === 'proximity' &&\r\n distance <= this.lenis.dimensions.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.value, {\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.options.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.options.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lenis-snap.js","sources":["../src/debounce.js","../../src/element.ts","../../src/uid.ts","../../src/index.ts"],"sourcesContent":["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","function removeParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction offsetTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport type SnapElementOptions = {\r\n align?: string[]\r\n ignoreSticky?: boolean\r\n ignoreTransform?: boolean\r\n}\r\n\r\ntype Rect = {\r\n top: number\r\n left: number\r\n width: number\r\n height: number\r\n x: number\r\n y: number\r\n bottom: number\r\n right: number\r\n element: HTMLElement\r\n}\r\n\r\nexport class SnapElement {\r\n element: HTMLElement\r\n options: SnapElementOptions\r\n align: string[]\r\n // @ts-ignore\r\n rect: Rect = {}\r\n wrapperResizeObserver: ResizeObserver\r\n resizeObserver: ResizeObserver\r\n\r\n constructor(\r\n element: HTMLElement,\r\n {\r\n align = ['start'],\r\n ignoreSticky = true,\r\n ignoreTransform = false,\r\n }: SnapElementOptions = {}\r\n ) {\r\n this.element = element\r\n\r\n this.options = { align, ignoreSticky, ignoreTransform }\r\n\r\n // this.ignoreSticky = ignoreSticky\r\n // this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n // TODO: assing rect immediately\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n this.onWrapperResize()\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n this.setRect({\r\n width: this.element.offsetWidth,\r\n height: this.element.offsetHeight,\r\n })\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({\r\n top,\r\n left,\r\n width,\r\n height,\r\n element,\r\n }: {\r\n top?: number\r\n left?: number\r\n width?: number\r\n height?: number\r\n element?: HTMLElement\r\n } = {}) {\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.options.ignoreSticky) removeParentSticky(this.element)\r\n if (this.options.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.options.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]: ResizeObserverEntry[]) => {\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","let index = 0\r\n\r\nexport type UID = number\r\n\r\nexport function uid(): UID {\r\n return index++\r\n}\r\n","import Lenis from 'lenis'\r\nimport { debounce } from './debounce'\r\nimport { SnapElement, SnapElementOptions } from './element'\r\nimport { UID, uid } from './uid'\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// - arrow, spacebar\r\n\r\ntype Viewport = {\r\n width: number\r\n height: number\r\n}\r\n\r\ntype SnapItem = {\r\n value: number\r\n userData: object\r\n}\r\n\r\nexport type SnapOptions = {\r\n type?: 'mandatory' | 'proximity'\r\n lerp?: number\r\n easing?: (t: number) => number\r\n duration?: number\r\n velocityThreshold?: number\r\n debounce?: number\r\n onSnapStart?: (t: SnapItem) => void\r\n onSnapComplete?: (t: SnapItem) => void\r\n}\r\n\r\nexport default class Snap {\r\n lenis: Lenis\r\n options: SnapOptions\r\n elements: Map<UID, SnapElement>\r\n snaps: Map<UID, SnapItem>\r\n viewport: Viewport\r\n isStopped: Boolean = false\r\n onSnapDebounced: Function\r\n\r\n constructor(\r\n lenis: Lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n debounce: debounceDelay = 0,\r\n onSnapStart,\r\n onSnapComplete,\r\n }: SnapOptions = {}\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 debounce: debounceDelay,\r\n onSnapStart,\r\n onSnapComplete,\r\n } as SnapOptions\r\n\r\n this.elements = new Map()\r\n this.snaps = 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, false)\r\n\r\n this.onSnapDebounced = debounce(this.onSnap, this.options.debounce)\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, false)\r\n this.elements.forEach((element) => element.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: number, userData: object = {}) {\r\n const id = uid()\r\n\r\n this.snaps.set(id, { value, userData })\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id: UID) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element: HTMLElement, options = {} as SnapElementOptions) {\r\n const id = uid()\r\n\r\n this.elements.set(id, new SnapElement(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id: UID) {\r\n this.elements.delete(id)\r\n }\r\n\r\n private onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n private onScroll = ({\r\n // scroll,\r\n // limit,\r\n lastVelocity,\r\n velocity,\r\n // isScrolling,\r\n userData,\r\n }: // isHorizontal,\r\n Lenis) => {\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.options.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n this.onSnapDebounced()\r\n }\r\n }\r\n\r\n private onSnap = () => {\r\n let { scroll, isHorizontal } = this.lenis\r\n scroll = Math.ceil(this.lenis.scroll)\r\n\r\n let snaps = [...this.snaps.values()] as SnapItem[]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let value: number | undefined\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n value = rect.top\r\n } else if (align === 'center') {\r\n value = isHorizontal\r\n ? rect.left + rect.width / 2 - this.viewport.width / 2\r\n : rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n value = isHorizontal\r\n ? rect.left + rect.width - this.viewport.width\r\n : rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (typeof value === 'number') {\r\n snaps.push({ value: Math.ceil(value), userData: {} })\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a.value) - Math.abs(b.value))\r\n\r\n let prevSnap = snaps.findLast(({ value }) => value <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap.value)\r\n\r\n let nextSnap = snaps.find(({ value }) => value >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap.value)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap.value)\r\n\r\n if (\r\n this.options.type === 'mandatory' ||\r\n (this.options.type === 'proximity' &&\r\n distance <=\r\n (isHorizontal\r\n ? this.lenis.dimensions.width\r\n : this.lenis.dimensions.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.value, {\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.options.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.options.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- !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){var e;"true"===(null===(e=null==t?void 0:t.dataset)||void 0===e?void 0:e.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 SnapElement{constructor(t,{align:e=["start"],ignoreSticky:i=!0,ignoreTransform:s=!1}={}){this.rect={},this.onWrapperResize=()=>{let t,e;if(this.options.ignoreSticky&&removeParentSticky(this.element),this.options.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.options.ignoreSticky&&addParentSticky(this.element),this.setRect({top:t,left:e})},this.onResize=([t])=>{const e=t.borderBoxSize[0].inlineSize,i=t.borderBoxSize[0].blockSize;this.setRect({width:e,height:i})},this.element=t,this.options={align:e,ignoreSticky:i,ignoreTransform:s},this.align=[e].flat(),this.wrapperResizeObserver=new ResizeObserver(this.onWrapperResize),this.wrapperResizeObserver.observe(document.body),this.onWrapperResize(),this.resizeObserver=new ResizeObserver(this.onResize),this.resizeObserver.observe(this.element),this.setRect({width:this.element.offsetWidth,height:this.element.offsetHeight})}destroy(){this.wrapperResizeObserver.disconnect(),this.resizeObserver.disconnect()}setRect({top:t,left:e,width:i,height:s,element:o}={}){t=null!=t?t:this.rect.top,e=null!=e?e:this.rect.left,i=null!=i?i:this.rect.width,s=null!=s?s:this.rect.height,o=null!=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)}}let t=0;function uid(){return t++}return class Snap{constructor(t,{type:e="mandatory",lerp:i,easing:s,duration:o,velocityThreshold:n=1,debounce:r=0,onSnapStart:h,onSnapComplete:l}={}){this.isStopped=!1,this.onWindowResize=()=>{this.viewport.width=window.innerWidth,this.viewport.height=window.innerHeight},this.onScroll=({lastVelocity:t,velocity:e,userData:i})=>{if(this.isStopped)return;const s=Math.abs(t)>Math.abs(e),o=Math.sign(t)!==Math.sign(e)&&0!==e;Math.abs(e)<this.options.velocityThreshold&&s&&!o&&"snap"!==(null==i?void 0:i.initiator)&&this.onSnapDebounced()},this.onSnap=()=>{let{scroll:t,isHorizontal:e}=this.lenis;t=Math.ceil(this.lenis.scroll);let i=[...this.snaps.values()];this.elements.forEach((({rect:t,align:s})=>{let o;s.forEach((s=>{"start"===s?o=t.top:"center"===s?o=e?t.left+t.width/2-this.viewport.width/2:t.top+t.height/2-this.viewport.height/2:"end"===s&&(o=e?t.left+t.width-this.viewport.width:t.top+t.height-this.viewport.height),"number"==typeof o&&i.push({value:Math.ceil(o),userData:{}})}))})),i=i.sort(((t,e)=>Math.abs(t.value)-Math.abs(e.value)));let s=i.findLast((({value:e})=>e<=t));void 0===s&&(s=i[0]);const o=Math.abs(t-s.value);let n=i.find((({value:e})=>e>=t));void 0===n&&(n=i[i.length-1]);const r=o<Math.abs(t-n.value)?s:n,h=Math.abs(t-r.value);("mandatory"===this.options.type||"proximity"===this.options.type&&h<=this.lenis.dimensions.height)&&this.lenis.scrollTo(r.value,{lerp:this.options.lerp,easing:this.options.easing,duration:this.options.duration,userData:{initiator:"snap"},onStart:()=>{var t,e;null===(e=(t=this.options).onSnapStart)||void 0===e||e.call(t,r)},onComplete:()=>{var t,e;null===(e=(t=this.options).onSnapComplete)||void 0===e||e.call(t,r)}})},this.lenis=t,this.options={type:e,lerp:i,easing:s,duration:o,velocityThreshold:n,debounce:r,onSnapStart:h,onSnapComplete:l},this.elements=new Map,this.snaps=new Map,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize,!1),this.onSnapDebounced=function debounce(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.onSnap,this.options.debounce),this.lenis.on("scroll",this.onScroll)}destroy(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize,!1),this.elements.forEach((t=>t.destroy()))}start(){this.isStopped=!1}stop(){this.isStopped=!0}add(t,e={}){const i=uid();return this.snaps.set(i,{value:t,userData:e}),()=>this.remove(i)}remove(t){this.snaps.delete(t)}addElement(t,e={}){const i=uid();return this.elements.set(i,new SnapElement(t,e)),()=>this.removeElement(i)}removeElement(t){this.elements.delete(t)}}}));
1
+ !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){var e;"true"===(null===(e=null==t?void 0:t.dataset)||void 0===e?void 0:e.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 SnapElement{constructor(t,{align:e=["start"],ignoreSticky:i=!0,ignoreTransform:s=!1}={}){this.rect={},this.onWrapperResize=()=>{let t,e;if(this.options.ignoreSticky&&removeParentSticky(this.element),this.options.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.options.ignoreSticky&&addParentSticky(this.element),this.setRect({top:t,left:e})},this.onResize=([t])=>{const e=t.borderBoxSize[0].inlineSize,i=t.borderBoxSize[0].blockSize;this.setRect({width:e,height:i})},this.element=t,this.options={align:e,ignoreSticky:i,ignoreTransform:s},this.align=[e].flat(),this.wrapperResizeObserver=new ResizeObserver(this.onWrapperResize),this.wrapperResizeObserver.observe(document.body),this.onWrapperResize(),this.resizeObserver=new ResizeObserver(this.onResize),this.resizeObserver.observe(this.element),this.setRect({width:this.element.offsetWidth,height:this.element.offsetHeight})}destroy(){this.wrapperResizeObserver.disconnect(),this.resizeObserver.disconnect()}setRect({top:t,left:e,width:i,height:s,element:o}={}){t=null!=t?t:this.rect.top,e=null!=e?e:this.rect.left,i=null!=i?i:this.rect.width,s=null!=s?s:this.rect.height,o=null!=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)}}let t=0;function uid(){return t++}return class Snap{constructor(t,{type:e="mandatory",lerp:i,easing:s,duration:o,velocityThreshold:n=1,debounce:r=0,onSnapStart:h,onSnapComplete:l}={}){this.isStopped=!1,this.onWindowResize=()=>{this.viewport.width=window.innerWidth,this.viewport.height=window.innerHeight},this.onScroll=({lastVelocity:t,velocity:e,userData:i})=>{if(this.isStopped)return;const s=Math.abs(t)>Math.abs(e),o=Math.sign(t)!==Math.sign(e)&&0!==e;Math.abs(e)<this.options.velocityThreshold&&s&&!o&&"snap"!==(null==i?void 0:i.initiator)&&this.onSnapDebounced()},this.onSnap=()=>{let{scroll:t,isHorizontal:e}=this.lenis;t=Math.ceil(this.lenis.scroll);let i=[...this.snaps.values()];this.elements.forEach((({rect:t,align:s})=>{let o;s.forEach((s=>{"start"===s?o=t.top:"center"===s?o=e?t.left+t.width/2-this.viewport.width/2:t.top+t.height/2-this.viewport.height/2:"end"===s&&(o=e?t.left+t.width-this.viewport.width:t.top+t.height-this.viewport.height),"number"==typeof o&&i.push({value:Math.ceil(o),userData:{}})}))})),i=i.sort(((t,e)=>Math.abs(t.value)-Math.abs(e.value)));let s=i.findLast((({value:e})=>e<=t));void 0===s&&(s=i[0]);const o=Math.abs(t-s.value);let n=i.find((({value:e})=>e>=t));void 0===n&&(n=i[i.length-1]);const r=o<Math.abs(t-n.value)?s:n,h=Math.abs(t-r.value);("mandatory"===this.options.type||"proximity"===this.options.type&&h<=(e?this.lenis.dimensions.width:this.lenis.dimensions.height))&&this.lenis.scrollTo(r.value,{lerp:this.options.lerp,easing:this.options.easing,duration:this.options.duration,userData:{initiator:"snap"},onStart:()=>{var t,e;null===(e=(t=this.options).onSnapStart)||void 0===e||e.call(t,r)},onComplete:()=>{var t,e;null===(e=(t=this.options).onSnapComplete)||void 0===e||e.call(t,r)}})},this.lenis=t,this.options={type:e,lerp:i,easing:s,duration:o,velocityThreshold:n,debounce:r,onSnapStart:h,onSnapComplete:l},this.elements=new Map,this.snaps=new Map,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize,!1),this.onSnapDebounced=function debounce(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.onSnap,this.options.debounce),this.lenis.on("scroll",this.onScroll)}destroy(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize,!1),this.elements.forEach((t=>t.destroy()))}start(){this.isStopped=!1}stop(){this.isStopped=!0}add(t,e={}){const i=uid();return this.snaps.set(i,{value:t,userData:e}),()=>this.remove(i)}remove(t){this.snaps.delete(t)}addElement(t,e={}){const i=uid();return this.elements.set(i,new SnapElement(t,e)),()=>this.removeElement(i)}removeElement(t){this.elements.delete(t)}}}));
2
2
  //# sourceMappingURL=lenis-snap.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lenis-snap.min.js","sources":["../../src/element.ts","../../src/uid.ts","../../src/index.ts","../src/debounce.js"],"sourcesContent":["function removeParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction offsetTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport type SnapElementOptions = {\r\n align?: string[]\r\n ignoreSticky?: boolean\r\n ignoreTransform?: boolean\r\n}\r\n\r\ntype Rect = {\r\n top: number\r\n left: number\r\n width: number\r\n height: number\r\n x: number\r\n y: number\r\n bottom: number\r\n right: number\r\n element: HTMLElement\r\n}\r\n\r\nexport class SnapElement {\r\n element: HTMLElement\r\n options: SnapElementOptions\r\n align: string[]\r\n // @ts-ignore\r\n rect: Rect = {}\r\n wrapperResizeObserver: ResizeObserver\r\n resizeObserver: ResizeObserver\r\n\r\n constructor(\r\n element: HTMLElement,\r\n {\r\n align = ['start'],\r\n ignoreSticky = true,\r\n ignoreTransform = false,\r\n }: SnapElementOptions = {}\r\n ) {\r\n this.element = element\r\n\r\n this.options = { align, ignoreSticky, ignoreTransform }\r\n\r\n // this.ignoreSticky = ignoreSticky\r\n // this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n // TODO: assing rect immediately\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n this.onWrapperResize()\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n this.setRect({\r\n width: this.element.offsetWidth,\r\n height: this.element.offsetHeight,\r\n })\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({\r\n top,\r\n left,\r\n width,\r\n height,\r\n element,\r\n }: {\r\n top?: number\r\n left?: number\r\n width?: number\r\n height?: number\r\n element?: HTMLElement\r\n } = {}) {\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.options.ignoreSticky) removeParentSticky(this.element)\r\n if (this.options.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.options.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]: ResizeObserverEntry[]) => {\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","let index = 0\r\n\r\nexport type UID = number\r\n\r\nexport function uid(): UID {\r\n return index++\r\n}\r\n","import Lenis from 'lenis'\r\nimport { debounce } from './debounce'\r\nimport { SnapElement, SnapElementOptions } from './element'\r\nimport { UID, uid } from './uid'\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// - arrow, spacebar\r\n\r\ntype Viewport = {\r\n width: number\r\n height: number\r\n}\r\n\r\ntype SnapItem = {\r\n value: number\r\n userData: object\r\n}\r\n\r\nexport type SnapOptions = {\r\n type?: 'mandatory' | 'proximity'\r\n lerp?: number\r\n easing?: (t: number) => number\r\n duration?: number\r\n velocityThreshold?: number\r\n debounce?: number\r\n onSnapStart?: (t: SnapItem) => void\r\n onSnapComplete?: (t: SnapItem) => void\r\n}\r\n\r\nexport default class Snap {\r\n lenis: Lenis\r\n options: SnapOptions\r\n elements: Map<UID, SnapElement>\r\n snaps: Map<UID, SnapItem>\r\n viewport: Viewport\r\n isStopped: Boolean = false\r\n onSnapDebounced: Function\r\n\r\n constructor(\r\n lenis: Lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n debounce: debounceDelay = 0,\r\n onSnapStart,\r\n onSnapComplete,\r\n }: SnapOptions = {}\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 debounce: debounceDelay,\r\n onSnapStart,\r\n onSnapComplete,\r\n } as SnapOptions\r\n\r\n this.elements = new Map()\r\n this.snaps = 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, false)\r\n\r\n this.onSnapDebounced = debounce(this.onSnap, this.options.debounce)\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, false)\r\n this.elements.forEach((element) => element.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: number, userData: object = {}) {\r\n const id = uid()\r\n\r\n this.snaps.set(id, { value, userData })\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id: UID) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element: HTMLElement, options = {} as SnapElementOptions) {\r\n const id = uid()\r\n\r\n this.elements.set(id, new SnapElement(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id: UID) {\r\n this.elements.delete(id)\r\n }\r\n\r\n private onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n private onScroll = ({\r\n // scroll,\r\n // limit,\r\n lastVelocity,\r\n velocity,\r\n // isScrolling,\r\n userData,\r\n }: // isHorizontal,\r\n Lenis) => {\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.options.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n this.onSnapDebounced()\r\n }\r\n }\r\n\r\n private onSnap = () => {\r\n let { scroll, isHorizontal } = this.lenis\r\n scroll = Math.ceil(this.lenis.scroll)\r\n\r\n let snaps = [...this.snaps.values()] as SnapItem[]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let value: number | undefined\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n value = rect.top\r\n } else if (align === 'center') {\r\n value = isHorizontal\r\n ? rect.left + rect.width / 2 - this.viewport.width / 2\r\n : rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n value = isHorizontal\r\n ? rect.left + rect.width - this.viewport.width\r\n : rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (typeof value === 'number') {\r\n snaps.push({ value: Math.ceil(value), userData: {} })\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a.value) - Math.abs(b.value))\r\n\r\n let prevSnap = snaps.findLast(({ value }) => value <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap.value)\r\n\r\n let nextSnap = snaps.find(({ value }) => value >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap.value)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap.value)\r\n\r\n if (\r\n this.options.type === 'mandatory' ||\r\n (this.options.type === 'proximity' &&\r\n distance <= this.lenis.dimensions.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.value, {\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.options.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.options.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\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"],"names":["removeParentSticky","element","getComputedStyle","position","style","setProperty","dataset","sticky","offsetParent","addParentSticky","_a","removeProperty","offsetTop","accumulator","top","offsetLeft","left","scrollTop","window","scrollY","scrollLeft","scrollX","SnapElement","constructor","align","ignoreSticky","ignoreTransform","this","rect","onWrapperResize","options","getBoundingClientRect","setRect","onResize","entry","width","borderBoxSize","inlineSize","height","blockSize","flat","wrapperResizeObserver","ResizeObserver","observe","document","body","resizeObserver","offsetWidth","offsetHeight","destroy","disconnect","y","x","bottom","right","index","uid","Snap","lenis","type","lerp","easing","duration","velocityThreshold","debounce","debounceDelay","onSnapStart","onSnapComplete","isStopped","onWindowResize","viewport","innerWidth","innerHeight","onScroll","lastVelocity","velocity","userData","isDecelerating","Math","abs","isTurningBack","sign","initiator","onSnapDebounced","onSnap","scroll","isHorizontal","ceil","snaps","values","elements","forEach","value","push","sort","a","b","prevSnap","findLast","undefined","distanceToPrevSnap","nextSnap","find","length","snap","distance","dimensions","scrollTo","onStart","_b","call","onComplete","Map","addEventListener","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","on","off","removeEventListener","start","stop","add","id","set","remove","delete","addElement","removeElement"],"mappings":"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"}
1
+ {"version":3,"file":"lenis-snap.min.js","sources":["../../src/element.ts","../../src/uid.ts","../../src/index.ts","../src/debounce.js"],"sourcesContent":["function removeParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction offsetTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport type SnapElementOptions = {\r\n align?: string[]\r\n ignoreSticky?: boolean\r\n ignoreTransform?: boolean\r\n}\r\n\r\ntype Rect = {\r\n top: number\r\n left: number\r\n width: number\r\n height: number\r\n x: number\r\n y: number\r\n bottom: number\r\n right: number\r\n element: HTMLElement\r\n}\r\n\r\nexport class SnapElement {\r\n element: HTMLElement\r\n options: SnapElementOptions\r\n align: string[]\r\n // @ts-ignore\r\n rect: Rect = {}\r\n wrapperResizeObserver: ResizeObserver\r\n resizeObserver: ResizeObserver\r\n\r\n constructor(\r\n element: HTMLElement,\r\n {\r\n align = ['start'],\r\n ignoreSticky = true,\r\n ignoreTransform = false,\r\n }: SnapElementOptions = {}\r\n ) {\r\n this.element = element\r\n\r\n this.options = { align, ignoreSticky, ignoreTransform }\r\n\r\n // this.ignoreSticky = ignoreSticky\r\n // this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n // TODO: assing rect immediately\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n this.onWrapperResize()\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n this.setRect({\r\n width: this.element.offsetWidth,\r\n height: this.element.offsetHeight,\r\n })\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({\r\n top,\r\n left,\r\n width,\r\n height,\r\n element,\r\n }: {\r\n top?: number\r\n left?: number\r\n width?: number\r\n height?: number\r\n element?: HTMLElement\r\n } = {}) {\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.options.ignoreSticky) removeParentSticky(this.element)\r\n if (this.options.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.options.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]: ResizeObserverEntry[]) => {\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","let index = 0\r\n\r\nexport type UID = number\r\n\r\nexport function uid(): UID {\r\n return index++\r\n}\r\n","import Lenis from 'lenis'\r\nimport { debounce } from './debounce'\r\nimport { SnapElement, SnapElementOptions } from './element'\r\nimport { UID, uid } from './uid'\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// - arrow, spacebar\r\n\r\ntype Viewport = {\r\n width: number\r\n height: number\r\n}\r\n\r\ntype SnapItem = {\r\n value: number\r\n userData: object\r\n}\r\n\r\nexport type SnapOptions = {\r\n type?: 'mandatory' | 'proximity'\r\n lerp?: number\r\n easing?: (t: number) => number\r\n duration?: number\r\n velocityThreshold?: number\r\n debounce?: number\r\n onSnapStart?: (t: SnapItem) => void\r\n onSnapComplete?: (t: SnapItem) => void\r\n}\r\n\r\nexport default class Snap {\r\n lenis: Lenis\r\n options: SnapOptions\r\n elements: Map<UID, SnapElement>\r\n snaps: Map<UID, SnapItem>\r\n viewport: Viewport\r\n isStopped: Boolean = false\r\n onSnapDebounced: Function\r\n\r\n constructor(\r\n lenis: Lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n debounce: debounceDelay = 0,\r\n onSnapStart,\r\n onSnapComplete,\r\n }: SnapOptions = {}\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 debounce: debounceDelay,\r\n onSnapStart,\r\n onSnapComplete,\r\n } as SnapOptions\r\n\r\n this.elements = new Map()\r\n this.snaps = 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, false)\r\n\r\n this.onSnapDebounced = debounce(this.onSnap, this.options.debounce)\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, false)\r\n this.elements.forEach((element) => element.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: number, userData: object = {}) {\r\n const id = uid()\r\n\r\n this.snaps.set(id, { value, userData })\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id: UID) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element: HTMLElement, options = {} as SnapElementOptions) {\r\n const id = uid()\r\n\r\n this.elements.set(id, new SnapElement(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id: UID) {\r\n this.elements.delete(id)\r\n }\r\n\r\n private onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n private onScroll = ({\r\n // scroll,\r\n // limit,\r\n lastVelocity,\r\n velocity,\r\n // isScrolling,\r\n userData,\r\n }: // isHorizontal,\r\n Lenis) => {\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.options.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n this.onSnapDebounced()\r\n }\r\n }\r\n\r\n private onSnap = () => {\r\n let { scroll, isHorizontal } = this.lenis\r\n scroll = Math.ceil(this.lenis.scroll)\r\n\r\n let snaps = [...this.snaps.values()] as SnapItem[]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let value: number | undefined\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n value = rect.top\r\n } else if (align === 'center') {\r\n value = isHorizontal\r\n ? rect.left + rect.width / 2 - this.viewport.width / 2\r\n : rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n value = isHorizontal\r\n ? rect.left + rect.width - this.viewport.width\r\n : rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (typeof value === 'number') {\r\n snaps.push({ value: Math.ceil(value), userData: {} })\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a.value) - Math.abs(b.value))\r\n\r\n let prevSnap = snaps.findLast(({ value }) => value <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap.value)\r\n\r\n let nextSnap = snaps.find(({ value }) => value >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap.value)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap.value)\r\n\r\n if (\r\n this.options.type === 'mandatory' ||\r\n (this.options.type === 'proximity' &&\r\n distance <=\r\n (isHorizontal\r\n ? this.lenis.dimensions.width\r\n : this.lenis.dimensions.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.value, {\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.options.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.options.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\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"],"names":["removeParentSticky","element","getComputedStyle","position","style","setProperty","dataset","sticky","offsetParent","addParentSticky","_a","removeProperty","offsetTop","accumulator","top","offsetLeft","left","scrollTop","window","scrollY","scrollLeft","scrollX","SnapElement","constructor","align","ignoreSticky","ignoreTransform","this","rect","onWrapperResize","options","getBoundingClientRect","setRect","onResize","entry","width","borderBoxSize","inlineSize","height","blockSize","flat","wrapperResizeObserver","ResizeObserver","observe","document","body","resizeObserver","offsetWidth","offsetHeight","destroy","disconnect","y","x","bottom","right","index","uid","Snap","lenis","type","lerp","easing","duration","velocityThreshold","debounce","debounceDelay","onSnapStart","onSnapComplete","isStopped","onWindowResize","viewport","innerWidth","innerHeight","onScroll","lastVelocity","velocity","userData","isDecelerating","Math","abs","isTurningBack","sign","initiator","onSnapDebounced","onSnap","scroll","isHorizontal","ceil","snaps","values","elements","forEach","value","push","sort","a","b","prevSnap","findLast","undefined","distanceToPrevSnap","nextSnap","find","length","snap","distance","dimensions","scrollTo","onStart","_b","call","onComplete","Map","addEventListener","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","on","off","removeEventListener","start","stop","add","id","set","remove","delete","addElement","removeElement"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- function removeParentSticky(t){"sticky"===getComputedStyle(t).position&&(t.style.setProperty("position","static"),t.dataset.sticky="true"),t.offsetParent&&removeParentSticky(t.offsetParent)}function addParentSticky(t){var e;"true"===(null===(e=null==t?void 0:t.dataset)||void 0===e?void 0:e.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 SnapElement{constructor(t,{align:e=["start"],ignoreSticky:i=!0,ignoreTransform:s=!1}={}){this.rect={},this.onWrapperResize=()=>{let t,e;if(this.options.ignoreSticky&&removeParentSticky(this.element),this.options.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.options.ignoreSticky&&addParentSticky(this.element),this.setRect({top:t,left:e})},this.onResize=([t])=>{const e=t.borderBoxSize[0].inlineSize,i=t.borderBoxSize[0].blockSize;this.setRect({width:e,height:i})},this.element=t,this.options={align:e,ignoreSticky:i,ignoreTransform:s},this.align=[e].flat(),this.wrapperResizeObserver=new ResizeObserver(this.onWrapperResize),this.wrapperResizeObserver.observe(document.body),this.onWrapperResize(),this.resizeObserver=new ResizeObserver(this.onResize),this.resizeObserver.observe(this.element),this.setRect({width:this.element.offsetWidth,height:this.element.offsetHeight})}destroy(){this.wrapperResizeObserver.disconnect(),this.resizeObserver.disconnect()}setRect({top:t,left:e,width:i,height:s,element:o}={}){t=null!=t?t:this.rect.top,e=null!=e?e:this.rect.left,i=null!=i?i:this.rect.width,s=null!=s?s:this.rect.height,o=null!=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)}}let t=0;function uid(){return t++}class Snap{constructor(t,{type:e="mandatory",lerp:i,easing:s,duration:o,velocityThreshold:n=1,debounce:r=0,onSnapStart:h,onSnapComplete:l}={}){this.isStopped=!1,this.onWindowResize=()=>{this.viewport.width=window.innerWidth,this.viewport.height=window.innerHeight},this.onScroll=({lastVelocity:t,velocity:e,userData:i})=>{if(this.isStopped)return;const s=Math.abs(t)>Math.abs(e),o=Math.sign(t)!==Math.sign(e)&&0!==e;Math.abs(e)<this.options.velocityThreshold&&s&&!o&&"snap"!==(null==i?void 0:i.initiator)&&this.onSnapDebounced()},this.onSnap=()=>{let{scroll:t,isHorizontal:e}=this.lenis;t=Math.ceil(this.lenis.scroll);let i=[...this.snaps.values()];this.elements.forEach((({rect:t,align:s})=>{let o;s.forEach((s=>{"start"===s?o=t.top:"center"===s?o=e?t.left+t.width/2-this.viewport.width/2:t.top+t.height/2-this.viewport.height/2:"end"===s&&(o=e?t.left+t.width-this.viewport.width:t.top+t.height-this.viewport.height),"number"==typeof o&&i.push({value:Math.ceil(o),userData:{}})}))})),i=i.sort(((t,e)=>Math.abs(t.value)-Math.abs(e.value)));let s=i.findLast((({value:e})=>e<=t));void 0===s&&(s=i[0]);const o=Math.abs(t-s.value);let n=i.find((({value:e})=>e>=t));void 0===n&&(n=i[i.length-1]);const r=o<Math.abs(t-n.value)?s:n,h=Math.abs(t-r.value);("mandatory"===this.options.type||"proximity"===this.options.type&&h<=this.lenis.dimensions.height)&&this.lenis.scrollTo(r.value,{lerp:this.options.lerp,easing:this.options.easing,duration:this.options.duration,userData:{initiator:"snap"},onStart:()=>{var t,e;null===(e=(t=this.options).onSnapStart)||void 0===e||e.call(t,r)},onComplete:()=>{var t,e;null===(e=(t=this.options).onSnapComplete)||void 0===e||e.call(t,r)}})},this.lenis=t,this.options={type:e,lerp:i,easing:s,duration:o,velocityThreshold:n,debounce:r,onSnapStart:h,onSnapComplete:l},this.elements=new Map,this.snaps=new Map,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize,!1),this.onSnapDebounced=function debounce(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.onSnap,this.options.debounce),this.lenis.on("scroll",this.onScroll)}destroy(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize,!1),this.elements.forEach((t=>t.destroy()))}start(){this.isStopped=!1}stop(){this.isStopped=!0}add(t,e={}){const i=uid();return this.snaps.set(i,{value:t,userData:e}),()=>this.remove(i)}remove(t){this.snaps.delete(t)}addElement(t,e={}){const i=uid();return this.elements.set(i,new SnapElement(t,e)),()=>this.removeElement(i)}removeElement(t){this.elements.delete(t)}}export{Snap as default};
1
+ function removeParentSticky(t){"sticky"===getComputedStyle(t).position&&(t.style.setProperty("position","static"),t.dataset.sticky="true"),t.offsetParent&&removeParentSticky(t.offsetParent)}function addParentSticky(t){var e;"true"===(null===(e=null==t?void 0:t.dataset)||void 0===e?void 0:e.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 SnapElement{constructor(t,{align:e=["start"],ignoreSticky:i=!0,ignoreTransform:s=!1}={}){this.rect={},this.onWrapperResize=()=>{let t,e;if(this.options.ignoreSticky&&removeParentSticky(this.element),this.options.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.options.ignoreSticky&&addParentSticky(this.element),this.setRect({top:t,left:e})},this.onResize=([t])=>{const e=t.borderBoxSize[0].inlineSize,i=t.borderBoxSize[0].blockSize;this.setRect({width:e,height:i})},this.element=t,this.options={align:e,ignoreSticky:i,ignoreTransform:s},this.align=[e].flat(),this.wrapperResizeObserver=new ResizeObserver(this.onWrapperResize),this.wrapperResizeObserver.observe(document.body),this.onWrapperResize(),this.resizeObserver=new ResizeObserver(this.onResize),this.resizeObserver.observe(this.element),this.setRect({width:this.element.offsetWidth,height:this.element.offsetHeight})}destroy(){this.wrapperResizeObserver.disconnect(),this.resizeObserver.disconnect()}setRect({top:t,left:e,width:i,height:s,element:o}={}){t=null!=t?t:this.rect.top,e=null!=e?e:this.rect.left,i=null!=i?i:this.rect.width,s=null!=s?s:this.rect.height,o=null!=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)}}let t=0;function uid(){return t++}class Snap{constructor(t,{type:e="mandatory",lerp:i,easing:s,duration:o,velocityThreshold:n=1,debounce:r=0,onSnapStart:h,onSnapComplete:l}={}){this.isStopped=!1,this.onWindowResize=()=>{this.viewport.width=window.innerWidth,this.viewport.height=window.innerHeight},this.onScroll=({lastVelocity:t,velocity:e,userData:i})=>{if(this.isStopped)return;const s=Math.abs(t)>Math.abs(e),o=Math.sign(t)!==Math.sign(e)&&0!==e;Math.abs(e)<this.options.velocityThreshold&&s&&!o&&"snap"!==(null==i?void 0:i.initiator)&&this.onSnapDebounced()},this.onSnap=()=>{let{scroll:t,isHorizontal:e}=this.lenis;t=Math.ceil(this.lenis.scroll);let i=[...this.snaps.values()];this.elements.forEach((({rect:t,align:s})=>{let o;s.forEach((s=>{"start"===s?o=t.top:"center"===s?o=e?t.left+t.width/2-this.viewport.width/2:t.top+t.height/2-this.viewport.height/2:"end"===s&&(o=e?t.left+t.width-this.viewport.width:t.top+t.height-this.viewport.height),"number"==typeof o&&i.push({value:Math.ceil(o),userData:{}})}))})),i=i.sort(((t,e)=>Math.abs(t.value)-Math.abs(e.value)));let s=i.findLast((({value:e})=>e<=t));void 0===s&&(s=i[0]);const o=Math.abs(t-s.value);let n=i.find((({value:e})=>e>=t));void 0===n&&(n=i[i.length-1]);const r=o<Math.abs(t-n.value)?s:n,h=Math.abs(t-r.value);("mandatory"===this.options.type||"proximity"===this.options.type&&h<=(e?this.lenis.dimensions.width:this.lenis.dimensions.height))&&this.lenis.scrollTo(r.value,{lerp:this.options.lerp,easing:this.options.easing,duration:this.options.duration,userData:{initiator:"snap"},onStart:()=>{var t,e;null===(e=(t=this.options).onSnapStart)||void 0===e||e.call(t,r)},onComplete:()=>{var t,e;null===(e=(t=this.options).onSnapComplete)||void 0===e||e.call(t,r)}})},this.lenis=t,this.options={type:e,lerp:i,easing:s,duration:o,velocityThreshold:n,debounce:r,onSnapStart:h,onSnapComplete:l},this.elements=new Map,this.snaps=new Map,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize,!1),this.onSnapDebounced=function debounce(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.onSnap,this.options.debounce),this.lenis.on("scroll",this.onScroll)}destroy(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize,!1),this.elements.forEach((t=>t.destroy()))}start(){this.isStopped=!1}stop(){this.isStopped=!0}add(t,e={}){const i=uid();return this.snaps.set(i,{value:t,userData:e}),()=>this.remove(i)}remove(t){this.snaps.delete(t)}addElement(t,e={}){const i=uid();return this.elements.set(i,new SnapElement(t,e)),()=>this.removeElement(i)}removeElement(t){this.elements.delete(t)}}export{Snap as default};
2
2
  //# sourceMappingURL=lenis-snap.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"lenis-snap.mjs","sources":["../../src/element.ts","../../src/uid.ts","../../src/index.ts","../src/debounce.js"],"sourcesContent":["function removeParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction offsetTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport type SnapElementOptions = {\r\n align?: string[]\r\n ignoreSticky?: boolean\r\n ignoreTransform?: boolean\r\n}\r\n\r\ntype Rect = {\r\n top: number\r\n left: number\r\n width: number\r\n height: number\r\n x: number\r\n y: number\r\n bottom: number\r\n right: number\r\n element: HTMLElement\r\n}\r\n\r\nexport class SnapElement {\r\n element: HTMLElement\r\n options: SnapElementOptions\r\n align: string[]\r\n // @ts-ignore\r\n rect: Rect = {}\r\n wrapperResizeObserver: ResizeObserver\r\n resizeObserver: ResizeObserver\r\n\r\n constructor(\r\n element: HTMLElement,\r\n {\r\n align = ['start'],\r\n ignoreSticky = true,\r\n ignoreTransform = false,\r\n }: SnapElementOptions = {}\r\n ) {\r\n this.element = element\r\n\r\n this.options = { align, ignoreSticky, ignoreTransform }\r\n\r\n // this.ignoreSticky = ignoreSticky\r\n // this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n // TODO: assing rect immediately\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n this.onWrapperResize()\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n this.setRect({\r\n width: this.element.offsetWidth,\r\n height: this.element.offsetHeight,\r\n })\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({\r\n top,\r\n left,\r\n width,\r\n height,\r\n element,\r\n }: {\r\n top?: number\r\n left?: number\r\n width?: number\r\n height?: number\r\n element?: HTMLElement\r\n } = {}) {\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.options.ignoreSticky) removeParentSticky(this.element)\r\n if (this.options.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.options.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]: ResizeObserverEntry[]) => {\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","let index = 0\r\n\r\nexport type UID = number\r\n\r\nexport function uid(): UID {\r\n return index++\r\n}\r\n","import Lenis from 'lenis'\r\nimport { debounce } from './debounce'\r\nimport { SnapElement, SnapElementOptions } from './element'\r\nimport { UID, uid } from './uid'\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// - arrow, spacebar\r\n\r\ntype Viewport = {\r\n width: number\r\n height: number\r\n}\r\n\r\ntype SnapItem = {\r\n value: number\r\n userData: object\r\n}\r\n\r\nexport type SnapOptions = {\r\n type?: 'mandatory' | 'proximity'\r\n lerp?: number\r\n easing?: (t: number) => number\r\n duration?: number\r\n velocityThreshold?: number\r\n debounce?: number\r\n onSnapStart?: (t: SnapItem) => void\r\n onSnapComplete?: (t: SnapItem) => void\r\n}\r\n\r\nexport default class Snap {\r\n lenis: Lenis\r\n options: SnapOptions\r\n elements: Map<UID, SnapElement>\r\n snaps: Map<UID, SnapItem>\r\n viewport: Viewport\r\n isStopped: Boolean = false\r\n onSnapDebounced: Function\r\n\r\n constructor(\r\n lenis: Lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n debounce: debounceDelay = 0,\r\n onSnapStart,\r\n onSnapComplete,\r\n }: SnapOptions = {}\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 debounce: debounceDelay,\r\n onSnapStart,\r\n onSnapComplete,\r\n } as SnapOptions\r\n\r\n this.elements = new Map()\r\n this.snaps = 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, false)\r\n\r\n this.onSnapDebounced = debounce(this.onSnap, this.options.debounce)\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, false)\r\n this.elements.forEach((element) => element.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: number, userData: object = {}) {\r\n const id = uid()\r\n\r\n this.snaps.set(id, { value, userData })\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id: UID) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element: HTMLElement, options = {} as SnapElementOptions) {\r\n const id = uid()\r\n\r\n this.elements.set(id, new SnapElement(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id: UID) {\r\n this.elements.delete(id)\r\n }\r\n\r\n private onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n private onScroll = ({\r\n // scroll,\r\n // limit,\r\n lastVelocity,\r\n velocity,\r\n // isScrolling,\r\n userData,\r\n }: // isHorizontal,\r\n Lenis) => {\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.options.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n this.onSnapDebounced()\r\n }\r\n }\r\n\r\n private onSnap = () => {\r\n let { scroll, isHorizontal } = this.lenis\r\n scroll = Math.ceil(this.lenis.scroll)\r\n\r\n let snaps = [...this.snaps.values()] as SnapItem[]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let value: number | undefined\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n value = rect.top\r\n } else if (align === 'center') {\r\n value = isHorizontal\r\n ? rect.left + rect.width / 2 - this.viewport.width / 2\r\n : rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n value = isHorizontal\r\n ? rect.left + rect.width - this.viewport.width\r\n : rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (typeof value === 'number') {\r\n snaps.push({ value: Math.ceil(value), userData: {} })\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a.value) - Math.abs(b.value))\r\n\r\n let prevSnap = snaps.findLast(({ value }) => value <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap.value)\r\n\r\n let nextSnap = snaps.find(({ value }) => value >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap.value)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap.value)\r\n\r\n if (\r\n this.options.type === 'mandatory' ||\r\n (this.options.type === 'proximity' &&\r\n distance <= this.lenis.dimensions.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.value, {\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.options.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.options.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\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"],"names":["removeParentSticky","element","getComputedStyle","position","style","setProperty","dataset","sticky","offsetParent","addParentSticky","_a","removeProperty","offsetTop","accumulator","top","offsetLeft","left","scrollTop","window","scrollY","scrollLeft","scrollX","SnapElement","constructor","align","ignoreSticky","ignoreTransform","this","rect","onWrapperResize","options","getBoundingClientRect","setRect","onResize","entry","width","borderBoxSize","inlineSize","height","blockSize","flat","wrapperResizeObserver","ResizeObserver","observe","document","body","resizeObserver","offsetWidth","offsetHeight","destroy","disconnect","y","x","bottom","right","index","uid","Snap","lenis","type","lerp","easing","duration","velocityThreshold","debounce","debounceDelay","onSnapStart","onSnapComplete","isStopped","onWindowResize","viewport","innerWidth","innerHeight","onScroll","lastVelocity","velocity","userData","isDecelerating","Math","abs","isTurningBack","sign","initiator","onSnapDebounced","onSnap","scroll","isHorizontal","ceil","snaps","values","elements","forEach","value","push","sort","a","b","prevSnap","findLast","undefined","distanceToPrevSnap","nextSnap","find","length","snap","distance","dimensions","scrollTo","onStart","_b","call","onComplete","Map","addEventListener","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","on","off","removeEventListener","start","stop","add","id","set","remove","delete","addElement","removeElement"],"mappings":"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"}
1
+ {"version":3,"file":"lenis-snap.mjs","sources":["../../src/element.ts","../../src/uid.ts","../../src/index.ts","../src/debounce.js"],"sourcesContent":["function removeParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction addParentSticky(element: HTMLElement) {\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 as HTMLElement)\r\n }\r\n}\r\n\r\nfunction offsetTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.offsetTop\r\n if (element.offsetParent) {\r\n return offsetTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top\r\n}\r\n\r\nfunction offsetLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.offsetLeft\r\n if (element.offsetParent) {\r\n return offsetLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left\r\n}\r\n\r\nfunction scrollTop(element: HTMLElement, accumulator = 0) {\r\n const top = accumulator + element.scrollTop\r\n if (element.offsetParent) {\r\n return scrollTop(element.offsetParent as HTMLElement, top)\r\n }\r\n return top + window.scrollY\r\n}\r\n\r\nfunction scrollLeft(element: HTMLElement, accumulator = 0) {\r\n const left = accumulator + element.scrollLeft\r\n if (element.offsetParent) {\r\n return scrollLeft(element.offsetParent as HTMLElement, left)\r\n }\r\n return left + window.scrollX\r\n}\r\n\r\nexport type SnapElementOptions = {\r\n align?: string[]\r\n ignoreSticky?: boolean\r\n ignoreTransform?: boolean\r\n}\r\n\r\ntype Rect = {\r\n top: number\r\n left: number\r\n width: number\r\n height: number\r\n x: number\r\n y: number\r\n bottom: number\r\n right: number\r\n element: HTMLElement\r\n}\r\n\r\nexport class SnapElement {\r\n element: HTMLElement\r\n options: SnapElementOptions\r\n align: string[]\r\n // @ts-ignore\r\n rect: Rect = {}\r\n wrapperResizeObserver: ResizeObserver\r\n resizeObserver: ResizeObserver\r\n\r\n constructor(\r\n element: HTMLElement,\r\n {\r\n align = ['start'],\r\n ignoreSticky = true,\r\n ignoreTransform = false,\r\n }: SnapElementOptions = {}\r\n ) {\r\n this.element = element\r\n\r\n this.options = { align, ignoreSticky, ignoreTransform }\r\n\r\n // this.ignoreSticky = ignoreSticky\r\n // this.ignoreTransform = ignoreTransform\r\n\r\n this.align = [align].flat()\r\n\r\n // TODO: assing rect immediately\r\n\r\n this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize)\r\n this.wrapperResizeObserver.observe(document.body)\r\n this.onWrapperResize()\r\n\r\n this.resizeObserver = new ResizeObserver(this.onResize)\r\n this.resizeObserver.observe(this.element)\r\n this.setRect({\r\n width: this.element.offsetWidth,\r\n height: this.element.offsetHeight,\r\n })\r\n }\r\n\r\n destroy() {\r\n this.wrapperResizeObserver.disconnect()\r\n this.resizeObserver.disconnect()\r\n }\r\n\r\n setRect({\r\n top,\r\n left,\r\n width,\r\n height,\r\n element,\r\n }: {\r\n top?: number\r\n left?: number\r\n width?: number\r\n height?: number\r\n element?: HTMLElement\r\n } = {}) {\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.options.ignoreSticky) removeParentSticky(this.element)\r\n if (this.options.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.options.ignoreSticky) addParentSticky(this.element)\r\n\r\n this.setRect({ top, left })\r\n }\r\n\r\n onResize = ([entry]: ResizeObserverEntry[]) => {\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","let index = 0\r\n\r\nexport type UID = number\r\n\r\nexport function uid(): UID {\r\n return index++\r\n}\r\n","import Lenis from 'lenis'\r\nimport { debounce } from './debounce'\r\nimport { SnapElement, SnapElementOptions } from './element'\r\nimport { UID, uid } from './uid'\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// - arrow, spacebar\r\n\r\ntype Viewport = {\r\n width: number\r\n height: number\r\n}\r\n\r\ntype SnapItem = {\r\n value: number\r\n userData: object\r\n}\r\n\r\nexport type SnapOptions = {\r\n type?: 'mandatory' | 'proximity'\r\n lerp?: number\r\n easing?: (t: number) => number\r\n duration?: number\r\n velocityThreshold?: number\r\n debounce?: number\r\n onSnapStart?: (t: SnapItem) => void\r\n onSnapComplete?: (t: SnapItem) => void\r\n}\r\n\r\nexport default class Snap {\r\n lenis: Lenis\r\n options: SnapOptions\r\n elements: Map<UID, SnapElement>\r\n snaps: Map<UID, SnapItem>\r\n viewport: Viewport\r\n isStopped: Boolean = false\r\n onSnapDebounced: Function\r\n\r\n constructor(\r\n lenis: Lenis,\r\n {\r\n type = 'mandatory',\r\n lerp,\r\n easing,\r\n duration,\r\n velocityThreshold = 1,\r\n debounce: debounceDelay = 0,\r\n onSnapStart,\r\n onSnapComplete,\r\n }: SnapOptions = {}\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 debounce: debounceDelay,\r\n onSnapStart,\r\n onSnapComplete,\r\n } as SnapOptions\r\n\r\n this.elements = new Map()\r\n this.snaps = 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, false)\r\n\r\n this.onSnapDebounced = debounce(this.onSnap, this.options.debounce)\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, false)\r\n this.elements.forEach((element) => element.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: number, userData: object = {}) {\r\n const id = uid()\r\n\r\n this.snaps.set(id, { value, userData })\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id: UID) {\r\n this.snaps.delete(id)\r\n }\r\n\r\n addElement(element: HTMLElement, options = {} as SnapElementOptions) {\r\n const id = uid()\r\n\r\n this.elements.set(id, new SnapElement(element, options))\r\n\r\n return () => this.removeElement(id)\r\n }\r\n\r\n removeElement(id: UID) {\r\n this.elements.delete(id)\r\n }\r\n\r\n private onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n private onScroll = ({\r\n // scroll,\r\n // limit,\r\n lastVelocity,\r\n velocity,\r\n // isScrolling,\r\n userData,\r\n }: // isHorizontal,\r\n Lenis) => {\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.options.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n this.onSnapDebounced()\r\n }\r\n }\r\n\r\n private onSnap = () => {\r\n let { scroll, isHorizontal } = this.lenis\r\n scroll = Math.ceil(this.lenis.scroll)\r\n\r\n let snaps = [...this.snaps.values()] as SnapItem[]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let value: number | undefined\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n value = rect.top\r\n } else if (align === 'center') {\r\n value = isHorizontal\r\n ? rect.left + rect.width / 2 - this.viewport.width / 2\r\n : rect.top + rect.height / 2 - this.viewport.height / 2\r\n } else if (align === 'end') {\r\n value = isHorizontal\r\n ? rect.left + rect.width - this.viewport.width\r\n : rect.top + rect.height - this.viewport.height\r\n }\r\n\r\n if (typeof value === 'number') {\r\n snaps.push({ value: Math.ceil(value), userData: {} })\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a.value) - Math.abs(b.value))\r\n\r\n let prevSnap = snaps.findLast(({ value }) => value <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap.value)\r\n\r\n let nextSnap = snaps.find(({ value }) => value >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap.value)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap.value)\r\n\r\n if (\r\n this.options.type === 'mandatory' ||\r\n (this.options.type === 'proximity' &&\r\n distance <=\r\n (isHorizontal\r\n ? this.lenis.dimensions.width\r\n : this.lenis.dimensions.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.value, {\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.options.onSnapStart?.(snap)\r\n },\r\n onComplete: () => {\r\n this.options.onSnapComplete?.(snap)\r\n },\r\n })\r\n }\r\n\r\n // console.timeEnd('scroll')\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"],"names":["removeParentSticky","element","getComputedStyle","position","style","setProperty","dataset","sticky","offsetParent","addParentSticky","_a","removeProperty","offsetTop","accumulator","top","offsetLeft","left","scrollTop","window","scrollY","scrollLeft","scrollX","SnapElement","constructor","align","ignoreSticky","ignoreTransform","this","rect","onWrapperResize","options","getBoundingClientRect","setRect","onResize","entry","width","borderBoxSize","inlineSize","height","blockSize","flat","wrapperResizeObserver","ResizeObserver","observe","document","body","resizeObserver","offsetWidth","offsetHeight","destroy","disconnect","y","x","bottom","right","index","uid","Snap","lenis","type","lerp","easing","duration","velocityThreshold","debounce","debounceDelay","onSnapStart","onSnapComplete","isStopped","onWindowResize","viewport","innerWidth","innerHeight","onScroll","lastVelocity","velocity","userData","isDecelerating","Math","abs","isTurningBack","sign","initiator","onSnapDebounced","onSnap","scroll","isHorizontal","ceil","snaps","values","elements","forEach","value","push","sort","a","b","prevSnap","findLast","undefined","distanceToPrevSnap","nextSnap","find","length","snap","distance","dimensions","scrollTo","onStart","_b","call","onComplete","Map","addEventListener","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","on","off","removeEventListener","start","stop","add","id","set","remove","delete","addElement","removeElement"],"mappings":"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"}
package/dist/lenis.js CHANGED
@@ -4,7 +4,7 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Lenis = factory());
5
5
  })(this, (function () { 'use strict';
6
6
 
7
- var version = "1.1.6-dev.0";
7
+ var version = "1.1.6";
8
8
 
9
9
  // Clamp a value between a minimum and maximum value
10
10
  function clamp(min, input, max) {
package/dist/lenis.min.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).Lenis=i()}(this,(function(){"use strict";function clamp(t,i,e){return Math.max(t,Math.min(i,e))}class Animate{constructor(){this.isRunning=!1,this.value=0,this.from=0,this.to=0,this.duration=0,this.currentTime=0}advance(t){var i;if(!this.isRunning)return;let e=!1;if(this.duration&&this.easing){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}else this.lerp?(this.value=function damp(t,i,e,s){return function lerp(t,i,e){return(1-e)*t+e*i}(t,i,1-Math.exp(-e*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0)):(this.value=this.to,e=!0);e&&this.stop(),null===(i=this.onUpdate)||void 0===i||i.call(this,this.value,e)}stop(){this.isRunning=!1}fromTo(t,i,{lerp:e,duration:s,easing:o,onStart:n,onUpdate:l}){this.from=this.value=t,this.to=i,this.lerp=e,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,null==n||n(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:i,autoResize:e=!0,debounce:s=250}={}){this.width=0,this.height=0,this.scrollWidth=0,this.scrollHeight=0,this.resize=()=>{this.onWrapperResize(),this.onContentResize()},this.onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):this.wrapper instanceof HTMLElement&&(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)},this.onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):this.wrapper instanceof HTMLElement&&(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)},this.wrapper=t,this.content=i,e&&(this.debouncedResize=function debounce(t,i){let e;return function(){let s=arguments,o=this;clearTimeout(e),e=setTimeout((function(){t.apply(o,s)}),i)}}(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(){var t,i;null===(t=this.wrapperResizeObserver)||void 0===t||t.disconnect(),null===(i=this.contentResizeObserver)||void 0===i||i.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...i){let e=this.events[t]||[];for(let t=0,s=e.length;t<s;t++)e[t](...i)}on(t,i){var e;return(null===(e=this.events[t])||void 0===e?void 0:e.push(i))||(this.events[t]=[i]),()=>{var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}}off(t,i){var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}destroy(){this.events={}}}const t=100/6;class VirtualScroll{constructor(i,{wheelMultiplier:e=1,touchMultiplier:s=1}){this.lastDelta={x:0,y:0},this.windowWidth=0,this.windowHeight=0,this.onTouchStart=t=>{const{clientX:i,clientY:e}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=i,this.touchStart.y=e,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})},this.onTouchMove=t=>{var i,e,s,o;const{clientX:n,clientY:l}=t.targetTouches?t.targetTouches[0]:t,r=-(n-(null!==(e=null===(i=this.touchStart)||void 0===i?void 0:i.x)&&void 0!==e?e:0))*this.touchMultiplier,h=-(l-(null!==(o=null===(s=this.touchStart)||void 0===s?void 0:s.y)&&void 0!==o?o:0))*this.touchMultiplier;this.touchStart.x=n,this.touchStart.y=l,this.lastDelta={x:r,y:h},this.emitter.emit("scroll",{deltaX:r,deltaY:h,event:t})},this.onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})},this.onWheel=i=>{let{deltaX:e,deltaY:s,deltaMode:o}=i;e*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,e*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:e,deltaY:s,event:i})},this.onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight},this.element=i,this.wheelMultiplier=e,this.touchMultiplier=s,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,i){return this.emitter.on(t,i)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd)}}return class Lenis{constructor({wrapper:t=window,content:i=document.documentElement,wheelEventsTarget:e=t,eventsTarget:s=e,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=.1,infinite:d=!1,orientation:u="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f=!1}={}){this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.userData={},this.lastVelocity=0,this.velocity=0,this.direction=0,this.onPointerDown=t=>{1===t.button&&this.reset()},this.onVirtualScroll=t=>{if("function"==typeof this.options.virtualScroll&&!1===this.options.virtualScroll(t))return;const{deltaX:i,deltaY:e,event:s}=t;if(this.emitter.emit("virtual-scroll",{deltaX:i,deltaY:e,event:s}),s.ctrlKey)return;const o=s.type.includes("touch"),n=s.type.includes("wheel");this.isTouching="touchstart"===s.type||"touchmove"===s.type;if(this.options.syncTouch&&o&&"touchstart"===s.type&&!this.isStopped&&!this.isLocked)return void this.reset();const l=0===i&&0===e,r="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===i;if(l||r)return;let h=s.composedPath();h=h.slice(0,h.indexOf(this.rootElement));const a=this.options.prevent;if(h.find((t=>{var i,e,s,l,r;return t instanceof Element&&("function"==typeof a&&(null==a?void 0:a(t))||(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent"))||o&&(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent-touch"))||n&&(null===(s=t.hasAttribute)||void 0===s?void 0:s.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped")))})))return;if(this.isStopped||this.isLocked)return void s.preventDefault();if(!(this.options.syncTouch&&o||this.options.smoothWheel&&n))return this.isScrolling="native",void this.animate.stop();s.preventDefault();let c=e;"both"===this.options.gestureOrientation?c=Math.abs(e)>Math.abs(i)?e:i:"horizontal"===this.options.gestureOrientation&&(c=i);const d=o&&this.options.syncTouch,u=o&&"touchend"===s.type&&Math.abs(c)>5;u&&(c=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+c,Object.assign({programmatic:!1},d?{lerp:u?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="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.6-dev.0",t&&t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:i,wheelEventsTarget:e,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:p,orientation:u,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:i,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.options.wrapper.addEventListener("pointerdown",this.onPointerDown,!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.options.wrapper.removeEventListener("pointerdown",this.onPointerDown,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.cleanUpClassName()}on(t,i){return this.emitter.on(t,i)}off(t,i){return this.emitter.off(t,i)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.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 i=t-(this.time||t);this.time=t,this.animate.advance(.001*i)}scrollTo(t,{offset:i=0,immediate:e=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:l=this.options.lerp,onStart:r,onComplete:h,force:a=!1,programmatic:c=!0,userData:d={}}={}){if(!this.isStopped&&!this.isLocked||a){if("string"==typeof t&&["top","left","start"].includes(t))t=0;else if("string"==typeof t&&["bottom","right","end"].includes(t))t=this.limit;else{let e;if("string"==typeof t?e=document.querySelector(t):t instanceof HTMLElement&&(null==t?void 0:t.nodeType)&&(e=t),e){if(this.options.wrapper!==window){const t=this.rootElement.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=e.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t&&(t+=i,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),t!==this.targetScroll)){if(this.userData=d,e)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),this.preventNextNativeScrollEvent(),this.emit(),null==h||h(this),void(this.userData={});c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:l,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==r||r(this)},onUpdate:(t,i)=>{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),i||this.emit(),i&&(this.reset(),this.emit(),null==h||h(this),this.userData={},this.preventNextNativeScrollEvent())}})}}}preventNextNativeScrollEvent(){this.__preventNextNativeScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextNativeScrollEvent}))}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,i){return(t%i+i)%i}(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()}}}));
1
+ !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).Lenis=i()}(this,(function(){"use strict";function clamp(t,i,e){return Math.max(t,Math.min(i,e))}class Animate{constructor(){this.isRunning=!1,this.value=0,this.from=0,this.to=0,this.duration=0,this.currentTime=0}advance(t){var i;if(!this.isRunning)return;let e=!1;if(this.duration&&this.easing){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}else this.lerp?(this.value=function damp(t,i,e,s){return function lerp(t,i,e){return(1-e)*t+e*i}(t,i,1-Math.exp(-e*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0)):(this.value=this.to,e=!0);e&&this.stop(),null===(i=this.onUpdate)||void 0===i||i.call(this,this.value,e)}stop(){this.isRunning=!1}fromTo(t,i,{lerp:e,duration:s,easing:o,onStart:n,onUpdate:l}){this.from=this.value=t,this.to=i,this.lerp=e,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,null==n||n(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:i,autoResize:e=!0,debounce:s=250}={}){this.width=0,this.height=0,this.scrollWidth=0,this.scrollHeight=0,this.resize=()=>{this.onWrapperResize(),this.onContentResize()},this.onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):this.wrapper instanceof HTMLElement&&(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)},this.onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):this.wrapper instanceof HTMLElement&&(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)},this.wrapper=t,this.content=i,e&&(this.debouncedResize=function debounce(t,i){let e;return function(){let s=arguments,o=this;clearTimeout(e),e=setTimeout((function(){t.apply(o,s)}),i)}}(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(){var t,i;null===(t=this.wrapperResizeObserver)||void 0===t||t.disconnect(),null===(i=this.contentResizeObserver)||void 0===i||i.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...i){let e=this.events[t]||[];for(let t=0,s=e.length;t<s;t++)e[t](...i)}on(t,i){var e;return(null===(e=this.events[t])||void 0===e?void 0:e.push(i))||(this.events[t]=[i]),()=>{var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}}off(t,i){var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}destroy(){this.events={}}}const t=100/6;class VirtualScroll{constructor(i,{wheelMultiplier:e=1,touchMultiplier:s=1}){this.lastDelta={x:0,y:0},this.windowWidth=0,this.windowHeight=0,this.onTouchStart=t=>{const{clientX:i,clientY:e}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=i,this.touchStart.y=e,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})},this.onTouchMove=t=>{var i,e,s,o;const{clientX:n,clientY:l}=t.targetTouches?t.targetTouches[0]:t,r=-(n-(null!==(e=null===(i=this.touchStart)||void 0===i?void 0:i.x)&&void 0!==e?e:0))*this.touchMultiplier,h=-(l-(null!==(o=null===(s=this.touchStart)||void 0===s?void 0:s.y)&&void 0!==o?o:0))*this.touchMultiplier;this.touchStart.x=n,this.touchStart.y=l,this.lastDelta={x:r,y:h},this.emitter.emit("scroll",{deltaX:r,deltaY:h,event:t})},this.onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})},this.onWheel=i=>{let{deltaX:e,deltaY:s,deltaMode:o}=i;e*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,e*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:e,deltaY:s,event:i})},this.onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight},this.element=i,this.wheelMultiplier=e,this.touchMultiplier=s,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,i){return this.emitter.on(t,i)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd)}}return class Lenis{constructor({wrapper:t=window,content:i=document.documentElement,wheelEventsTarget:e=t,eventsTarget:s=e,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=.1,infinite:d=!1,orientation:u="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f=!1}={}){this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.userData={},this.lastVelocity=0,this.velocity=0,this.direction=0,this.onPointerDown=t=>{1===t.button&&this.reset()},this.onVirtualScroll=t=>{if("function"==typeof this.options.virtualScroll&&!1===this.options.virtualScroll(t))return;const{deltaX:i,deltaY:e,event:s}=t;if(this.emitter.emit("virtual-scroll",{deltaX:i,deltaY:e,event:s}),s.ctrlKey)return;const o=s.type.includes("touch"),n=s.type.includes("wheel");this.isTouching="touchstart"===s.type||"touchmove"===s.type;if(this.options.syncTouch&&o&&"touchstart"===s.type&&!this.isStopped&&!this.isLocked)return void this.reset();const l=0===i&&0===e,r="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===i;if(l||r)return;let h=s.composedPath();h=h.slice(0,h.indexOf(this.rootElement));const a=this.options.prevent;if(h.find((t=>{var i,e,s,l,r;return t instanceof Element&&("function"==typeof a&&(null==a?void 0:a(t))||(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent"))||o&&(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent-touch"))||n&&(null===(s=t.hasAttribute)||void 0===s?void 0:s.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped")))})))return;if(this.isStopped||this.isLocked)return void s.preventDefault();if(!(this.options.syncTouch&&o||this.options.smoothWheel&&n))return this.isScrolling="native",void this.animate.stop();s.preventDefault();let c=e;"both"===this.options.gestureOrientation?c=Math.abs(e)>Math.abs(i)?e:i:"horizontal"===this.options.gestureOrientation&&(c=i);const d=o&&this.options.syncTouch,u=o&&"touchend"===s.type&&Math.abs(c)>5;u&&(c=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+c,Object.assign({programmatic:!1},d?{lerp:u?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="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.6",t&&t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:i,wheelEventsTarget:e,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:p,orientation:u,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:i,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.options.wrapper.addEventListener("pointerdown",this.onPointerDown,!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.options.wrapper.removeEventListener("pointerdown",this.onPointerDown,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.cleanUpClassName()}on(t,i){return this.emitter.on(t,i)}off(t,i){return this.emitter.off(t,i)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.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 i=t-(this.time||t);this.time=t,this.animate.advance(.001*i)}scrollTo(t,{offset:i=0,immediate:e=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:l=this.options.lerp,onStart:r,onComplete:h,force:a=!1,programmatic:c=!0,userData:d={}}={}){if(!this.isStopped&&!this.isLocked||a){if("string"==typeof t&&["top","left","start"].includes(t))t=0;else if("string"==typeof t&&["bottom","right","end"].includes(t))t=this.limit;else{let e;if("string"==typeof t?e=document.querySelector(t):t instanceof HTMLElement&&(null==t?void 0:t.nodeType)&&(e=t),e){if(this.options.wrapper!==window){const t=this.rootElement.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=e.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t&&(t+=i,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),t!==this.targetScroll)){if(this.userData=d,e)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),this.preventNextNativeScrollEvent(),this.emit(),null==h||h(this),void(this.userData={});c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:l,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==r||r(this)},onUpdate:(t,i)=>{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),i||this.emit(),i&&(this.reset(),this.emit(),null==h||h(this),this.userData={},this.preventNextNativeScrollEvent())}})}}}preventNextNativeScrollEvent(){this.__preventNextNativeScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextNativeScrollEvent}))}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,i){return(t%i+i)%i}(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()}}}));
2
2
  //# sourceMappingURL=lenis.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lenis.min.js","sources":["../src/maths.js","../../src/animate.ts","../../src/dimensions.ts","../src/debounce.js","../../src/emitter.ts","../../src/virtual-scroll.ts","../../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 isRunning: boolean = false\r\n value: number = 0\r\n from: number = 0\r\n to: number = 0\r\n lerp?: number\r\n duration?: number = 0\r\n easing?: Function\r\n currentTime: number = 0\r\n onUpdate?: Function\r\n\r\n // Advance the animation by the given delta time\r\n advance(deltaTime: number) {\r\n if (!this.isRunning) return\r\n\r\n let completed = false\r\n\r\n if (this.duration && this.easing) {\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 } else 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 // If no easing or lerp, just jump to the end value\r\n this.value = this.to\r\n completed = true\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: number,\r\n to: number,\r\n {\r\n lerp,\r\n duration,\r\n easing,\r\n onStart,\r\n onUpdate,\r\n }: {\r\n lerp?: number\r\n duration?: number\r\n easing?: Function\r\n onStart?: Function\r\n onUpdate?: Function\r\n }\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\ntype DimensionsOptions = {\r\n wrapper: Window | HTMLElement\r\n content: HTMLElement\r\n autoResize?: boolean\r\n debounce?: number\r\n}\r\n\r\nexport class Dimensions {\r\n wrapper: Window | HTMLElement\r\n content: HTMLElement\r\n width: number = 0\r\n height: number = 0\r\n scrollWidth: number = 0\r\n scrollHeight: number = 0\r\n debouncedResize?: Function\r\n wrapperResizeObserver?: ResizeObserver\r\n contentResizeObserver?: ResizeObserver\r\n\r\n // @ts-ignore\r\n constructor({\r\n wrapper,\r\n content,\r\n autoResize = true,\r\n debounce: debounceValue = 250,\r\n }: DimensionsOptions = {}) {\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(\r\n 'resize',\r\n this.debouncedResize as EventListener,\r\n false\r\n )\r\n } else {\r\n this.wrapperResizeObserver = new ResizeObserver(\r\n this.debouncedResize as ResizeObserverCallback\r\n )\r\n this.wrapperResizeObserver.observe(this.wrapper as HTMLElement)\r\n }\r\n\r\n this.contentResizeObserver = new ResizeObserver(\r\n this.debouncedResize as ResizeObserverCallback\r\n )\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(\r\n 'resize',\r\n this.debouncedResize as EventListener,\r\n false\r\n )\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 if (this.wrapper instanceof HTMLElement) {\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 if (this.wrapper instanceof HTMLElement) {\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 x: number\r\n y: number\r\n } {\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 events: Record<string, Function[]>\r\n\r\n constructor() {\r\n this.events = {}\r\n }\r\n\r\n emit(event: string, ...args: any[]) {\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: string, callback: Function) {\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(callback) || (this.events[event] = [callback])\r\n\r\n // Return an unsubscribe function\r\n return () => {\r\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\r\n }\r\n }\r\n\r\n off(event: string, callback: Function) {\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 element: HTMLElement | Window\r\n wheelMultiplier: number\r\n touchMultiplier: number\r\n touchStart: {\r\n x: number | null\r\n y: number | null\r\n }\r\n emitter: Emitter\r\n lastDelta: {\r\n x: number\r\n y: number\r\n } = {\r\n x: 0,\r\n y: 0,\r\n }\r\n windowWidth: number = 0\r\n windowHeight: number = 0\r\n\r\n constructor(\r\n element: HTMLElement | Window,\r\n { wheelMultiplier = 1, touchMultiplier = 1 }\r\n ) {\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 as EventListener, {\r\n passive: false,\r\n })\r\n this.element.addEventListener(\r\n 'touchstart',\r\n this.onTouchStart as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n this.element.addEventListener(\r\n 'touchmove',\r\n this.onTouchMove as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n this.element.addEventListener(\r\n 'touchend',\r\n this.onTouchEnd as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n }\r\n\r\n // Add an event listener for the given event and callback\r\n on(event: string, callback: Function) {\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 as EventListener)\r\n this.element.removeEventListener(\r\n 'touchstart',\r\n this.onTouchStart as EventListener\r\n )\r\n this.element.removeEventListener(\r\n 'touchmove',\r\n this.onTouchMove as EventListener\r\n )\r\n this.element.removeEventListener(\r\n 'touchend',\r\n this.onTouchEnd as EventListener\r\n )\r\n }\r\n\r\n // Event handler for 'touchstart' event\r\n onTouchStart = (event: TouchEvent) => {\r\n // @ts-expect-error\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: TouchEvent) => {\r\n // @ts-expect-error\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 ?? 0)) * this.touchMultiplier\r\n const deltaY = -(clientY - (this.touchStart?.y ?? 0)) * 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: TouchEvent) => {\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: WheelEvent) => {\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 Overwrite<T, R> = Omit<T, keyof R> & R\r\n\r\ntype EasingFunction = (t: number) => number\r\ntype Orientation = 'vertical' | 'horizontal'\r\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\r\ntype Scrolling = boolean | 'native' | 'smooth'\r\n\r\ntype onVirtualScrollOptions = {\r\n deltaX: number\r\n deltaY: number\r\n event: WheelEvent | TouchEvent\r\n}\r\n\r\nexport type LenisOptions = Partial<{\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: (node: Element) => boolean\r\n virtualScroll: (data: onVirtualScrollOptions) => 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: Scrolling = 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 __preventNextNativeScrollEvent?: boolean\r\n __resetVelocityTimeout?: number\r\n\r\n isTouching?: boolean\r\n time: number\r\n userData: Object = {}\r\n lastVelocity: number = 0\r\n velocity: number = 0\r\n direction: 1 | -1 | 0 = 0\r\n options: Overwrite<\r\n LenisOptions,\r\n {\r\n wrapper: NonNullable<LenisOptions['wrapper']>\r\n }\r\n >\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 = 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,\r\n virtualScroll,\r\n __experimental__naiveDimensions = false,\r\n }: LenisOptions = {}) {\r\n // @ts-expect-error\r\n window.lenisVersion = version\r\n\r\n // if wrapper is html or body, fallback to window\r\n if (\r\n !wrapper ||\r\n wrapper === document.documentElement ||\r\n wrapper === document.body\r\n ) {\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 virtualScroll,\r\n __experimental__naiveDimensions,\r\n } as LenisOptions\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.options.wrapper.addEventListener(\r\n 'pointerdown',\r\n this.onPointerDown as EventListener,\r\n false\r\n )\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 this.options.wrapper.removeEventListener(\r\n 'pointerdown',\r\n this.onPointerDown as EventListener,\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: number) {\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 onPointerDown = (event: PointerEvent | MouseEvent) => {\r\n if (event.button === 1) {\r\n this.reset()\r\n }\r\n }\r\n\r\n private onVirtualScroll = (data: onVirtualScrollOptions) => {\r\n if (\r\n typeof this.options.virtualScroll === 'function' &&\r\n this.options.virtualScroll(data) === false\r\n )\r\n return\r\n\r\n const { deltaX, deltaY, event } = data\r\n\r\n this.emitter.emit('virtual-scroll', { deltaX, deltaY, event })\r\n\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 const prevent = this.options.prevent\r\n\r\n if (\r\n !!composedPath.find(\r\n (node) =>\r\n node instanceof Element &&\r\n ((typeof prevent === 'function' && 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() {\r\n this.emitter.emit('scroll', this)\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(\r\n this.animatedScroll - lastScroll\r\n ) as Lenis['direction']\r\n // this.isSmooth = false\r\n this.isScrolling = 'native'\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 = 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 (\r\n typeof target === 'string' &&\r\n ['top', 'left', 'start'].includes(target)\r\n ) {\r\n target = 0\r\n } else if (\r\n typeof target === 'string' &&\r\n ['bottom', 'right', 'end'].includes(target)\r\n ) {\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 instanceof HTMLElement && 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.rootElement.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 (target === this.targetScroll) return\r\n\r\n this.userData = userData\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 this.preventNextNativeScrollEvent()\r\n this.emit()\r\n onComplete?.(this)\r\n this.userData = {}\r\n return\r\n }\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) as Lenis['direction']\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 this.userData = {}\r\n\r\n // avoid emitting event twice\r\n this.preventNextNativeScrollEvent()\r\n }\r\n },\r\n })\r\n }\r\n\r\n private preventNextNativeScrollEvent() {\r\n this.__preventNextNativeScrollEvent = true\r\n\r\n requestAnimationFrame(() => {\r\n delete this.__preventNextNativeScrollEvent\r\n })\r\n }\r\n\r\n get rootElement() {\r\n return (\r\n this.options.wrapper === window\r\n ? document.documentElement\r\n : this.options.wrapper\r\n ) as HTMLElement\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: Scrolling) {\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 }\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"],"names":["clamp","min","input","max","Math","Animate","constructor","this","isRunning","value","from","to","duration","currentTime","advance","deltaTime","completed","easing","linearProgress","easedProgress","lerp","damp","x","y","lambda","dt","t","exp","round","stop","_a","onUpdate","call","fromTo","onStart","Dimensions","wrapper","content","autoResize","debounce","debounceValue","width","height","scrollWidth","scrollHeight","resize","onWrapperResize","onContentResize","window","innerWidth","innerHeight","HTMLElement","clientWidth","clientHeight","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","_b","removeEventListener","limit","Emitter","events","emit","event","callbacks","i","length","on","push","filter","off","LINE_HEIGHT","VirtualScroll","element","wheelMultiplier","touchMultiplier","lastDelta","windowWidth","windowHeight","onTouchStart","clientX","clientY","targetTouches","touchStart","emitter","deltaX","deltaY","onTouchMove","_d","_c","onTouchEnd","onWheel","deltaMode","onWindowResize","passive","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","prevent","virtualScroll","__experimental__naiveDimensions","__isScrolling","__isStopped","__isLocked","userData","lastVelocity","velocity","direction","onPointerDown","button","reset","onVirtualScroll","data","options","ctrlKey","isTouch","type","includes","isWheel","isTouching","isStopped","isLocked","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","Element","hasAttribute","classList","contains","_e","preventDefault","isScrolling","animate","delta","abs","hasTouchInertia","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__resetVelocityTimeout","__preventNextNativeScrollEvent","lastScroll","animatedScroll","actualScroll","sign","lenisVersion","body","dimensions","updateClassName","time","cleanUpClassName","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","preventNextNativeScrollEvent","requestAnimationFrame","modulo","n","d","progress","isSmooth","className","trim","replace"],"mappings":"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"}
1
+ {"version":3,"file":"lenis.min.js","sources":["../src/maths.js","../../src/animate.ts","../../src/dimensions.ts","../src/debounce.js","../../src/emitter.ts","../../src/virtual-scroll.ts","../../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 isRunning: boolean = false\r\n value: number = 0\r\n from: number = 0\r\n to: number = 0\r\n lerp?: number\r\n duration?: number = 0\r\n easing?: Function\r\n currentTime: number = 0\r\n onUpdate?: Function\r\n\r\n // Advance the animation by the given delta time\r\n advance(deltaTime: number) {\r\n if (!this.isRunning) return\r\n\r\n let completed = false\r\n\r\n if (this.duration && this.easing) {\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 } else 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 // If no easing or lerp, just jump to the end value\r\n this.value = this.to\r\n completed = true\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: number,\r\n to: number,\r\n {\r\n lerp,\r\n duration,\r\n easing,\r\n onStart,\r\n onUpdate,\r\n }: {\r\n lerp?: number\r\n duration?: number\r\n easing?: Function\r\n onStart?: Function\r\n onUpdate?: Function\r\n }\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\ntype DimensionsOptions = {\r\n wrapper: Window | HTMLElement\r\n content: HTMLElement\r\n autoResize?: boolean\r\n debounce?: number\r\n}\r\n\r\nexport class Dimensions {\r\n wrapper: Window | HTMLElement\r\n content: HTMLElement\r\n width: number = 0\r\n height: number = 0\r\n scrollWidth: number = 0\r\n scrollHeight: number = 0\r\n debouncedResize?: Function\r\n wrapperResizeObserver?: ResizeObserver\r\n contentResizeObserver?: ResizeObserver\r\n\r\n // @ts-ignore\r\n constructor({\r\n wrapper,\r\n content,\r\n autoResize = true,\r\n debounce: debounceValue = 250,\r\n }: DimensionsOptions = {}) {\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(\r\n 'resize',\r\n this.debouncedResize as EventListener,\r\n false\r\n )\r\n } else {\r\n this.wrapperResizeObserver = new ResizeObserver(\r\n this.debouncedResize as ResizeObserverCallback\r\n )\r\n this.wrapperResizeObserver.observe(this.wrapper as HTMLElement)\r\n }\r\n\r\n this.contentResizeObserver = new ResizeObserver(\r\n this.debouncedResize as ResizeObserverCallback\r\n )\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(\r\n 'resize',\r\n this.debouncedResize as EventListener,\r\n false\r\n )\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 if (this.wrapper instanceof HTMLElement) {\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 if (this.wrapper instanceof HTMLElement) {\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 x: number\r\n y: number\r\n } {\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 events: Record<string, Function[]>\r\n\r\n constructor() {\r\n this.events = {}\r\n }\r\n\r\n emit(event: string, ...args: any[]) {\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: string, callback: Function) {\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(callback) || (this.events[event] = [callback])\r\n\r\n // Return an unsubscribe function\r\n return () => {\r\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\r\n }\r\n }\r\n\r\n off(event: string, callback: Function) {\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 element: HTMLElement | Window\r\n wheelMultiplier: number\r\n touchMultiplier: number\r\n touchStart: {\r\n x: number | null\r\n y: number | null\r\n }\r\n emitter: Emitter\r\n lastDelta: {\r\n x: number\r\n y: number\r\n } = {\r\n x: 0,\r\n y: 0,\r\n }\r\n windowWidth: number = 0\r\n windowHeight: number = 0\r\n\r\n constructor(\r\n element: HTMLElement | Window,\r\n { wheelMultiplier = 1, touchMultiplier = 1 }\r\n ) {\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 as EventListener, {\r\n passive: false,\r\n })\r\n this.element.addEventListener(\r\n 'touchstart',\r\n this.onTouchStart as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n this.element.addEventListener(\r\n 'touchmove',\r\n this.onTouchMove as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n this.element.addEventListener(\r\n 'touchend',\r\n this.onTouchEnd as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n }\r\n\r\n // Add an event listener for the given event and callback\r\n on(event: string, callback: Function) {\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 as EventListener)\r\n this.element.removeEventListener(\r\n 'touchstart',\r\n this.onTouchStart as EventListener\r\n )\r\n this.element.removeEventListener(\r\n 'touchmove',\r\n this.onTouchMove as EventListener\r\n )\r\n this.element.removeEventListener(\r\n 'touchend',\r\n this.onTouchEnd as EventListener\r\n )\r\n }\r\n\r\n // Event handler for 'touchstart' event\r\n onTouchStart = (event: TouchEvent) => {\r\n // @ts-expect-error\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: TouchEvent) => {\r\n // @ts-expect-error\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 ?? 0)) * this.touchMultiplier\r\n const deltaY = -(clientY - (this.touchStart?.y ?? 0)) * 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: TouchEvent) => {\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: WheelEvent) => {\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 Overwrite<T, R> = Omit<T, keyof R> & R\r\n\r\ntype EasingFunction = (t: number) => number\r\ntype Orientation = 'vertical' | 'horizontal'\r\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\r\ntype Scrolling = boolean | 'native' | 'smooth'\r\n\r\ntype onVirtualScrollOptions = {\r\n deltaX: number\r\n deltaY: number\r\n event: WheelEvent | TouchEvent\r\n}\r\n\r\nexport type LenisOptions = Partial<{\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: (node: Element) => boolean\r\n virtualScroll: (data: onVirtualScrollOptions) => 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: Scrolling = 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 __preventNextNativeScrollEvent?: boolean\r\n __resetVelocityTimeout?: number\r\n\r\n isTouching?: boolean\r\n time: number\r\n userData: Object = {}\r\n lastVelocity: number = 0\r\n velocity: number = 0\r\n direction: 1 | -1 | 0 = 0\r\n options: Overwrite<\r\n LenisOptions,\r\n {\r\n wrapper: NonNullable<LenisOptions['wrapper']>\r\n }\r\n >\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 = 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,\r\n virtualScroll,\r\n __experimental__naiveDimensions = false,\r\n }: LenisOptions = {}) {\r\n // @ts-expect-error\r\n window.lenisVersion = version\r\n\r\n // if wrapper is html or body, fallback to window\r\n if (\r\n !wrapper ||\r\n wrapper === document.documentElement ||\r\n wrapper === document.body\r\n ) {\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 virtualScroll,\r\n __experimental__naiveDimensions,\r\n } as LenisOptions\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.options.wrapper.addEventListener(\r\n 'pointerdown',\r\n this.onPointerDown as EventListener,\r\n false\r\n )\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 this.options.wrapper.removeEventListener(\r\n 'pointerdown',\r\n this.onPointerDown as EventListener,\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: number) {\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 onPointerDown = (event: PointerEvent | MouseEvent) => {\r\n if (event.button === 1) {\r\n this.reset()\r\n }\r\n }\r\n\r\n private onVirtualScroll = (data: onVirtualScrollOptions) => {\r\n if (\r\n typeof this.options.virtualScroll === 'function' &&\r\n this.options.virtualScroll(data) === false\r\n )\r\n return\r\n\r\n const { deltaX, deltaY, event } = data\r\n\r\n this.emitter.emit('virtual-scroll', { deltaX, deltaY, event })\r\n\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 const prevent = this.options.prevent\r\n\r\n if (\r\n !!composedPath.find(\r\n (node) =>\r\n node instanceof Element &&\r\n ((typeof prevent === 'function' && 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() {\r\n this.emitter.emit('scroll', this)\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(\r\n this.animatedScroll - lastScroll\r\n ) as Lenis['direction']\r\n // this.isSmooth = false\r\n this.isScrolling = 'native'\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 = 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 (\r\n typeof target === 'string' &&\r\n ['top', 'left', 'start'].includes(target)\r\n ) {\r\n target = 0\r\n } else if (\r\n typeof target === 'string' &&\r\n ['bottom', 'right', 'end'].includes(target)\r\n ) {\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 instanceof HTMLElement && 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.rootElement.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 (target === this.targetScroll) return\r\n\r\n this.userData = userData\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 this.preventNextNativeScrollEvent()\r\n this.emit()\r\n onComplete?.(this)\r\n this.userData = {}\r\n return\r\n }\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) as Lenis['direction']\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 this.userData = {}\r\n\r\n // avoid emitting event twice\r\n this.preventNextNativeScrollEvent()\r\n }\r\n },\r\n })\r\n }\r\n\r\n private preventNextNativeScrollEvent() {\r\n this.__preventNextNativeScrollEvent = true\r\n\r\n requestAnimationFrame(() => {\r\n delete this.__preventNextNativeScrollEvent\r\n })\r\n }\r\n\r\n get rootElement() {\r\n return (\r\n this.options.wrapper === window\r\n ? document.documentElement\r\n : this.options.wrapper\r\n ) as HTMLElement\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: Scrolling) {\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 }\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"],"names":["clamp","min","input","max","Math","Animate","constructor","this","isRunning","value","from","to","duration","currentTime","advance","deltaTime","completed","easing","linearProgress","easedProgress","lerp","damp","x","y","lambda","dt","t","exp","round","stop","_a","onUpdate","call","fromTo","onStart","Dimensions","wrapper","content","autoResize","debounce","debounceValue","width","height","scrollWidth","scrollHeight","resize","onWrapperResize","onContentResize","window","innerWidth","innerHeight","HTMLElement","clientWidth","clientHeight","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","_b","removeEventListener","limit","Emitter","events","emit","event","callbacks","i","length","on","push","filter","off","LINE_HEIGHT","VirtualScroll","element","wheelMultiplier","touchMultiplier","lastDelta","windowWidth","windowHeight","onTouchStart","clientX","clientY","targetTouches","touchStart","emitter","deltaX","deltaY","onTouchMove","_d","_c","onTouchEnd","onWheel","deltaMode","onWindowResize","passive","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","prevent","virtualScroll","__experimental__naiveDimensions","__isScrolling","__isStopped","__isLocked","userData","lastVelocity","velocity","direction","onPointerDown","button","reset","onVirtualScroll","data","options","ctrlKey","isTouch","type","includes","isWheel","isTouching","isStopped","isLocked","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","Element","hasAttribute","classList","contains","_e","preventDefault","isScrolling","animate","delta","abs","hasTouchInertia","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__resetVelocityTimeout","__preventNextNativeScrollEvent","lastScroll","animatedScroll","actualScroll","sign","lenisVersion","body","dimensions","updateClassName","time","cleanUpClassName","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","preventNextNativeScrollEvent","requestAnimationFrame","modulo","n","d","progress","isSmooth","className","trim","replace"],"mappings":"sOACO,SAASA,MAAMC,EAAKC,EAAOC,GAChC,OAAOC,KAAKD,IAAIF,EAAKG,KAAKH,IAAIC,EAAOC,GACvC,OCAaE,QAAb,WAAAC,GACEC,KAASC,WAAY,EACrBD,KAAKE,MAAW,EAChBF,KAAIG,KAAW,EACfH,KAAEI,GAAW,EAEbJ,KAAQK,SAAY,EAEpBL,KAAWM,YAAW,CAuEvB,CAnEC,OAAAC,CAAQC,SACN,IAAKR,KAAKC,UAAW,OAErB,IAAIQ,GAAY,EAEhB,GAAIT,KAAKK,UAAYL,KAAKU,OAAQ,CAChCV,KAAKM,aAAeE,EACpB,MAAMG,EAAiBlB,MAAM,EAAGO,KAAKM,YAAcN,KAAKK,SAAU,GAElEI,EAAYE,GAAkB,EAC9B,MAAMC,EAAgBH,EAAY,EAAIT,KAAKU,OAAOC,GAClDX,KAAKE,MAAQF,KAAKG,MAAQH,KAAKI,GAAKJ,KAAKG,MAAQS,CAClD,MAAUZ,KAAKa,MACdb,KAAKE,MDZJ,SAASY,KAAKC,EAAGC,EAAGC,EAAQC,GACjC,OANK,SAASL,KAAKE,EAAGC,EAAGG,GACzB,OAAQ,EAAIA,GAAKJ,EAAII,EAAIH,CAC3B,CAISH,CAAKE,EAAGC,EAAG,EAAInB,KAAKuB,KAAKH,EAASC,GAC3C,CCUmBJ,CAAKd,KAAKE,MAAOF,KAAKI,GAAgB,GAAZJ,KAAKa,KAAWL,GACnDX,KAAKwB,MAAMrB,KAAKE,SAAWF,KAAKI,KAClCJ,KAAKE,MAAQF,KAAKI,GAClBK,GAAY,KAIdT,KAAKE,MAAQF,KAAKI,GAClBK,GAAY,GAGVA,GACFT,KAAKsB,OAIS,QAAhBC,EAAAvB,KAAKwB,gBAAW,IAAAD,GAAAA,EAAAE,KAAAzB,KAAAA,KAAKE,MAAOO,EAC7B,CAGD,IAAAa,GACEtB,KAAKC,WAAY,CAClB,CAID,MAAAyB,CACEvB,EACAC,GACAS,KACEA,EAAIR,SACJA,EAAQK,OACRA,EAAMiB,QACNA,EAAOH,SACPA,IASFxB,KAAKG,KAAOH,KAAKE,MAAQC,EACzBH,KAAKI,GAAKA,EACVJ,KAAKa,KAAOA,EACZb,KAAKK,SAAWA,EAChBL,KAAKU,OAASA,EACdV,KAAKM,YAAc,EACnBN,KAAKC,WAAY,EAEjB0B,SAAAA,IACA3B,KAAKwB,SAAWA,CACjB,QCxEUI,WAYX,WAAA7B,EAAY8B,QACVA,EAAOC,QACPA,EAAOC,WACPA,GAAa,EACbC,SAAUC,EAAgB,KACL,IAdvBjC,KAAKkC,MAAW,EAChBlC,KAAMmC,OAAW,EACjBnC,KAAWoC,YAAW,EACtBpC,KAAYqC,aAAW,EAkDvBrC,KAAMsC,OAAG,KACPtC,KAAKuC,kBACLvC,KAAKwC,iBAAiB,EAGxBxC,KAAeuC,gBAAG,KACZvC,KAAK6B,UAAYY,QACnBzC,KAAKkC,MAAQO,OAAOC,WACpB1C,KAAKmC,OAASM,OAAOE,aACZ3C,KAAK6B,mBAAmBe,cACjC5C,KAAKkC,MAAQlC,KAAK6B,QAAQgB,YAC1B7C,KAAKmC,OAASnC,KAAK6B,QAAQiB,aAC5B,EAGH9C,KAAewC,gBAAG,KACZxC,KAAK6B,UAAYY,QACnBzC,KAAKqC,aAAerC,KAAK8B,QAAQO,aACjCrC,KAAKoC,YAAcpC,KAAK8B,QAAQM,aACvBpC,KAAK6B,mBAAmBe,cACjC5C,KAAKqC,aAAerC,KAAK6B,QAAQQ,aACjCrC,KAAKoC,YAAcpC,KAAK6B,QAAQO,YACjC,EA5DDpC,KAAK6B,QAAUA,EACf7B,KAAK8B,QAAUA,EAEXC,IACF/B,KAAK+C,gBC/BJ,SAASf,SAASgB,EAAUC,GACjC,IAAIC,EACJ,OAAO,WACL,IAAIC,EAAOC,UACPC,EAAUrD,KACdsD,aAAaJ,GACbA,EAAQK,YAAW,WACjBP,EAASQ,MAAMH,EAASF,EACzB,GAAEF,EACJ,CACH,CDqB6BjB,CAAShC,KAAKsC,OAAQL,GAEzCjC,KAAK6B,UAAYY,OACnBA,OAAOgB,iBACL,SACAzD,KAAK+C,iBACL,IAGF/C,KAAK0D,sBAAwB,IAAIC,eAC/B3D,KAAK+C,iBAEP/C,KAAK0D,sBAAsBE,QAAQ5D,KAAK6B,UAG1C7B,KAAK6D,sBAAwB,IAAIF,eAC/B3D,KAAK+C,iBAEP/C,KAAK6D,sBAAsBD,QAAQ5D,KAAK8B,UAG1C9B,KAAKsC,QACN,CAED,OAAAwB,WAC8B,QAA5BvC,EAAAvB,KAAK0D,6BAAuB,IAAAnC,GAAAA,EAAAwC,aACA,QAA5BC,EAAAhE,KAAK6D,6BAAuB,IAAAG,GAAAA,EAAAD,aAC5BtB,OAAOwB,oBACL,SACAjE,KAAK+C,iBACL,EAEH,CA2BD,SAAImB,GAIF,MAAO,CACLnD,EAAGf,KAAKoC,YAAcpC,KAAKkC,MAC3BlB,EAAGhB,KAAKqC,aAAerC,KAAKmC,OAE/B,QElGUgC,QAGX,WAAApE,GACEC,KAAKoE,OAAS,EACf,CAED,IAAAC,CAAKC,KAAkBnB,GACrB,IAAIoB,EAAYvE,KAAKoE,OAAOE,IAAU,GACtC,IAAK,IAAIE,EAAI,EAAGC,EAASF,EAAUE,OAAQD,EAAIC,EAAQD,IACrDD,EAAUC,MAAMrB,EAEnB,CAED,EAAAuB,CAAGJ,EAAetB,SAKhB,OAHkB,QAAlBzB,EAAAvB,KAAKoE,OAAOE,UAAM,IAAA/C,OAAA,EAAAA,EAAEoD,KAAK3B,MAAchD,KAAKoE,OAAOE,GAAS,CAACtB,IAGtD,WACLhD,KAAKoE,OAAOE,GAA6B,QAApB/C,EAAAvB,KAAKoE,OAAOE,UAAQ,IAAA/C,OAAA,EAAAA,EAAAqD,QAAQJ,GAAMxB,IAAawB,GAAE,CAEzE,CAED,GAAAK,CAAIP,EAAetB,SACjBhD,KAAKoE,OAAOE,GAA6B,QAApB/C,EAAAvB,KAAKoE,OAAOE,UAAQ,IAAA/C,OAAA,EAAAA,EAAAqD,QAAQJ,GAAMxB,IAAawB,GACrE,CAED,OAAAV,GACE9D,KAAKoE,OAAS,EACf,EC5BH,MAAMU,EAAc,IAAM,QAEbC,cAmBX,WAAAhF,CACEiF,GACAC,gBAAEA,EAAkB,EAACC,gBAAEA,EAAkB,IAZ3ClF,KAAAmF,UAGI,CACFpE,EAAG,EACHC,EAAG,GAELhB,KAAWoF,YAAW,EACtBpF,KAAYqF,aAAW,EAwEvBrF,KAAAsF,aAAgBhB,IAEd,MAAMiB,QAAEA,EAAOC,QAAEA,GAAYlB,EAAMmB,cAC/BnB,EAAMmB,cAAc,GACpBnB,EAEJtE,KAAK0F,WAAW3E,EAAIwE,EACpBvF,KAAK0F,WAAW1E,EAAIwE,EAEpBxF,KAAKmF,UAAY,CACfpE,EAAG,EACHC,EAAG,GAGLhB,KAAK2F,QAAQtB,KAAK,SAAU,CAC1BuB,OAAQ,EACRC,OAAQ,EACRvB,SACA,EAIJtE,KAAA8F,YAAexB,gBAEb,MAAMiB,QAAEA,EAAOC,QAAEA,GAAYlB,EAAMmB,cAC/BnB,EAAMmB,cAAc,GACpBnB,EAEEsB,IAAWL,WAAWvB,EAAiB,QAAjBzC,EAAAvB,KAAK0F,kBAAY,IAAAnE,OAAA,EAAAA,EAAAR,iBAAK,IAAMf,KAAKkF,gBACvDW,IAAWL,WAAWO,EAAiB,QAAjBC,EAAAhG,KAAK0F,kBAAY,IAAAM,OAAA,EAAAA,EAAAhF,iBAAK,IAAMhB,KAAKkF,gBAE7DlF,KAAK0F,WAAW3E,EAAIwE,EACpBvF,KAAK0F,WAAW1E,EAAIwE,EAEpBxF,KAAKmF,UAAY,CACfpE,EAAG6E,EACH5E,EAAG6E,GAGL7F,KAAK2F,QAAQtB,KAAK,SAAU,CAC1BuB,SACAC,SACAvB,SACA,EAGJtE,KAAAiG,WAAc3B,IACZtE,KAAK2F,QAAQtB,KAAK,SAAU,CAC1BuB,OAAQ5F,KAAKmF,UAAUpE,EACvB8E,OAAQ7F,KAAKmF,UAAUnE,EACvBsD,SACA,EAIJtE,KAAAkG,QAAW5B,IACT,IAAIsB,OAAEA,EAAMC,OAAEA,EAAMM,UAAEA,GAAc7B,EAOpCsB,GAJgB,IAAdO,EAAkBrB,EAA4B,IAAdqB,EAAkBnG,KAAKoF,YAAc,EAKvES,GAHgB,IAAdM,EAAkBrB,EAA4B,IAAdqB,EAAkBnG,KAAKqF,aAAe,EAKxEO,GAAU5F,KAAKiF,gBACfY,GAAU7F,KAAKiF,gBAEfjF,KAAK2F,QAAQtB,KAAK,SAAU,CAAEuB,SAAQC,SAAQvB,SAAQ,EAGxDtE,KAAcoG,eAAG,KACfpG,KAAKoF,YAAc3C,OAAOC,WAC1B1C,KAAKqF,aAAe5C,OAAOE,WAAW,EA5ItC3C,KAAKgF,QAAUA,EACfhF,KAAKiF,gBAAkBA,EACvBjF,KAAKkF,gBAAkBA,EAEvBlF,KAAK0F,WAAa,CAChB3E,EAAG,KACHC,EAAG,MAGLhB,KAAK2F,QAAU,IAAIxB,QACnB1B,OAAOgB,iBAAiB,SAAUzD,KAAKoG,gBAAgB,GACvDpG,KAAKoG,iBAELpG,KAAKgF,QAAQvB,iBAAiB,QAASzD,KAAKkG,QAA0B,CACpEG,SAAS,IAEXrG,KAAKgF,QAAQvB,iBACX,aACAzD,KAAKsF,aACL,CACEe,SAAS,IAGbrG,KAAKgF,QAAQvB,iBACX,YACAzD,KAAK8F,YACL,CACEO,SAAS,IAGbrG,KAAKgF,QAAQvB,iBACX,WACAzD,KAAKiG,WACL,CACEI,SAAS,GAGd,CAGD,EAAA3B,CAAGJ,EAAetB,GAChB,OAAOhD,KAAK2F,QAAQjB,GAAGJ,EAAOtB,EAC/B,CAGD,OAAAc,GACE9D,KAAK2F,QAAQ7B,UAEbrB,OAAOwB,oBAAoB,SAAUjE,KAAKoG,gBAAgB,GAE1DpG,KAAKgF,QAAQf,oBAAoB,QAASjE,KAAKkG,SAC/ClG,KAAKgF,QAAQf,oBACX,aACAjE,KAAKsF,cAEPtF,KAAKgF,QAAQf,oBACX,YACAjE,KAAK8F,aAEP9F,KAAKgF,QAAQf,oBACX,WACAjE,KAAKiG,WAER,SCvCW,MAAOK,MA2BnB,WAAAvG,EAAY8B,QACVA,EAAUY,OAAMX,QAChBA,EAAUyE,SAASC,gBAAeC,kBAClCA,EAAoB5E,EAAO6E,aAC3BA,EAAeD,EAAiBE,YAChCA,GAAc,EAAIC,UAClBA,GAAY,EAAKC,cACjBA,EAAgB,KAAKC,uBACrBA,EAAyB,GAAEzG,SAC3BA,EAAQK,OACRA,EAAS,CAACS,GAAMtB,KAAKH,IAAI,EAAG,MAAQG,KAAKkH,IAAI,GAAI,GAAK5F,KAAGN,KACzDA,EAAO,GAAGmG,SACVA,GAAW,EAAKC,YAChBA,EAAc,WAAUC,mBACxBA,EAAqB,WAAUhC,gBAC/BA,EAAkB,EAACD,gBACnBA,EAAkB,EAAClD,WACnBA,GAAa,EAAIoF,QACjBA,EAAOC,cACPA,EAAaC,gCACbA,GAAkC,GAClB,CAAA,GA9ClBrH,KAAasH,eAAc,EAC3BtH,KAAWuH,aAAY,EACvBvH,KAAUwH,YAAY,EAMtBxH,KAAQyH,SAAW,GACnBzH,KAAY0H,aAAW,EACvB1H,KAAQ2H,SAAW,EACnB3H,KAAS4H,UAAe,EAoJhB5H,KAAA6H,cAAiBvD,IACF,IAAjBA,EAAMwD,QACR9H,KAAK+H,OACN,EAGK/H,KAAAgI,gBAAmBC,IACzB,GACwC,mBAA/BjI,KAAKkI,QAAQd,gBACiB,IAArCpH,KAAKkI,QAAQd,cAAca,GAE3B,OAEF,MAAMrC,OAAEA,EAAMC,OAAEA,EAAMvB,MAAEA,GAAU2D,EAKlC,GAHAjI,KAAK2F,QAAQtB,KAAK,iBAAkB,CAAEuB,SAAQC,SAAQvB,UAGlDA,EAAM6D,QAAS,OAEnB,MAAMC,EAAU9D,EAAM+D,KAAKC,SAAS,SAC9BC,EAAUjE,EAAM+D,KAAKC,SAAS,SAEpCtI,KAAKwI,WAA4B,eAAflE,EAAM+D,MAAwC,cAAf/D,EAAM+D,KAkBvD,GANErI,KAAKkI,QAAQtB,WACbwB,GACe,eAAf9D,EAAM+D,OACLrI,KAAKyI,YACLzI,KAAK0I,SAIN,YADA1I,KAAK+H,QAIP,MAAMY,EAAqB,IAAX/C,GAA2B,IAAXC,EAQ1B+C,EACiC,aAApC5I,KAAKkI,QAAQhB,oBAAgD,IAAXrB,GACd,eAApC7F,KAAKkI,QAAQhB,oBAAkD,IAAXtB,EAEvD,GAAI+C,GAAWC,EAEb,OAIF,IAAIC,EAAevE,EAAMuE,eACzBA,EAAeA,EAAaC,MAAM,EAAGD,EAAaE,QAAQ/I,KAAKgJ,cAE/D,MAAM7B,EAAUnH,KAAKkI,QAAQf,QAE7B,GACI0B,EAAaI,MACZC,kBACC,OAAAA,aAAgBC,UACK,mBAAZhC,IAA0BA,eAAAA,EAAU+B,MACvB,QAApB3H,EAAA2H,EAAKE,oBAAe,IAAA7H,OAAA,EAAAA,EAAAE,KAAAyH,EAAA,wBACnBd,IAA+B,QAApBpE,EAAAkF,EAAKE,oBAAe,IAAApF,OAAA,EAAAA,EAAAvC,KAAAyH,EAAA,8BAC/BX,IAA+B,QAApBvC,EAAAkD,EAAKE,oBAAe,IAAApD,OAAA,EAAAA,EAAAvE,KAAAyH,EAAA,+BACf,UAAhBA,EAAKG,iBAAW,IAAAtD,OAAA,EAAAA,EAAAuD,SAAS,aACT,QAAdC,EAAAL,EAAKG,iBAAS,IAAAE,OAAA,EAAAA,EAAED,SAAS,kBAAkB,IAGpD,OAEF,GAAItJ,KAAKyI,WAAazI,KAAK0I,SAEzB,YADApE,EAAMkF,iBAQR,KAHGxJ,KAAKkI,QAAQtB,WAAawB,GAC1BpI,KAAKkI,QAAQvB,aAAe4B,GAK7B,OAFAvI,KAAKyJ,YAAc,cACnBzJ,KAAK0J,QAAQpI,OAIfgD,EAAMkF,iBAEN,IAAIG,EAAQ9D,EAC4B,SAApC7F,KAAKkI,QAAQhB,mBACfyC,EAAQ9J,KAAK+J,IAAI/D,GAAUhG,KAAK+J,IAAIhE,GAAUC,EAASD,EACV,eAApC5F,KAAKkI,QAAQhB,qBACtByC,EAAQ/D,GAGV,MAAMgB,EAAYwB,GAAWpI,KAAKkI,QAAQtB,UAGpCiD,EAFazB,GAA0B,aAAf9D,EAAM+D,MAEExI,KAAK+J,IAAID,GAAS,EAEpDE,IACFF,EAAQ3J,KAAK2H,SAAW3H,KAAKkI,QAAQpB,wBAGvC9G,KAAK8J,SAAS9J,KAAK+J,aAAeJ,EAAKK,OAAAC,OAAA,CACrCC,cAAc,GACVtD,EACA,CACE/F,KAAMgJ,EAAkB7J,KAAKkI,QAAQrB,cAAgB,GAEvD,CACEhG,KAAMb,KAAKkI,QAAQrH,KACnBR,SAAUL,KAAKkI,QAAQ7H,SACvBK,OAAQV,KAAKkI,QAAQxH,SAE3B,EAWIV,KAAcmK,eAAG,KAIvB,GAHA7G,aAAatD,KAAKoK,+BACXpK,KAAKoK,uBAERpK,KAAKqK,sCACArK,KAAKqK,oCAId,IAAyB,IAArBrK,KAAKyJ,aAA8C,WAArBzJ,KAAKyJ,YAA0B,CAC/D,MAAMa,EAAatK,KAAKuK,eACxBvK,KAAKuK,eAAiBvK,KAAK+J,aAAe/J,KAAKwK,aAC/CxK,KAAK0H,aAAe1H,KAAK2H,SACzB3H,KAAK2H,SAAW3H,KAAKuK,eAAiBD,EACtCtK,KAAK4H,UAAY/H,KAAK4K,KACpBzK,KAAKuK,eAAiBD,GAGxBtK,KAAKyJ,YAAc,SACnBzJ,KAAKqE,OAEiB,IAAlBrE,KAAK2H,WACP3H,KAAKoK,uBAAyB7G,YAAW,KACvCvD,KAAK0H,aAAe1H,KAAK2H,SACzB3H,KAAK2H,SAAW,EAChB3H,KAAKyJ,aAAc,EACnBzJ,KAAKqE,MAAM,GACV,KAKN,GAzRD5B,OAAOiI,qBAIJ7I,GACDA,IAAY0E,SAASC,iBACrB3E,IAAY0E,SAASoE,OAErB9I,EAAUY,QAGZzC,KAAKkI,QAAU,CACbrG,UACAC,UACA2E,oBACAC,eACAC,cACAC,YACAC,gBACAC,yBACAzG,WACAK,SACAG,OACAmG,WACAE,qBACAD,cACA/B,kBACAD,kBACAlD,aACAoF,UACAC,gBACAC,mCAGFrH,KAAK0J,QAAU,IAAI5J,QACnBE,KAAK2F,QAAU,IAAIxB,QACnBnE,KAAK4K,WAAa,IAAIhJ,WAAW,CAAEC,UAASC,UAASC,eAErD/B,KAAK6K,kBAEL7K,KAAKyH,SAAW,GAChBzH,KAAK8K,KAAO,EACZ9K,KAAK2H,SAAW3H,KAAK0H,aAAe,EACpC1H,KAAK0I,UAAW,EAChB1I,KAAKyI,WAAY,EAIjBzI,KAAKyJ,aAAc,EACnBzJ,KAAK+J,aAAe/J,KAAKuK,eAAiBvK,KAAKwK,aAE/CxK,KAAKkI,QAAQrG,QAAQ4B,iBAAiB,SAAUzD,KAAKmK,gBAAgB,GAErEnK,KAAKkI,QAAQrG,QAAQ4B,iBACnB,cACAzD,KAAK6H,eACL,GAGF7H,KAAKoH,cAAgB,IAAIrC,cAAc2B,EAAc,CACnDxB,kBACAD,oBAEFjF,KAAKoH,cAAc1C,GAAG,SAAU1E,KAAKgI,gBACtC,CAED,OAAAlE,GACE9D,KAAK2F,QAAQ7B,UAEb9D,KAAKkI,QAAQrG,QAAQoC,oBACnB,SACAjE,KAAKmK,gBACL,GAEFnK,KAAKkI,QAAQrG,QAAQoC,oBACnB,cACAjE,KAAK6H,eACL,GAGF7H,KAAKoH,cAActD,UACnB9D,KAAK4K,WAAW9G,UAEhB9D,KAAK+K,kBASN,CAED,EAAArG,CAAGJ,EAAetB,GAChB,OAAOhD,KAAK2F,QAAQjB,GAAGJ,EAAOtB,EAC/B,CAED,GAAA6B,CAAIP,EAAetB,GACjB,OAAOhD,KAAK2F,QAAQd,IAAIP,EAAOtB,EAChC,CAEO,SAAAgI,CAAUC,GAEZjL,KAAKkL,aACPlL,KAAKgJ,YAAYmC,WAAaF,EAE9BjL,KAAKgJ,YAAYoC,UAAYH,CAEhC,CAoID,MAAA3I,GACEtC,KAAK4K,WAAWtI,QACjB,CAEO,IAAA+B,GACNrE,KAAK2F,QAAQtB,KAAK,SAAUrE,KAC7B,CAqCO,KAAA+H,GACN/H,KAAK0I,UAAW,EAChB1I,KAAKyJ,aAAc,EACnBzJ,KAAKuK,eAAiBvK,KAAK+J,aAAe/J,KAAKwK,aAC/CxK,KAAK0H,aAAe1H,KAAK2H,SAAW,EACpC3H,KAAK0J,QAAQpI,MACd,CAED,KAAA+J,GACOrL,KAAKyI,YACVzI,KAAKyI,WAAY,EAEjBzI,KAAK+H,QACN,CAED,IAAAzG,GACMtB,KAAKyI,YACTzI,KAAKyI,WAAY,EACjBzI,KAAK0J,QAAQpI,OAEbtB,KAAK+H,QACN,CAED,GAAAuD,CAAIR,GACF,MAAMtK,EAAYsK,GAAQ9K,KAAK8K,MAAQA,GACvC9K,KAAK8K,KAAOA,EAEZ9K,KAAK0J,QAAQnJ,QAAoB,KAAZC,EACtB,CAED,QAAAsJ,CACEyB,GACAC,OACEA,EAAS,EAACC,UACVA,GAAY,EAAKC,KACjBA,GAAO,EAAKrL,SACZA,EAAWL,KAAKkI,QAAQ7H,SAAQK,OAChCA,EAASV,KAAKkI,QAAQxH,OAAMG,KAC5BA,EAAOb,KAAKkI,QAAQrH,KAAIc,QACxBA,EAAOgK,WACPA,EAAUC,MACVA,GAAQ,EAAK1B,aACbA,GAAe,EAAIzC,SACnBA,EAAW,CAAE,GAaX,CAAA,GAEJ,IAAKzH,KAAKyI,YAAazI,KAAK0I,UAAckD,EAA1C,CAGA,GACoB,iBAAXL,GACP,CAAC,MAAO,OAAQ,SAASjD,SAASiD,GAElCA,EAAS,OACJ,GACa,iBAAXA,GACP,CAAC,SAAU,QAAS,OAAOjD,SAASiD,GAEpCA,EAASvL,KAAKkE,UACT,CACL,IAAIgF,EAUJ,GARsB,iBAAXqC,EAETrC,EAAO3C,SAASsF,cAAcN,GACrBA,aAAkB3I,cAAe2I,aAAM,EAANA,EAAQO,YAElD5C,EAAOqC,GAGLrC,EAAM,CACR,GAAIlJ,KAAKkI,QAAQrG,UAAYY,OAAQ,CAEnC,MAAMsJ,EAAc/L,KAAKgJ,YAAYgD,wBACrCR,GAAUxL,KAAKkL,aAAea,EAAYE,KAAOF,EAAYG,GAC9D,CAED,MAAMC,EAAOjD,EAAK8C,wBAElBT,GACGvL,KAAKkL,aAAeiB,EAAKF,KAAOE,EAAKD,KAAOlM,KAAKuK,cACrD,CACF,CAED,GAAsB,iBAAXgB,IAEXA,GAAUC,EACVD,EAAS1L,KAAKwB,MAAMkK,GAEhBvL,KAAKkI,QAAQlB,SACXkD,IACFlK,KAAK+J,aAAe/J,KAAKuK,eAAiBvK,KAAKiL,QAGjDM,EAAS9L,MAAM,EAAG8L,EAAQvL,KAAKkE,OAG7BqH,IAAWvL,KAAK+J,cAApB,CAIA,GAFA/J,KAAKyH,SAAWA,EAEZgE,EAQF,OAPAzL,KAAKuK,eAAiBvK,KAAK+J,aAAewB,EAC1CvL,KAAKgL,UAAUhL,KAAKiL,QACpBjL,KAAK+H,QACL/H,KAAKoM,+BACLpM,KAAKqE,OACLsH,SAAAA,EAAa3L,WACbA,KAAKyH,SAAW,IAIbyC,IACHlK,KAAK+J,aAAewB,GAGtBvL,KAAK0J,QAAQhI,OAAO1B,KAAKuK,eAAgBgB,EAAQ,CAC/ClL,WACAK,SACAG,OACAc,QAAS,KAEH+J,IAAM1L,KAAK0I,UAAW,GAC1B1I,KAAKyJ,YAAc,SACnB9H,SAAAA,EAAU3B,KAAK,EAEjBwB,SAAU,CAACtB,EAAeO,KACxBT,KAAKyJ,YAAc,SAGnBzJ,KAAK0H,aAAe1H,KAAK2H,SACzB3H,KAAK2H,SAAWzH,EAAQF,KAAKuK,eAC7BvK,KAAK4H,UAAY/H,KAAK4K,KAAKzK,KAAK2H,UAEhC3H,KAAKuK,eAAiBrK,EACtBF,KAAKgL,UAAUhL,KAAKiL,QAEhBf,IAEFlK,KAAK+J,aAAe7J,GAGjBO,GAAWT,KAAKqE,OAEjB5D,IACFT,KAAK+H,QACL/H,KAAKqE,OACLsH,SAAAA,EAAa3L,MACbA,KAAKyH,SAAW,GAGhBzH,KAAKoM,+BACN,GAvDmC,CAnDe,CA6GxD,CAEO,4BAAAA,GACNpM,KAAKqK,gCAAiC,EAEtCgC,uBAAsB,YACbrM,KAAKqK,8BAA8B,GAE7C,CAED,eAAIrB,GACF,OACEhJ,KAAKkI,QAAQrG,UAAYY,OACrB8D,SAASC,gBACTxG,KAAKkI,QAAQrG,OAEpB,CAED,SAAIqC,GACF,OAAIlE,KAAKkI,QAAQb,gCACXrH,KAAKkL,aACAlL,KAAKgJ,YAAY5G,YAAcpC,KAAKgJ,YAAYnG,YAEhD7C,KAAKgJ,YAAY3G,aAAerC,KAAKgJ,YAAYlG,aAGnD9C,KAAK4K,WAAW1G,MAAMlE,KAAKkL,aAAe,IAAM,IAE1D,CAED,gBAAIA,GACF,MAAoC,eAA7BlL,KAAKkI,QAAQjB,WACrB,CAED,gBAAIuD,GAEF,OAAOxK,KAAKkL,aACRlL,KAAKgJ,YAAYmC,WACjBnL,KAAKgJ,YAAYoC,SACtB,CAED,UAAIH,GACF,OAAOjL,KAAKkI,QAAQlB,SN5jBjB,SAASsF,OAAOC,EAAGC,GACxB,OAASD,EAAIC,EAAKA,GAAKA,CACzB,CM2jBQF,CAAOtM,KAAKuK,eAAgBvK,KAAKkE,OACjClE,KAAKuK,cACV,CAED,YAAIkC,GAEF,OAAsB,IAAfzM,KAAKkE,MAAc,EAAIlE,KAAKiL,OAASjL,KAAKkE,KAClD,CAaD,eAAIuF,GACF,OAAOzJ,KAAKsH,aACb,CAED,eAAYmC,CAAYvJ,GAClBF,KAAKsH,gBAAkBpH,IACzBF,KAAKsH,cAAgBpH,EACrBF,KAAK6K,kBAER,CAED,aAAIpC,GACF,OAAOzI,KAAKuH,WACb,CAED,aAAYkB,CAAUvI,GAChBF,KAAKuH,cAAgBrH,IACvBF,KAAKuH,YAAcrH,EACnBF,KAAK6K,kBAER,CAED,YAAInC,GACF,OAAO1I,KAAKwH,UACb,CAED,YAAYkB,CAASxI,GACfF,KAAKwH,aAAetH,IACtBF,KAAKwH,WAAatH,EAClBF,KAAK6K,kBAER,CAED,YAAI6B,GACF,MAA4B,WAArB1M,KAAKyJ,WACb,CAED,aAAIkD,GACF,IAAIA,EAAY,QAOhB,OANI3M,KAAKyI,YAAWkE,GAAa,kBAC7B3M,KAAK0I,WAAUiE,GAAa,iBAC5B3M,KAAKyJ,cAAakD,GAAa,oBACV,WAArB3M,KAAKyJ,cAA0BkD,GAAa,iBAGzCA,CACR,CAEO,eAAA9B,GACN7K,KAAK+K,mBAEL/K,KAAKgJ,YAAY2D,UACf,GAAG3M,KAAKgJ,YAAY2D,aAAa3M,KAAK2M,YAAYC,MACrD,CAEO,gBAAA7B,GACN/K,KAAKgJ,YAAY2D,UAAY3M,KAAKgJ,YAAY2D,UAC3CE,QAAQ,gBAAiB,IACzBD,MACJ"}
package/dist/lenis.mjs CHANGED
@@ -1,2 +1,2 @@
1
- function clamp(t,i,e){return Math.max(t,Math.min(i,e))}class Animate{constructor(){this.isRunning=!1,this.value=0,this.from=0,this.to=0,this.duration=0,this.currentTime=0}advance(t){var i;if(!this.isRunning)return;let e=!1;if(this.duration&&this.easing){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}else this.lerp?(this.value=function damp(t,i,e,s){return function lerp(t,i,e){return(1-e)*t+e*i}(t,i,1-Math.exp(-e*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0)):(this.value=this.to,e=!0);e&&this.stop(),null===(i=this.onUpdate)||void 0===i||i.call(this,this.value,e)}stop(){this.isRunning=!1}fromTo(t,i,{lerp:e,duration:s,easing:o,onStart:n,onUpdate:l}){this.from=this.value=t,this.to=i,this.lerp=e,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,null==n||n(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:i,autoResize:e=!0,debounce:s=250}={}){this.width=0,this.height=0,this.scrollWidth=0,this.scrollHeight=0,this.resize=()=>{this.onWrapperResize(),this.onContentResize()},this.onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):this.wrapper instanceof HTMLElement&&(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)},this.onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):this.wrapper instanceof HTMLElement&&(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)},this.wrapper=t,this.content=i,e&&(this.debouncedResize=function debounce(t,i){let e;return function(){let s=arguments,o=this;clearTimeout(e),e=setTimeout((function(){t.apply(o,s)}),i)}}(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(){var t,i;null===(t=this.wrapperResizeObserver)||void 0===t||t.disconnect(),null===(i=this.contentResizeObserver)||void 0===i||i.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...i){let e=this.events[t]||[];for(let t=0,s=e.length;t<s;t++)e[t](...i)}on(t,i){var e;return(null===(e=this.events[t])||void 0===e?void 0:e.push(i))||(this.events[t]=[i]),()=>{var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}}off(t,i){var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}destroy(){this.events={}}}const t=100/6;class VirtualScroll{constructor(i,{wheelMultiplier:e=1,touchMultiplier:s=1}){this.lastDelta={x:0,y:0},this.windowWidth=0,this.windowHeight=0,this.onTouchStart=t=>{const{clientX:i,clientY:e}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=i,this.touchStart.y=e,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})},this.onTouchMove=t=>{var i,e,s,o;const{clientX:n,clientY:l}=t.targetTouches?t.targetTouches[0]:t,r=-(n-(null!==(e=null===(i=this.touchStart)||void 0===i?void 0:i.x)&&void 0!==e?e:0))*this.touchMultiplier,h=-(l-(null!==(o=null===(s=this.touchStart)||void 0===s?void 0:s.y)&&void 0!==o?o:0))*this.touchMultiplier;this.touchStart.x=n,this.touchStart.y=l,this.lastDelta={x:r,y:h},this.emitter.emit("scroll",{deltaX:r,deltaY:h,event:t})},this.onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})},this.onWheel=i=>{let{deltaX:e,deltaY:s,deltaMode:o}=i;e*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,e*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:e,deltaY:s,event:i})},this.onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight},this.element=i,this.wheelMultiplier=e,this.touchMultiplier=s,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,i){return this.emitter.on(t,i)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd)}}class Lenis{constructor({wrapper:t=window,content:i=document.documentElement,wheelEventsTarget:e=t,eventsTarget:s=e,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=.1,infinite:d=!1,orientation:u="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f=!1}={}){this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.userData={},this.lastVelocity=0,this.velocity=0,this.direction=0,this.onPointerDown=t=>{1===t.button&&this.reset()},this.onVirtualScroll=t=>{if("function"==typeof this.options.virtualScroll&&!1===this.options.virtualScroll(t))return;const{deltaX:i,deltaY:e,event:s}=t;if(this.emitter.emit("virtual-scroll",{deltaX:i,deltaY:e,event:s}),s.ctrlKey)return;const o=s.type.includes("touch"),n=s.type.includes("wheel");this.isTouching="touchstart"===s.type||"touchmove"===s.type;if(this.options.syncTouch&&o&&"touchstart"===s.type&&!this.isStopped&&!this.isLocked)return void this.reset();const l=0===i&&0===e,r="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===i;if(l||r)return;let h=s.composedPath();h=h.slice(0,h.indexOf(this.rootElement));const a=this.options.prevent;if(h.find((t=>{var i,e,s,l,r;return t instanceof Element&&("function"==typeof a&&(null==a?void 0:a(t))||(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent"))||o&&(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent-touch"))||n&&(null===(s=t.hasAttribute)||void 0===s?void 0:s.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped")))})))return;if(this.isStopped||this.isLocked)return void s.preventDefault();if(!(this.options.syncTouch&&o||this.options.smoothWheel&&n))return this.isScrolling="native",void this.animate.stop();s.preventDefault();let c=e;"both"===this.options.gestureOrientation?c=Math.abs(e)>Math.abs(i)?e:i:"horizontal"===this.options.gestureOrientation&&(c=i);const d=o&&this.options.syncTouch,u=o&&"touchend"===s.type&&Math.abs(c)>5;u&&(c=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+c,Object.assign({programmatic:!1},d?{lerp:u?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="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.6-dev.0",t&&t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:i,wheelEventsTarget:e,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:p,orientation:u,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:i,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.options.wrapper.addEventListener("pointerdown",this.onPointerDown,!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.options.wrapper.removeEventListener("pointerdown",this.onPointerDown,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.cleanUpClassName()}on(t,i){return this.emitter.on(t,i)}off(t,i){return this.emitter.off(t,i)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.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 i=t-(this.time||t);this.time=t,this.animate.advance(.001*i)}scrollTo(t,{offset:i=0,immediate:e=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:l=this.options.lerp,onStart:r,onComplete:h,force:a=!1,programmatic:c=!0,userData:d={}}={}){if(!this.isStopped&&!this.isLocked||a){if("string"==typeof t&&["top","left","start"].includes(t))t=0;else if("string"==typeof t&&["bottom","right","end"].includes(t))t=this.limit;else{let e;if("string"==typeof t?e=document.querySelector(t):t instanceof HTMLElement&&(null==t?void 0:t.nodeType)&&(e=t),e){if(this.options.wrapper!==window){const t=this.rootElement.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=e.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t&&(t+=i,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),t!==this.targetScroll)){if(this.userData=d,e)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),this.preventNextNativeScrollEvent(),this.emit(),null==h||h(this),void(this.userData={});c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:l,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==r||r(this)},onUpdate:(t,i)=>{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),i||this.emit(),i&&(this.reset(),this.emit(),null==h||h(this),this.userData={},this.preventNextNativeScrollEvent())}})}}}preventNextNativeScrollEvent(){this.__preventNextNativeScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextNativeScrollEvent}))}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,i){return(t%i+i)%i}(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};
1
+ function clamp(t,i,e){return Math.max(t,Math.min(i,e))}class Animate{constructor(){this.isRunning=!1,this.value=0,this.from=0,this.to=0,this.duration=0,this.currentTime=0}advance(t){var i;if(!this.isRunning)return;let e=!1;if(this.duration&&this.easing){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}else this.lerp?(this.value=function damp(t,i,e,s){return function lerp(t,i,e){return(1-e)*t+e*i}(t,i,1-Math.exp(-e*s))}(this.value,this.to,60*this.lerp,t),Math.round(this.value)===this.to&&(this.value=this.to,e=!0)):(this.value=this.to,e=!0);e&&this.stop(),null===(i=this.onUpdate)||void 0===i||i.call(this,this.value,e)}stop(){this.isRunning=!1}fromTo(t,i,{lerp:e,duration:s,easing:o,onStart:n,onUpdate:l}){this.from=this.value=t,this.to=i,this.lerp=e,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,null==n||n(),this.onUpdate=l}}class Dimensions{constructor({wrapper:t,content:i,autoResize:e=!0,debounce:s=250}={}){this.width=0,this.height=0,this.scrollWidth=0,this.scrollHeight=0,this.resize=()=>{this.onWrapperResize(),this.onContentResize()},this.onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):this.wrapper instanceof HTMLElement&&(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)},this.onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):this.wrapper instanceof HTMLElement&&(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)},this.wrapper=t,this.content=i,e&&(this.debouncedResize=function debounce(t,i){let e;return function(){let s=arguments,o=this;clearTimeout(e),e=setTimeout((function(){t.apply(o,s)}),i)}}(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(){var t,i;null===(t=this.wrapperResizeObserver)||void 0===t||t.disconnect(),null===(i=this.contentResizeObserver)||void 0===i||i.disconnect(),window.removeEventListener("resize",this.debouncedResize,!1)}get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...i){let e=this.events[t]||[];for(let t=0,s=e.length;t<s;t++)e[t](...i)}on(t,i){var e;return(null===(e=this.events[t])||void 0===e?void 0:e.push(i))||(this.events[t]=[i]),()=>{var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}}off(t,i){var e;this.events[t]=null===(e=this.events[t])||void 0===e?void 0:e.filter((t=>i!==t))}destroy(){this.events={}}}const t=100/6;class VirtualScroll{constructor(i,{wheelMultiplier:e=1,touchMultiplier:s=1}){this.lastDelta={x:0,y:0},this.windowWidth=0,this.windowHeight=0,this.onTouchStart=t=>{const{clientX:i,clientY:e}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=i,this.touchStart.y=e,this.lastDelta={x:0,y:0},this.emitter.emit("scroll",{deltaX:0,deltaY:0,event:t})},this.onTouchMove=t=>{var i,e,s,o;const{clientX:n,clientY:l}=t.targetTouches?t.targetTouches[0]:t,r=-(n-(null!==(e=null===(i=this.touchStart)||void 0===i?void 0:i.x)&&void 0!==e?e:0))*this.touchMultiplier,h=-(l-(null!==(o=null===(s=this.touchStart)||void 0===s?void 0:s.y)&&void 0!==o?o:0))*this.touchMultiplier;this.touchStart.x=n,this.touchStart.y=l,this.lastDelta={x:r,y:h},this.emitter.emit("scroll",{deltaX:r,deltaY:h,event:t})},this.onTouchEnd=t=>{this.emitter.emit("scroll",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})},this.onWheel=i=>{let{deltaX:e,deltaY:s,deltaMode:o}=i;e*=1===o?t:2===o?this.windowWidth:1,s*=1===o?t:2===o?this.windowHeight:1,e*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit("scroll",{deltaX:e,deltaY:s,event:i})},this.onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight},this.element=i,this.wheelMultiplier=e,this.touchMultiplier=s,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,i){return this.emitter.on(t,i)}destroy(){this.emitter.destroy(),window.removeEventListener("resize",this.onWindowResize,!1),this.element.removeEventListener("wheel",this.onWheel),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd)}}class Lenis{constructor({wrapper:t=window,content:i=document.documentElement,wheelEventsTarget:e=t,eventsTarget:s=e,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:l=.075,touchInertiaMultiplier:r=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=.1,infinite:d=!1,orientation:u="vertical",gestureOrientation:p="vertical",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f=!1}={}){this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.userData={},this.lastVelocity=0,this.velocity=0,this.direction=0,this.onPointerDown=t=>{1===t.button&&this.reset()},this.onVirtualScroll=t=>{if("function"==typeof this.options.virtualScroll&&!1===this.options.virtualScroll(t))return;const{deltaX:i,deltaY:e,event:s}=t;if(this.emitter.emit("virtual-scroll",{deltaX:i,deltaY:e,event:s}),s.ctrlKey)return;const o=s.type.includes("touch"),n=s.type.includes("wheel");this.isTouching="touchstart"===s.type||"touchmove"===s.type;if(this.options.syncTouch&&o&&"touchstart"===s.type&&!this.isStopped&&!this.isLocked)return void this.reset();const l=0===i&&0===e,r="vertical"===this.options.gestureOrientation&&0===e||"horizontal"===this.options.gestureOrientation&&0===i;if(l||r)return;let h=s.composedPath();h=h.slice(0,h.indexOf(this.rootElement));const a=this.options.prevent;if(h.find((t=>{var i,e,s,l,r;return t instanceof Element&&("function"==typeof a&&(null==a?void 0:a(t))||(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,"data-lenis-prevent"))||o&&(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,"data-lenis-prevent-touch"))||n&&(null===(s=t.hasAttribute)||void 0===s?void 0:s.call(t,"data-lenis-prevent-wheel"))||(null===(l=t.classList)||void 0===l?void 0:l.contains("lenis"))&&!(null===(r=t.classList)||void 0===r?void 0:r.contains("lenis-stopped")))})))return;if(this.isStopped||this.isLocked)return void s.preventDefault();if(!(this.options.syncTouch&&o||this.options.smoothWheel&&n))return this.isScrolling="native",void this.animate.stop();s.preventDefault();let c=e;"both"===this.options.gestureOrientation?c=Math.abs(e)>Math.abs(i)?e:i:"horizontal"===this.options.gestureOrientation&&(c=i);const d=o&&this.options.syncTouch,u=o&&"touchend"===s.type&&Math.abs(c)>5;u&&(c=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+c,Object.assign({programmatic:!1},d?{lerp:u?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="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.6",t&&t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:i,wheelEventsTarget:e,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:l,touchInertiaMultiplier:r,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:p,orientation:u,touchMultiplier:m,wheelMultiplier:v,autoResize:g,prevent:w,virtualScroll:S,__experimental__naiveDimensions:f},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:i,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.options.wrapper.addEventListener("pointerdown",this.onPointerDown,!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.options.wrapper.removeEventListener("pointerdown",this.onPointerDown,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.cleanUpClassName()}on(t,i){return this.emitter.on(t,i)}off(t,i){return this.emitter.off(t,i)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit("scroll",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.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 i=t-(this.time||t);this.time=t,this.animate.advance(.001*i)}scrollTo(t,{offset:i=0,immediate:e=!1,lock:s=!1,duration:o=this.options.duration,easing:n=this.options.easing,lerp:l=this.options.lerp,onStart:r,onComplete:h,force:a=!1,programmatic:c=!0,userData:d={}}={}){if(!this.isStopped&&!this.isLocked||a){if("string"==typeof t&&["top","left","start"].includes(t))t=0;else if("string"==typeof t&&["bottom","right","end"].includes(t))t=this.limit;else{let e;if("string"==typeof t?e=document.querySelector(t):t instanceof HTMLElement&&(null==t?void 0:t.nodeType)&&(e=t),e){if(this.options.wrapper!==window){const t=this.rootElement.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=e.getBoundingClientRect();t=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if("number"==typeof t&&(t+=i,t=Math.round(t),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):t=clamp(0,t,this.limit),t!==this.targetScroll)){if(this.userData=d,e)return this.animatedScroll=this.targetScroll=t,this.setScroll(this.scroll),this.reset(),this.preventNextNativeScrollEvent(),this.emit(),null==h||h(this),void(this.userData={});c||(this.targetScroll=t),this.animate.fromTo(this.animatedScroll,t,{duration:o,easing:n,lerp:l,onStart:()=>{s&&(this.isLocked=!0),this.isScrolling="smooth",null==r||r(this)},onUpdate:(t,i)=>{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),i||this.emit(),i&&(this.reset(),this.emit(),null==h||h(this),this.userData={},this.preventNextNativeScrollEvent())}})}}}preventNextNativeScrollEvent(){this.__preventNextNativeScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextNativeScrollEvent}))}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,i){return(t%i+i)%i}(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};
2
2
  //# sourceMappingURL=lenis.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"lenis.mjs","sources":["../src/maths.js","../../src/animate.ts","../../src/dimensions.ts","../src/debounce.js","../../src/emitter.ts","../../src/virtual-scroll.ts","../../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 isRunning: boolean = false\r\n value: number = 0\r\n from: number = 0\r\n to: number = 0\r\n lerp?: number\r\n duration?: number = 0\r\n easing?: Function\r\n currentTime: number = 0\r\n onUpdate?: Function\r\n\r\n // Advance the animation by the given delta time\r\n advance(deltaTime: number) {\r\n if (!this.isRunning) return\r\n\r\n let completed = false\r\n\r\n if (this.duration && this.easing) {\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 } else 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 // If no easing or lerp, just jump to the end value\r\n this.value = this.to\r\n completed = true\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: number,\r\n to: number,\r\n {\r\n lerp,\r\n duration,\r\n easing,\r\n onStart,\r\n onUpdate,\r\n }: {\r\n lerp?: number\r\n duration?: number\r\n easing?: Function\r\n onStart?: Function\r\n onUpdate?: Function\r\n }\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\ntype DimensionsOptions = {\r\n wrapper: Window | HTMLElement\r\n content: HTMLElement\r\n autoResize?: boolean\r\n debounce?: number\r\n}\r\n\r\nexport class Dimensions {\r\n wrapper: Window | HTMLElement\r\n content: HTMLElement\r\n width: number = 0\r\n height: number = 0\r\n scrollWidth: number = 0\r\n scrollHeight: number = 0\r\n debouncedResize?: Function\r\n wrapperResizeObserver?: ResizeObserver\r\n contentResizeObserver?: ResizeObserver\r\n\r\n // @ts-ignore\r\n constructor({\r\n wrapper,\r\n content,\r\n autoResize = true,\r\n debounce: debounceValue = 250,\r\n }: DimensionsOptions = {}) {\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(\r\n 'resize',\r\n this.debouncedResize as EventListener,\r\n false\r\n )\r\n } else {\r\n this.wrapperResizeObserver = new ResizeObserver(\r\n this.debouncedResize as ResizeObserverCallback\r\n )\r\n this.wrapperResizeObserver.observe(this.wrapper as HTMLElement)\r\n }\r\n\r\n this.contentResizeObserver = new ResizeObserver(\r\n this.debouncedResize as ResizeObserverCallback\r\n )\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(\r\n 'resize',\r\n this.debouncedResize as EventListener,\r\n false\r\n )\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 if (this.wrapper instanceof HTMLElement) {\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 if (this.wrapper instanceof HTMLElement) {\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 x: number\r\n y: number\r\n } {\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 events: Record<string, Function[]>\r\n\r\n constructor() {\r\n this.events = {}\r\n }\r\n\r\n emit(event: string, ...args: any[]) {\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: string, callback: Function) {\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(callback) || (this.events[event] = [callback])\r\n\r\n // Return an unsubscribe function\r\n return () => {\r\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\r\n }\r\n }\r\n\r\n off(event: string, callback: Function) {\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 element: HTMLElement | Window\r\n wheelMultiplier: number\r\n touchMultiplier: number\r\n touchStart: {\r\n x: number | null\r\n y: number | null\r\n }\r\n emitter: Emitter\r\n lastDelta: {\r\n x: number\r\n y: number\r\n } = {\r\n x: 0,\r\n y: 0,\r\n }\r\n windowWidth: number = 0\r\n windowHeight: number = 0\r\n\r\n constructor(\r\n element: HTMLElement | Window,\r\n { wheelMultiplier = 1, touchMultiplier = 1 }\r\n ) {\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 as EventListener, {\r\n passive: false,\r\n })\r\n this.element.addEventListener(\r\n 'touchstart',\r\n this.onTouchStart as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n this.element.addEventListener(\r\n 'touchmove',\r\n this.onTouchMove as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n this.element.addEventListener(\r\n 'touchend',\r\n this.onTouchEnd as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n }\r\n\r\n // Add an event listener for the given event and callback\r\n on(event: string, callback: Function) {\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 as EventListener)\r\n this.element.removeEventListener(\r\n 'touchstart',\r\n this.onTouchStart as EventListener\r\n )\r\n this.element.removeEventListener(\r\n 'touchmove',\r\n this.onTouchMove as EventListener\r\n )\r\n this.element.removeEventListener(\r\n 'touchend',\r\n this.onTouchEnd as EventListener\r\n )\r\n }\r\n\r\n // Event handler for 'touchstart' event\r\n onTouchStart = (event: TouchEvent) => {\r\n // @ts-expect-error\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: TouchEvent) => {\r\n // @ts-expect-error\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 ?? 0)) * this.touchMultiplier\r\n const deltaY = -(clientY - (this.touchStart?.y ?? 0)) * 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: TouchEvent) => {\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: WheelEvent) => {\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 Overwrite<T, R> = Omit<T, keyof R> & R\r\n\r\ntype EasingFunction = (t: number) => number\r\ntype Orientation = 'vertical' | 'horizontal'\r\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\r\ntype Scrolling = boolean | 'native' | 'smooth'\r\n\r\ntype onVirtualScrollOptions = {\r\n deltaX: number\r\n deltaY: number\r\n event: WheelEvent | TouchEvent\r\n}\r\n\r\nexport type LenisOptions = Partial<{\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: (node: Element) => boolean\r\n virtualScroll: (data: onVirtualScrollOptions) => 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: Scrolling = 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 __preventNextNativeScrollEvent?: boolean\r\n __resetVelocityTimeout?: number\r\n\r\n isTouching?: boolean\r\n time: number\r\n userData: Object = {}\r\n lastVelocity: number = 0\r\n velocity: number = 0\r\n direction: 1 | -1 | 0 = 0\r\n options: Overwrite<\r\n LenisOptions,\r\n {\r\n wrapper: NonNullable<LenisOptions['wrapper']>\r\n }\r\n >\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 = 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,\r\n virtualScroll,\r\n __experimental__naiveDimensions = false,\r\n }: LenisOptions = {}) {\r\n // @ts-expect-error\r\n window.lenisVersion = version\r\n\r\n // if wrapper is html or body, fallback to window\r\n if (\r\n !wrapper ||\r\n wrapper === document.documentElement ||\r\n wrapper === document.body\r\n ) {\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 virtualScroll,\r\n __experimental__naiveDimensions,\r\n } as LenisOptions\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.options.wrapper.addEventListener(\r\n 'pointerdown',\r\n this.onPointerDown as EventListener,\r\n false\r\n )\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 this.options.wrapper.removeEventListener(\r\n 'pointerdown',\r\n this.onPointerDown as EventListener,\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: number) {\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 onPointerDown = (event: PointerEvent | MouseEvent) => {\r\n if (event.button === 1) {\r\n this.reset()\r\n }\r\n }\r\n\r\n private onVirtualScroll = (data: onVirtualScrollOptions) => {\r\n if (\r\n typeof this.options.virtualScroll === 'function' &&\r\n this.options.virtualScroll(data) === false\r\n )\r\n return\r\n\r\n const { deltaX, deltaY, event } = data\r\n\r\n this.emitter.emit('virtual-scroll', { deltaX, deltaY, event })\r\n\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 const prevent = this.options.prevent\r\n\r\n if (\r\n !!composedPath.find(\r\n (node) =>\r\n node instanceof Element &&\r\n ((typeof prevent === 'function' && 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() {\r\n this.emitter.emit('scroll', this)\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(\r\n this.animatedScroll - lastScroll\r\n ) as Lenis['direction']\r\n // this.isSmooth = false\r\n this.isScrolling = 'native'\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 = 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 (\r\n typeof target === 'string' &&\r\n ['top', 'left', 'start'].includes(target)\r\n ) {\r\n target = 0\r\n } else if (\r\n typeof target === 'string' &&\r\n ['bottom', 'right', 'end'].includes(target)\r\n ) {\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 instanceof HTMLElement && 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.rootElement.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 (target === this.targetScroll) return\r\n\r\n this.userData = userData\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 this.preventNextNativeScrollEvent()\r\n this.emit()\r\n onComplete?.(this)\r\n this.userData = {}\r\n return\r\n }\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) as Lenis['direction']\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 this.userData = {}\r\n\r\n // avoid emitting event twice\r\n this.preventNextNativeScrollEvent()\r\n }\r\n },\r\n })\r\n }\r\n\r\n private preventNextNativeScrollEvent() {\r\n this.__preventNextNativeScrollEvent = true\r\n\r\n requestAnimationFrame(() => {\r\n delete this.__preventNextNativeScrollEvent\r\n })\r\n }\r\n\r\n get rootElement() {\r\n return (\r\n this.options.wrapper === window\r\n ? document.documentElement\r\n : this.options.wrapper\r\n ) as HTMLElement\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: Scrolling) {\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 }\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"],"names":["clamp","min","input","max","Math","Animate","constructor","this","isRunning","value","from","to","duration","currentTime","advance","deltaTime","completed","easing","linearProgress","easedProgress","lerp","damp","x","y","lambda","dt","t","exp","round","stop","_a","onUpdate","call","fromTo","onStart","Dimensions","wrapper","content","autoResize","debounce","debounceValue","width","height","scrollWidth","scrollHeight","resize","onWrapperResize","onContentResize","window","innerWidth","innerHeight","HTMLElement","clientWidth","clientHeight","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","_b","removeEventListener","limit","Emitter","events","emit","event","callbacks","i","length","on","push","filter","off","LINE_HEIGHT","VirtualScroll","element","wheelMultiplier","touchMultiplier","lastDelta","windowWidth","windowHeight","onTouchStart","clientX","clientY","targetTouches","touchStart","emitter","deltaX","deltaY","onTouchMove","_d","_c","onTouchEnd","onWheel","deltaMode","onWindowResize","passive","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","prevent","virtualScroll","__experimental__naiveDimensions","__isScrolling","__isStopped","__isLocked","userData","lastVelocity","velocity","direction","onPointerDown","button","reset","onVirtualScroll","data","options","ctrlKey","isTouch","type","includes","isWheel","isTouching","isStopped","isLocked","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","Element","hasAttribute","classList","contains","_e","preventDefault","isScrolling","animate","delta","abs","hasTouchInertia","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__resetVelocityTimeout","__preventNextNativeScrollEvent","lastScroll","animatedScroll","actualScroll","sign","lenisVersion","body","dimensions","updateClassName","time","cleanUpClassName","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","preventNextNativeScrollEvent","requestAnimationFrame","modulo","n","d","progress","isSmooth","className","trim","replace"],"mappings":"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"}
1
+ {"version":3,"file":"lenis.mjs","sources":["../src/maths.js","../../src/animate.ts","../../src/dimensions.ts","../src/debounce.js","../../src/emitter.ts","../../src/virtual-scroll.ts","../../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 isRunning: boolean = false\r\n value: number = 0\r\n from: number = 0\r\n to: number = 0\r\n lerp?: number\r\n duration?: number = 0\r\n easing?: Function\r\n currentTime: number = 0\r\n onUpdate?: Function\r\n\r\n // Advance the animation by the given delta time\r\n advance(deltaTime: number) {\r\n if (!this.isRunning) return\r\n\r\n let completed = false\r\n\r\n if (this.duration && this.easing) {\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 } else 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 // If no easing or lerp, just jump to the end value\r\n this.value = this.to\r\n completed = true\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: number,\r\n to: number,\r\n {\r\n lerp,\r\n duration,\r\n easing,\r\n onStart,\r\n onUpdate,\r\n }: {\r\n lerp?: number\r\n duration?: number\r\n easing?: Function\r\n onStart?: Function\r\n onUpdate?: Function\r\n }\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\ntype DimensionsOptions = {\r\n wrapper: Window | HTMLElement\r\n content: HTMLElement\r\n autoResize?: boolean\r\n debounce?: number\r\n}\r\n\r\nexport class Dimensions {\r\n wrapper: Window | HTMLElement\r\n content: HTMLElement\r\n width: number = 0\r\n height: number = 0\r\n scrollWidth: number = 0\r\n scrollHeight: number = 0\r\n debouncedResize?: Function\r\n wrapperResizeObserver?: ResizeObserver\r\n contentResizeObserver?: ResizeObserver\r\n\r\n // @ts-ignore\r\n constructor({\r\n wrapper,\r\n content,\r\n autoResize = true,\r\n debounce: debounceValue = 250,\r\n }: DimensionsOptions = {}) {\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(\r\n 'resize',\r\n this.debouncedResize as EventListener,\r\n false\r\n )\r\n } else {\r\n this.wrapperResizeObserver = new ResizeObserver(\r\n this.debouncedResize as ResizeObserverCallback\r\n )\r\n this.wrapperResizeObserver.observe(this.wrapper as HTMLElement)\r\n }\r\n\r\n this.contentResizeObserver = new ResizeObserver(\r\n this.debouncedResize as ResizeObserverCallback\r\n )\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(\r\n 'resize',\r\n this.debouncedResize as EventListener,\r\n false\r\n )\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 if (this.wrapper instanceof HTMLElement) {\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 if (this.wrapper instanceof HTMLElement) {\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 x: number\r\n y: number\r\n } {\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 events: Record<string, Function[]>\r\n\r\n constructor() {\r\n this.events = {}\r\n }\r\n\r\n emit(event: string, ...args: any[]) {\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: string, callback: Function) {\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(callback) || (this.events[event] = [callback])\r\n\r\n // Return an unsubscribe function\r\n return () => {\r\n this.events[event] = this.events[event]?.filter((i) => callback !== i)\r\n }\r\n }\r\n\r\n off(event: string, callback: Function) {\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 element: HTMLElement | Window\r\n wheelMultiplier: number\r\n touchMultiplier: number\r\n touchStart: {\r\n x: number | null\r\n y: number | null\r\n }\r\n emitter: Emitter\r\n lastDelta: {\r\n x: number\r\n y: number\r\n } = {\r\n x: 0,\r\n y: 0,\r\n }\r\n windowWidth: number = 0\r\n windowHeight: number = 0\r\n\r\n constructor(\r\n element: HTMLElement | Window,\r\n { wheelMultiplier = 1, touchMultiplier = 1 }\r\n ) {\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 as EventListener, {\r\n passive: false,\r\n })\r\n this.element.addEventListener(\r\n 'touchstart',\r\n this.onTouchStart as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n this.element.addEventListener(\r\n 'touchmove',\r\n this.onTouchMove as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n this.element.addEventListener(\r\n 'touchend',\r\n this.onTouchEnd as EventListener,\r\n {\r\n passive: false,\r\n }\r\n )\r\n }\r\n\r\n // Add an event listener for the given event and callback\r\n on(event: string, callback: Function) {\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 as EventListener)\r\n this.element.removeEventListener(\r\n 'touchstart',\r\n this.onTouchStart as EventListener\r\n )\r\n this.element.removeEventListener(\r\n 'touchmove',\r\n this.onTouchMove as EventListener\r\n )\r\n this.element.removeEventListener(\r\n 'touchend',\r\n this.onTouchEnd as EventListener\r\n )\r\n }\r\n\r\n // Event handler for 'touchstart' event\r\n onTouchStart = (event: TouchEvent) => {\r\n // @ts-expect-error\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: TouchEvent) => {\r\n // @ts-expect-error\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 ?? 0)) * this.touchMultiplier\r\n const deltaY = -(clientY - (this.touchStart?.y ?? 0)) * 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: TouchEvent) => {\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: WheelEvent) => {\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 Overwrite<T, R> = Omit<T, keyof R> & R\r\n\r\ntype EasingFunction = (t: number) => number\r\ntype Orientation = 'vertical' | 'horizontal'\r\ntype GestureOrientation = 'vertical' | 'horizontal' | 'both'\r\ntype Scrolling = boolean | 'native' | 'smooth'\r\n\r\ntype onVirtualScrollOptions = {\r\n deltaX: number\r\n deltaY: number\r\n event: WheelEvent | TouchEvent\r\n}\r\n\r\nexport type LenisOptions = Partial<{\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: (node: Element) => boolean\r\n virtualScroll: (data: onVirtualScrollOptions) => 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: Scrolling = 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 __preventNextNativeScrollEvent?: boolean\r\n __resetVelocityTimeout?: number\r\n\r\n isTouching?: boolean\r\n time: number\r\n userData: Object = {}\r\n lastVelocity: number = 0\r\n velocity: number = 0\r\n direction: 1 | -1 | 0 = 0\r\n options: Overwrite<\r\n LenisOptions,\r\n {\r\n wrapper: NonNullable<LenisOptions['wrapper']>\r\n }\r\n >\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 = 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,\r\n virtualScroll,\r\n __experimental__naiveDimensions = false,\r\n }: LenisOptions = {}) {\r\n // @ts-expect-error\r\n window.lenisVersion = version\r\n\r\n // if wrapper is html or body, fallback to window\r\n if (\r\n !wrapper ||\r\n wrapper === document.documentElement ||\r\n wrapper === document.body\r\n ) {\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 virtualScroll,\r\n __experimental__naiveDimensions,\r\n } as LenisOptions\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.options.wrapper.addEventListener(\r\n 'pointerdown',\r\n this.onPointerDown as EventListener,\r\n false\r\n )\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 this.options.wrapper.removeEventListener(\r\n 'pointerdown',\r\n this.onPointerDown as EventListener,\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: number) {\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 onPointerDown = (event: PointerEvent | MouseEvent) => {\r\n if (event.button === 1) {\r\n this.reset()\r\n }\r\n }\r\n\r\n private onVirtualScroll = (data: onVirtualScrollOptions) => {\r\n if (\r\n typeof this.options.virtualScroll === 'function' &&\r\n this.options.virtualScroll(data) === false\r\n )\r\n return\r\n\r\n const { deltaX, deltaY, event } = data\r\n\r\n this.emitter.emit('virtual-scroll', { deltaX, deltaY, event })\r\n\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 const prevent = this.options.prevent\r\n\r\n if (\r\n !!composedPath.find(\r\n (node) =>\r\n node instanceof Element &&\r\n ((typeof prevent === 'function' && 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() {\r\n this.emitter.emit('scroll', this)\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(\r\n this.animatedScroll - lastScroll\r\n ) as Lenis['direction']\r\n // this.isSmooth = false\r\n this.isScrolling = 'native'\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 = 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 (\r\n typeof target === 'string' &&\r\n ['top', 'left', 'start'].includes(target)\r\n ) {\r\n target = 0\r\n } else if (\r\n typeof target === 'string' &&\r\n ['bottom', 'right', 'end'].includes(target)\r\n ) {\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 instanceof HTMLElement && 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.rootElement.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 (target === this.targetScroll) return\r\n\r\n this.userData = userData\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 this.preventNextNativeScrollEvent()\r\n this.emit()\r\n onComplete?.(this)\r\n this.userData = {}\r\n return\r\n }\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) as Lenis['direction']\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 this.userData = {}\r\n\r\n // avoid emitting event twice\r\n this.preventNextNativeScrollEvent()\r\n }\r\n },\r\n })\r\n }\r\n\r\n private preventNextNativeScrollEvent() {\r\n this.__preventNextNativeScrollEvent = true\r\n\r\n requestAnimationFrame(() => {\r\n delete this.__preventNextNativeScrollEvent\r\n })\r\n }\r\n\r\n get rootElement() {\r\n return (\r\n this.options.wrapper === window\r\n ? document.documentElement\r\n : this.options.wrapper\r\n ) as HTMLElement\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: Scrolling) {\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 }\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"],"names":["clamp","min","input","max","Math","Animate","constructor","this","isRunning","value","from","to","duration","currentTime","advance","deltaTime","completed","easing","linearProgress","easedProgress","lerp","damp","x","y","lambda","dt","t","exp","round","stop","_a","onUpdate","call","fromTo","onStart","Dimensions","wrapper","content","autoResize","debounce","debounceValue","width","height","scrollWidth","scrollHeight","resize","onWrapperResize","onContentResize","window","innerWidth","innerHeight","HTMLElement","clientWidth","clientHeight","debouncedResize","callback","delay","timer","args","arguments","context","clearTimeout","setTimeout","apply","addEventListener","wrapperResizeObserver","ResizeObserver","observe","contentResizeObserver","destroy","disconnect","_b","removeEventListener","limit","Emitter","events","emit","event","callbacks","i","length","on","push","filter","off","LINE_HEIGHT","VirtualScroll","element","wheelMultiplier","touchMultiplier","lastDelta","windowWidth","windowHeight","onTouchStart","clientX","clientY","targetTouches","touchStart","emitter","deltaX","deltaY","onTouchMove","_d","_c","onTouchEnd","onWheel","deltaMode","onWindowResize","passive","Lenis","document","documentElement","wheelEventsTarget","eventsTarget","smoothWheel","syncTouch","syncTouchLerp","touchInertiaMultiplier","pow","infinite","orientation","gestureOrientation","prevent","virtualScroll","__experimental__naiveDimensions","__isScrolling","__isStopped","__isLocked","userData","lastVelocity","velocity","direction","onPointerDown","button","reset","onVirtualScroll","data","options","ctrlKey","isTouch","type","includes","isWheel","isTouching","isStopped","isLocked","isClick","isUnknownGesture","composedPath","slice","indexOf","rootElement","find","node","Element","hasAttribute","classList","contains","_e","preventDefault","isScrolling","animate","delta","abs","hasTouchInertia","scrollTo","targetScroll","Object","assign","programmatic","onNativeScroll","__resetVelocityTimeout","__preventNextNativeScrollEvent","lastScroll","animatedScroll","actualScroll","sign","lenisVersion","body","dimensions","updateClassName","time","cleanUpClassName","setScroll","scroll","isHorizontal","scrollLeft","scrollTop","start","raf","target","offset","immediate","lock","onComplete","force","querySelector","nodeType","wrapperRect","getBoundingClientRect","left","top","rect","preventNextNativeScrollEvent","requestAnimationFrame","modulo","n","d","progress","isSmooth","className","trim","replace"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lenis",
3
- "version": "1.1.6-dev.0",
3
+ "version": "1.1.6",
4
4
  "author": "darkroom.engineering",
5
5
  "license": "MIT",
6
6
  "repository": {