lenis 1.1.5 → 1.1.6-dev.0

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.
@@ -1,247 +1,266 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
- typeof define === 'function' && define.amd ? define(factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Lenis = factory());
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
+ typeof define === 'function' && define.amd ? define(factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Lenis = factory());
5
5
  })(this, (function () { 'use strict';
6
6
 
7
- function removeParentSticky(element) {
8
- const position = getComputedStyle(element).position;
9
- const isSticky = position === 'sticky';
10
- if (isSticky) {
11
- element.style.setProperty('position', 'static');
12
- element.dataset.sticky = 'true';
13
- }
14
- if (element.offsetParent) {
15
- removeParentSticky(element.offsetParent);
16
- }
17
- }
18
- function addParentSticky(element) {
19
- var _a;
20
- if (((_a = element === null || element === void 0 ? void 0 : element.dataset) === null || _a === void 0 ? void 0 : _a.sticky) === 'true') {
21
- element.style.removeProperty('position');
22
- delete element.dataset.sticky;
23
- }
24
- if (element.offsetParent) {
25
- addParentSticky(element.offsetParent);
26
- }
27
- }
28
- function offsetTop(element, accumulator = 0) {
29
- const top = accumulator + element.offsetTop;
30
- if (element.offsetParent) {
31
- return offsetTop(element.offsetParent, top);
32
- }
33
- return top;
34
- }
35
- function offsetLeft(element, accumulator = 0) {
36
- const left = accumulator + element.offsetLeft;
37
- if (element.offsetParent) {
38
- return offsetLeft(element.offsetParent, left);
39
- }
40
- return left;
41
- }
42
- function scrollTop(element, accumulator = 0) {
43
- const top = accumulator + element.scrollTop;
44
- if (element.offsetParent) {
45
- return scrollTop(element.offsetParent, top);
46
- }
47
- return top + window.scrollY;
48
- }
49
- function scrollLeft(element, accumulator = 0) {
50
- const left = accumulator + element.scrollLeft;
51
- if (element.offsetParent) {
52
- return scrollLeft(element.offsetParent, left);
53
- }
54
- return left + window.scrollX;
55
- }
56
- class SnapElement {
57
- constructor(element, { align = ['start'], ignoreSticky = true, ignoreTransform = false, } = {}) {
58
- this.rect = {};
59
- this.onWrapperResize = () => {
60
- let top, left;
61
- if (this.options.ignoreSticky)
62
- removeParentSticky(this.element);
63
- if (this.options.ignoreTransform) {
64
- top = offsetTop(this.element);
65
- left = offsetLeft(this.element);
66
- }
67
- else {
68
- const rect = this.element.getBoundingClientRect();
69
- top = rect.top + scrollTop(this.element);
70
- left = rect.left + scrollLeft(this.element);
71
- }
72
- if (this.options.ignoreSticky)
73
- addParentSticky(this.element);
74
- this.setRect({ top, left });
75
- };
76
- this.onResize = ([entry]) => {
77
- const width = entry.borderBoxSize[0].inlineSize;
78
- const height = entry.borderBoxSize[0].blockSize;
79
- this.setRect({ width, height });
80
- };
81
- this.element = element;
82
- this.options = { align, ignoreSticky, ignoreTransform };
83
- this.align = [align].flat();
84
- this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize);
85
- this.wrapperResizeObserver.observe(document.body);
86
- this.onWrapperResize();
87
- this.resizeObserver = new ResizeObserver(this.onResize);
88
- this.resizeObserver.observe(this.element);
89
- this.setRect({
90
- width: this.element.offsetWidth,
91
- height: this.element.offsetHeight,
92
- });
93
- }
94
- destroy() {
95
- this.wrapperResizeObserver.disconnect();
96
- this.resizeObserver.disconnect();
97
- }
98
- setRect({ top, left, width, height, element, } = {}) {
99
- top = top !== null && top !== void 0 ? top : this.rect.top;
100
- left = left !== null && left !== void 0 ? left : this.rect.left;
101
- width = width !== null && width !== void 0 ? width : this.rect.width;
102
- height = height !== null && height !== void 0 ? height : this.rect.height;
103
- element = element !== null && element !== void 0 ? element : this.rect.element;
104
- if (top === this.rect.top &&
105
- left === this.rect.left &&
106
- width === this.rect.width &&
107
- height === this.rect.height &&
108
- element === this.rect.element)
109
- return;
110
- this.rect.top = top;
111
- this.rect.y = top;
112
- this.rect.width = width;
113
- this.rect.height = height;
114
- this.rect.left = left;
115
- this.rect.x = left;
116
- this.rect.bottom = top + height;
117
- this.rect.right = left + width;
118
- }
119
- }
7
+ function debounce(callback, delay) {
8
+ let timer;
9
+ return function () {
10
+ let args = arguments;
11
+ let context = this;
12
+ clearTimeout(timer);
13
+ timer = setTimeout(function () {
14
+ callback.apply(context, args);
15
+ }, delay);
16
+ }
17
+ }
120
18
 
121
- let index = 0;
122
- function uid() {
123
- return index++;
124
- }
19
+ function removeParentSticky(element) {
20
+ const position = getComputedStyle(element).position;
21
+ const isSticky = position === 'sticky';
22
+ if (isSticky) {
23
+ element.style.setProperty('position', 'static');
24
+ element.dataset.sticky = 'true';
25
+ }
26
+ if (element.offsetParent) {
27
+ removeParentSticky(element.offsetParent);
28
+ }
29
+ }
30
+ function addParentSticky(element) {
31
+ var _a;
32
+ if (((_a = element === null || element === void 0 ? void 0 : element.dataset) === null || _a === void 0 ? void 0 : _a.sticky) === 'true') {
33
+ element.style.removeProperty('position');
34
+ delete element.dataset.sticky;
35
+ }
36
+ if (element.offsetParent) {
37
+ addParentSticky(element.offsetParent);
38
+ }
39
+ }
40
+ function offsetTop(element, accumulator = 0) {
41
+ const top = accumulator + element.offsetTop;
42
+ if (element.offsetParent) {
43
+ return offsetTop(element.offsetParent, top);
44
+ }
45
+ return top;
46
+ }
47
+ function offsetLeft(element, accumulator = 0) {
48
+ const left = accumulator + element.offsetLeft;
49
+ if (element.offsetParent) {
50
+ return offsetLeft(element.offsetParent, left);
51
+ }
52
+ return left;
53
+ }
54
+ function scrollTop(element, accumulator = 0) {
55
+ const top = accumulator + element.scrollTop;
56
+ if (element.offsetParent) {
57
+ return scrollTop(element.offsetParent, top);
58
+ }
59
+ return top + window.scrollY;
60
+ }
61
+ function scrollLeft(element, accumulator = 0) {
62
+ const left = accumulator + element.scrollLeft;
63
+ if (element.offsetParent) {
64
+ return scrollLeft(element.offsetParent, left);
65
+ }
66
+ return left + window.scrollX;
67
+ }
68
+ class SnapElement {
69
+ constructor(element, { align = ['start'], ignoreSticky = true, ignoreTransform = false, } = {}) {
70
+ this.rect = {};
71
+ this.onWrapperResize = () => {
72
+ let top, left;
73
+ if (this.options.ignoreSticky)
74
+ removeParentSticky(this.element);
75
+ if (this.options.ignoreTransform) {
76
+ top = offsetTop(this.element);
77
+ left = offsetLeft(this.element);
78
+ }
79
+ else {
80
+ const rect = this.element.getBoundingClientRect();
81
+ top = rect.top + scrollTop(this.element);
82
+ left = rect.left + scrollLeft(this.element);
83
+ }
84
+ if (this.options.ignoreSticky)
85
+ addParentSticky(this.element);
86
+ this.setRect({ top, left });
87
+ };
88
+ this.onResize = ([entry]) => {
89
+ const width = entry.borderBoxSize[0].inlineSize;
90
+ const height = entry.borderBoxSize[0].blockSize;
91
+ this.setRect({ width, height });
92
+ };
93
+ this.element = element;
94
+ this.options = { align, ignoreSticky, ignoreTransform };
95
+ this.align = [align].flat();
96
+ this.wrapperResizeObserver = new ResizeObserver(this.onWrapperResize);
97
+ this.wrapperResizeObserver.observe(document.body);
98
+ this.onWrapperResize();
99
+ this.resizeObserver = new ResizeObserver(this.onResize);
100
+ this.resizeObserver.observe(this.element);
101
+ this.setRect({
102
+ width: this.element.offsetWidth,
103
+ height: this.element.offsetHeight,
104
+ });
105
+ }
106
+ destroy() {
107
+ this.wrapperResizeObserver.disconnect();
108
+ this.resizeObserver.disconnect();
109
+ }
110
+ setRect({ top, left, width, height, element, } = {}) {
111
+ top = top !== null && top !== void 0 ? top : this.rect.top;
112
+ left = left !== null && left !== void 0 ? left : this.rect.left;
113
+ width = width !== null && width !== void 0 ? width : this.rect.width;
114
+ height = height !== null && height !== void 0 ? height : this.rect.height;
115
+ element = element !== null && element !== void 0 ? element : this.rect.element;
116
+ if (top === this.rect.top &&
117
+ left === this.rect.left &&
118
+ width === this.rect.width &&
119
+ height === this.rect.height &&
120
+ element === this.rect.element)
121
+ return;
122
+ this.rect.top = top;
123
+ this.rect.y = top;
124
+ this.rect.width = width;
125
+ this.rect.height = height;
126
+ this.rect.left = left;
127
+ this.rect.x = left;
128
+ this.rect.bottom = top + height;
129
+ this.rect.right = left + width;
130
+ }
131
+ }
125
132
 
126
- class Snap {
127
- constructor(lenis, { type = 'mandatory', lerp, easing, duration, velocityThreshold = 1, onSnapStart, onSnapComplete, } = {}) {
128
- this.isStopped = false;
129
- this.onWindowResize = () => {
130
- this.viewport.width = window.innerWidth;
131
- this.viewport.height = window.innerHeight;
132
- };
133
- this.onScroll = ({ scroll, limit, lastVelocity, velocity, isScrolling, userData, isHorizontal, }) => {
134
- if (this.isStopped)
135
- return;
136
- const isDecelerating = Math.abs(lastVelocity) > Math.abs(velocity);
137
- const isTurningBack = Math.sign(lastVelocity) !== Math.sign(velocity) && velocity !== 0;
138
- if (Math.abs(velocity) < this.options.velocityThreshold &&
139
- isDecelerating &&
140
- !isTurningBack &&
141
- (userData === null || userData === void 0 ? void 0 : userData.initiator) !== 'snap') {
142
- scroll = Math.ceil(scroll);
143
- let snaps = [...this.snaps.values()];
144
- this.elements.forEach(({ rect, align }) => {
145
- let snap;
146
- align.forEach((align) => {
147
- if (align === 'start') {
148
- snap = rect.top;
149
- }
150
- else if (align === 'center') {
151
- snap = isHorizontal
152
- ? rect.left + rect.width / 2 - this.viewport.width / 2
153
- : rect.top + rect.height / 2 - this.viewport.height / 2;
154
- }
155
- else if (align === 'end') {
156
- snap = isHorizontal
157
- ? rect.left + rect.width - this.viewport.width
158
- : rect.top + rect.height - this.viewport.height;
159
- }
160
- if (snap !== undefined) {
161
- snaps.push(Math.ceil(snap));
162
- }
163
- });
164
- });
165
- snaps = snaps.sort((a, b) => Math.abs(a) - Math.abs(b));
166
- let prevSnap = snaps.findLast((snap) => snap <= scroll);
167
- if (prevSnap === undefined)
168
- prevSnap = snaps[0];
169
- const distanceToPrevSnap = Math.abs(scroll - prevSnap);
170
- let nextSnap = snaps.find((snap) => snap >= scroll);
171
- if (nextSnap === undefined)
172
- nextSnap = snaps[snaps.length - 1];
173
- const distanceToNextSnap = Math.abs(scroll - nextSnap);
174
- const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap;
175
- const distance = Math.abs(scroll - snap);
176
- if (this.options.type === 'mandatory' ||
177
- (this.options.type === 'proximity' && distance <= this.viewport.height)) {
178
- this.lenis.scrollTo(snap, {
179
- lerp: this.options.lerp,
180
- easing: this.options.easing,
181
- duration: this.options.duration,
182
- userData: { initiator: 'snap' },
183
- onStart: () => {
184
- var _a, _b;
185
- (_b = (_a = this.options).onSnapStart) === null || _b === void 0 ? void 0 : _b.call(_a, snap);
186
- },
187
- onComplete: () => {
188
- var _a, _b;
189
- (_b = (_a = this.options).onSnapComplete) === null || _b === void 0 ? void 0 : _b.call(_a, snap);
190
- },
191
- });
192
- }
193
- }
194
- };
195
- this.lenis = lenis;
196
- this.options = {
197
- type,
198
- lerp,
199
- easing,
200
- duration,
201
- velocityThreshold,
202
- onSnapStart,
203
- onSnapComplete,
204
- };
205
- this.elements = new Map();
206
- this.snaps = new Map();
207
- this.viewport = {
208
- width: window.innerWidth,
209
- height: window.innerHeight,
210
- };
211
- this.onWindowResize();
212
- window.addEventListener('resize', this.onWindowResize);
213
- this.lenis.on('scroll', this.onScroll);
214
- }
215
- destroy() {
216
- this.lenis.off('scroll', this.onScroll);
217
- window.removeEventListener('resize', this.onWindowResize);
218
- this.elements.forEach((element) => element.destroy());
219
- }
220
- start() {
221
- this.isStopped = false;
222
- }
223
- stop() {
224
- this.isStopped = true;
225
- }
226
- add(value) {
227
- const id = uid();
228
- this.snaps.set(id, value);
229
- return () => this.remove(id);
230
- }
231
- remove(id) {
232
- this.snaps.delete(id);
233
- }
234
- addElement(element, options = {}) {
235
- const id = uid();
236
- this.elements.set(id, new SnapElement(element, options));
237
- return () => this.removeElement(id);
238
- }
239
- removeElement(id) {
240
- this.elements.delete(id);
241
- }
242
- }
133
+ let index = 0;
134
+ function uid() {
135
+ return index++;
136
+ }
243
137
 
244
- return Snap;
138
+ class Snap {
139
+ constructor(lenis, { type = 'mandatory', lerp, easing, duration, velocityThreshold = 1, debounce: debounceDelay = 0, onSnapStart, onSnapComplete, } = {}) {
140
+ this.isStopped = false;
141
+ this.onWindowResize = () => {
142
+ this.viewport.width = window.innerWidth;
143
+ this.viewport.height = window.innerHeight;
144
+ };
145
+ this.onScroll = ({ lastVelocity, velocity, userData, }) => {
146
+ if (this.isStopped)
147
+ return;
148
+ const isDecelerating = Math.abs(lastVelocity) > Math.abs(velocity);
149
+ const isTurningBack = Math.sign(lastVelocity) !== Math.sign(velocity) && velocity !== 0;
150
+ if (Math.abs(velocity) < this.options.velocityThreshold &&
151
+ isDecelerating &&
152
+ !isTurningBack &&
153
+ (userData === null || userData === void 0 ? void 0 : userData.initiator) !== 'snap') {
154
+ this.onSnapDebounced();
155
+ }
156
+ };
157
+ this.onSnap = () => {
158
+ let { scroll, isHorizontal } = this.lenis;
159
+ scroll = Math.ceil(this.lenis.scroll);
160
+ let snaps = [...this.snaps.values()];
161
+ this.elements.forEach(({ rect, align }) => {
162
+ let value;
163
+ align.forEach((align) => {
164
+ if (align === 'start') {
165
+ value = rect.top;
166
+ }
167
+ else if (align === 'center') {
168
+ value = isHorizontal
169
+ ? rect.left + rect.width / 2 - this.viewport.width / 2
170
+ : rect.top + rect.height / 2 - this.viewport.height / 2;
171
+ }
172
+ else if (align === 'end') {
173
+ value = isHorizontal
174
+ ? rect.left + rect.width - this.viewport.width
175
+ : rect.top + rect.height - this.viewport.height;
176
+ }
177
+ if (typeof value === 'number') {
178
+ snaps.push({ value: Math.ceil(value), userData: {} });
179
+ }
180
+ });
181
+ });
182
+ snaps = snaps.sort((a, b) => Math.abs(a.value) - Math.abs(b.value));
183
+ let prevSnap = snaps.findLast(({ value }) => value <= scroll);
184
+ if (prevSnap === undefined)
185
+ prevSnap = snaps[0];
186
+ const distanceToPrevSnap = Math.abs(scroll - prevSnap.value);
187
+ let nextSnap = snaps.find(({ value }) => value >= scroll);
188
+ if (nextSnap === undefined)
189
+ nextSnap = snaps[snaps.length - 1];
190
+ const distanceToNextSnap = Math.abs(scroll - nextSnap.value);
191
+ const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap;
192
+ const distance = Math.abs(scroll - snap.value);
193
+ if (this.options.type === 'mandatory' ||
194
+ (this.options.type === 'proximity' &&
195
+ distance <= this.lenis.dimensions.height)) {
196
+ this.lenis.scrollTo(snap.value, {
197
+ lerp: this.options.lerp,
198
+ easing: this.options.easing,
199
+ duration: this.options.duration,
200
+ userData: { initiator: 'snap' },
201
+ onStart: () => {
202
+ var _a, _b;
203
+ (_b = (_a = this.options).onSnapStart) === null || _b === void 0 ? void 0 : _b.call(_a, snap);
204
+ },
205
+ onComplete: () => {
206
+ var _a, _b;
207
+ (_b = (_a = this.options).onSnapComplete) === null || _b === void 0 ? void 0 : _b.call(_a, snap);
208
+ },
209
+ });
210
+ }
211
+ };
212
+ this.lenis = lenis;
213
+ this.options = {
214
+ type,
215
+ lerp,
216
+ easing,
217
+ duration,
218
+ velocityThreshold,
219
+ debounce: debounceDelay,
220
+ onSnapStart,
221
+ onSnapComplete,
222
+ };
223
+ this.elements = new Map();
224
+ this.snaps = new Map();
225
+ this.viewport = {
226
+ width: window.innerWidth,
227
+ height: window.innerHeight,
228
+ };
229
+ this.onWindowResize();
230
+ window.addEventListener('resize', this.onWindowResize, false);
231
+ this.onSnapDebounced = debounce(this.onSnap, this.options.debounce);
232
+ this.lenis.on('scroll', this.onScroll);
233
+ }
234
+ destroy() {
235
+ this.lenis.off('scroll', this.onScroll);
236
+ window.removeEventListener('resize', this.onWindowResize, false);
237
+ this.elements.forEach((element) => element.destroy());
238
+ }
239
+ start() {
240
+ this.isStopped = false;
241
+ }
242
+ stop() {
243
+ this.isStopped = true;
244
+ }
245
+ add(value, userData = {}) {
246
+ const id = uid();
247
+ this.snaps.set(id, { value, userData });
248
+ return () => this.remove(id);
249
+ }
250
+ remove(id) {
251
+ this.snaps.delete(id);
252
+ }
253
+ addElement(element, options = {}) {
254
+ const id = uid();
255
+ this.elements.set(id, new SnapElement(element, options));
256
+ return () => this.removeElement(id);
257
+ }
258
+ removeElement(id) {
259
+ this.elements.delete(id);
260
+ }
261
+ }
262
+
263
+ return Snap;
245
264
 
246
265
  }));
247
266
  //# sourceMappingURL=lenis-snap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lenis-snap.js","sources":["../src/element.ts","../src/uid.ts","../src/index.ts"],"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 { 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\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 onSnapStart?: (t: number) => number\r\n onSnapComplete?: (t: number) => number\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, number>\r\n viewport: Viewport\r\n isStopped: Boolean = false\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 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 onSnapStart,\r\n onSnapComplete,\r\n }\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)\r\n\r\n this.lenis.on('scroll', this.onScroll)\r\n }\r\n\r\n // debug() {\r\n // const element = document.createElement('div')\r\n // element.style.cssText = `\r\n // position: fixed;\r\n // background: red;\r\n // border-bottom: 1px solid red;\r\n // left: 0;\r\n // right: 0;\r\n // top: 0;\r\n // z-index: 9999;\r\n // `\r\n // document.body.appendChild(element)\r\n // }\r\n\r\n destroy() {\r\n this.lenis.off('scroll', this.onScroll)\r\n window.removeEventListener('resize', this.onWindowResize)\r\n this.elements.forEach((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) {\r\n const id = uid()\r\n\r\n this.snaps.set(id, value)\r\n\r\n return () => this.remove(id)\r\n }\r\n\r\n remove(id: 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 onWindowResize = () => {\r\n this.viewport.width = window.innerWidth\r\n this.viewport.height = window.innerHeight\r\n }\r\n\r\n onScroll = ({\r\n scroll,\r\n limit,\r\n lastVelocity,\r\n velocity,\r\n isScrolling,\r\n userData,\r\n isHorizontal,\r\n }) => {\r\n if (this.isStopped) return\r\n // console.log(scroll, velocity, type)\r\n\r\n // return\r\n const isDecelerating = Math.abs(lastVelocity) > Math.abs(velocity)\r\n const isTurningBack =\r\n Math.sign(lastVelocity) !== Math.sign(velocity) && velocity !== 0\r\n\r\n // console.log({ lastVelocity, velocity, isTurningBack, isDecelerating })\r\n\r\n // console.log('onScroll')\r\n\r\n if (\r\n Math.abs(velocity) < this.options.velocityThreshold &&\r\n // !isTouching &&\r\n isDecelerating &&\r\n !isTurningBack &&\r\n userData?.initiator !== 'snap'\r\n ) {\r\n scroll = Math.ceil(scroll)\r\n\r\n let snaps = [...this.snaps.values()] as number[]\r\n\r\n this.elements.forEach(({ rect, align }) => {\r\n let snap: number | undefined\r\n\r\n align.forEach((align) => {\r\n if (align === 'start') {\r\n snap = rect.top\r\n } else if (align === 'center') {\r\n snap = 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 snap = 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 (snap !== undefined) {\r\n snaps.push(Math.ceil(snap))\r\n }\r\n })\r\n })\r\n\r\n snaps = snaps.sort((a, b) => Math.abs(a) - Math.abs(b))\r\n\r\n let prevSnap = snaps.findLast((snap) => snap <= scroll)\r\n if (prevSnap === undefined) prevSnap = snaps[0]\r\n const distanceToPrevSnap = Math.abs(scroll - prevSnap)\r\n\r\n let nextSnap = snaps.find((snap) => snap >= scroll)\r\n if (nextSnap === undefined) nextSnap = snaps[snaps.length - 1]\r\n const distanceToNextSnap = Math.abs(scroll - nextSnap)\r\n\r\n const snap = distanceToPrevSnap < distanceToNextSnap ? prevSnap : nextSnap\r\n\r\n const distance = Math.abs(scroll - snap)\r\n\r\n if (\r\n this.options.type === 'mandatory' ||\r\n (this.options.type === 'proximity' && distance <= this.viewport.height)\r\n ) {\r\n // this.__isScrolling = true\r\n // this.onSnapStart?.(snap)\r\n\r\n // console.log('scroll to')\r\n\r\n this.lenis.scrollTo(snap, {\r\n lerp: this.options.lerp,\r\n easing: this.options.easing,\r\n duration: this.options.duration,\r\n userData: { initiator: 'snap' },\r\n onStart: () => {\r\n this.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}\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 <= 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,onSnapStart:r,onSnapComplete:h}={}){this.isStopped=!1,this.onWindowResize=()=>{this.viewport.width=window.innerWidth,this.viewport.height=window.innerHeight},this.onScroll=({scroll:t,limit:e,lastVelocity:i,velocity:s,isScrolling:o,userData:n,isHorizontal:r})=>{if(this.isStopped)return;const h=Math.abs(i)>Math.abs(s),l=Math.sign(i)!==Math.sign(s)&&0!==s;if(Math.abs(s)<this.options.velocityThreshold&&h&&!l&&"snap"!==(null==n?void 0:n.initiator)){t=Math.ceil(t);let e=[...this.snaps.values()];this.elements.forEach((({rect:t,align:i})=>{let s;i.forEach((i=>{"start"===i?s=t.top:"center"===i?s=r?t.left+t.width/2-this.viewport.width/2:t.top+t.height/2-this.viewport.height/2:"end"===i&&(s=r?t.left+t.width-this.viewport.width:t.top+t.height-this.viewport.height),void 0!==s&&e.push(Math.ceil(s))}))})),e=e.sort(((t,e)=>Math.abs(t)-Math.abs(e)));let i=e.findLast((e=>e<=t));void 0===i&&(i=e[0]);const s=Math.abs(t-i);let o=e.find((e=>e>=t));void 0===o&&(o=e[e.length-1]);const n=s<Math.abs(t-o)?i:o,h=Math.abs(t-n);("mandatory"===this.options.type||"proximity"===this.options.type&&h<=this.viewport.height)&&this.lenis.scrollTo(n,{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,n)},onComplete:()=>{var t,e;null===(e=(t=this.options).onSnapComplete)||void 0===e||e.call(t,n)}})}},this.lenis=t,this.options={type:e,lerp:i,easing:s,duration:o,velocityThreshold:n,onSnapStart:r,onSnapComplete:h},this.elements=new Map,this.snaps=new Map,this.viewport={width:window.innerWidth,height:window.innerHeight},this.onWindowResize(),window.addEventListener("resize",this.onWindowResize),this.lenis.on("scroll",this.onScroll)}destroy(){this.lenis.off("scroll",this.onScroll),window.removeEventListener("resize",this.onWindowResize),this.elements.forEach((t=>t.destroy()))}start(){this.isStopped=!1}stop(){this.isStopped=!0}add(t){const e=uid();return this.snaps.set(e,t),()=>this.remove(e)}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<=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