lenis 1.0.45-dev.0 → 1.0.45-dev.1
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.
- package/LICENSE +8 -8
- package/README.md +277 -277
- package/dist/lenis-react.d.ts +7 -5
- package/dist/lenis-react.mjs +1 -1
- package/dist/lenis-react.mjs.map +1 -1
- package/dist/lenis.d.ts +4 -3
- package/dist/lenis.js +306 -306
- package/dist/lenis.js.map +1 -1
- package/dist/lenis.min.js +1 -1
- package/dist/lenis.min.js.map +1 -1
- package/dist/lenis.mjs +1 -1
- package/dist/lenis.mjs.map +1 -1
- package/package.json +93 -93
package/dist/lenis.js
CHANGED
|
@@ -37,323 +37,323 @@
|
|
|
37
37
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
var version = "1.0.45-dev.
|
|
40
|
+
var version = "1.0.45-dev.1";
|
|
41
41
|
|
|
42
|
-
// Clamp a value between a minimum and maximum value
|
|
43
|
-
function clamp(min, input, max) {
|
|
44
|
-
return Math.max(min, Math.min(input, max))
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Linearly interpolate between two values using an amount (0 <= t <= 1)
|
|
48
|
-
function lerp(x, y, t) {
|
|
49
|
-
return (1 - t) * x + t * y
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
|
|
53
|
-
function damp(x, y, lambda, dt) {
|
|
54
|
-
return lerp(x, y, 1 - Math.exp(-lambda * dt))
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor
|
|
58
|
-
// https://anguscroll.com/just/just-modulo
|
|
59
|
-
function modulo(n, d) {
|
|
60
|
-
return ((n % d) + d) % d
|
|
42
|
+
// Clamp a value between a minimum and maximum value
|
|
43
|
+
function clamp(min, input, max) {
|
|
44
|
+
return Math.max(min, Math.min(input, max))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Linearly interpolate between two values using an amount (0 <= t <= 1)
|
|
48
|
+
function lerp(x, y, t) {
|
|
49
|
+
return (1 - t) * x + t * y
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
|
|
53
|
+
function damp(x, y, lambda, dt) {
|
|
54
|
+
return lerp(x, y, 1 - Math.exp(-lambda * dt))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor
|
|
58
|
+
// https://anguscroll.com/just/just-modulo
|
|
59
|
+
function modulo(n, d) {
|
|
60
|
+
return ((n % d) + d) % d
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
// Animate class to handle value animations with lerping or easing
|
|
64
|
-
class Animate {
|
|
65
|
-
// Advance the animation by the given delta time
|
|
66
|
-
advance(deltaTime) {
|
|
67
|
-
if (!this.isRunning) return
|
|
68
|
-
|
|
69
|
-
let completed = false;
|
|
70
|
-
|
|
71
|
-
if (this.lerp) {
|
|
72
|
-
this.value = damp(this.value, this.to, this.lerp * 60, deltaTime);
|
|
73
|
-
if (Math.round(this.value) === this.to) {
|
|
74
|
-
this.value = this.to;
|
|
75
|
-
completed = true;
|
|
76
|
-
}
|
|
77
|
-
} else {
|
|
78
|
-
this.currentTime += deltaTime;
|
|
79
|
-
const linearProgress = clamp(0, this.currentTime / this.duration, 1);
|
|
80
|
-
|
|
81
|
-
completed = linearProgress >= 1;
|
|
82
|
-
const easedProgress = completed ? 1 : this.easing(linearProgress);
|
|
83
|
-
this.value = this.from + (this.to - this.from) * easedProgress;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Call the onUpdate callback with the current value and completed status
|
|
87
|
-
this.onUpdate?.(this.value, completed);
|
|
88
|
-
|
|
89
|
-
if (completed) {
|
|
90
|
-
this.stop();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Stop the animation
|
|
95
|
-
stop() {
|
|
96
|
-
this.isRunning = false;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Set up the animation from a starting value to an ending value
|
|
100
|
-
// with optional parameters for lerping, duration, easing, and onUpdate callback
|
|
101
|
-
fromTo(
|
|
102
|
-
from,
|
|
103
|
-
to,
|
|
104
|
-
{ lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }
|
|
105
|
-
) {
|
|
106
|
-
this.from = this.value = from;
|
|
107
|
-
this.to = to;
|
|
108
|
-
this.lerp = lerp;
|
|
109
|
-
this.duration = duration;
|
|
110
|
-
this.easing = easing;
|
|
111
|
-
this.currentTime = 0;
|
|
112
|
-
this.isRunning = true;
|
|
113
|
-
|
|
114
|
-
onStart?.();
|
|
115
|
-
this.onUpdate = onUpdate;
|
|
116
|
-
}
|
|
63
|
+
// Animate class to handle value animations with lerping or easing
|
|
64
|
+
class Animate {
|
|
65
|
+
// Advance the animation by the given delta time
|
|
66
|
+
advance(deltaTime) {
|
|
67
|
+
if (!this.isRunning) return
|
|
68
|
+
|
|
69
|
+
let completed = false;
|
|
70
|
+
|
|
71
|
+
if (this.lerp) {
|
|
72
|
+
this.value = damp(this.value, this.to, this.lerp * 60, deltaTime);
|
|
73
|
+
if (Math.round(this.value) === this.to) {
|
|
74
|
+
this.value = this.to;
|
|
75
|
+
completed = true;
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
this.currentTime += deltaTime;
|
|
79
|
+
const linearProgress = clamp(0, this.currentTime / this.duration, 1);
|
|
80
|
+
|
|
81
|
+
completed = linearProgress >= 1;
|
|
82
|
+
const easedProgress = completed ? 1 : this.easing(linearProgress);
|
|
83
|
+
this.value = this.from + (this.to - this.from) * easedProgress;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Call the onUpdate callback with the current value and completed status
|
|
87
|
+
this.onUpdate?.(this.value, completed);
|
|
88
|
+
|
|
89
|
+
if (completed) {
|
|
90
|
+
this.stop();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Stop the animation
|
|
95
|
+
stop() {
|
|
96
|
+
this.isRunning = false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Set up the animation from a starting value to an ending value
|
|
100
|
+
// with optional parameters for lerping, duration, easing, and onUpdate callback
|
|
101
|
+
fromTo(
|
|
102
|
+
from,
|
|
103
|
+
to,
|
|
104
|
+
{ lerp = 0.1, duration = 1, easing = (t) => t, onStart, onUpdate }
|
|
105
|
+
) {
|
|
106
|
+
this.from = this.value = from;
|
|
107
|
+
this.to = to;
|
|
108
|
+
this.lerp = lerp;
|
|
109
|
+
this.duration = duration;
|
|
110
|
+
this.easing = easing;
|
|
111
|
+
this.currentTime = 0;
|
|
112
|
+
this.isRunning = true;
|
|
113
|
+
|
|
114
|
+
onStart?.();
|
|
115
|
+
this.onUpdate = onUpdate;
|
|
116
|
+
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
function debounce(callback, delay) {
|
|
120
|
-
let timer;
|
|
121
|
-
return function () {
|
|
122
|
-
let args = arguments;
|
|
123
|
-
let context = this;
|
|
124
|
-
clearTimeout(timer);
|
|
125
|
-
timer = setTimeout(function () {
|
|
126
|
-
callback.apply(context, args);
|
|
127
|
-
}, delay);
|
|
128
|
-
}
|
|
119
|
+
function debounce(callback, delay) {
|
|
120
|
+
let timer;
|
|
121
|
+
return function () {
|
|
122
|
+
let args = arguments;
|
|
123
|
+
let context = this;
|
|
124
|
+
clearTimeout(timer);
|
|
125
|
+
timer = setTimeout(function () {
|
|
126
|
+
callback.apply(context, args);
|
|
127
|
+
}, delay);
|
|
128
|
+
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
class Dimensions {
|
|
132
|
-
constructor({
|
|
133
|
-
wrapper,
|
|
134
|
-
content,
|
|
135
|
-
autoResize = true,
|
|
136
|
-
debounce: debounceValue = 250,
|
|
137
|
-
} = {}) {
|
|
138
|
-
this.wrapper = wrapper;
|
|
139
|
-
this.content = content;
|
|
140
|
-
|
|
141
|
-
if (autoResize) {
|
|
142
|
-
this.debouncedResize = debounce(this.resize, debounceValue);
|
|
143
|
-
|
|
144
|
-
if (this.wrapper === window) {
|
|
145
|
-
window.addEventListener('resize', this.debouncedResize, false);
|
|
146
|
-
} else {
|
|
147
|
-
this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize);
|
|
148
|
-
this.wrapperResizeObserver.observe(this.wrapper);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
this.contentResizeObserver = new ResizeObserver(this.debouncedResize);
|
|
152
|
-
this.contentResizeObserver.observe(this.content);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
this.resize();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
destroy() {
|
|
159
|
-
this.wrapperResizeObserver?.disconnect();
|
|
160
|
-
this.contentResizeObserver?.disconnect();
|
|
161
|
-
window.removeEventListener('resize', this.debouncedResize, false);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
resize = () => {
|
|
165
|
-
this.onWrapperResize();
|
|
166
|
-
this.onContentResize();
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
onWrapperResize = () => {
|
|
170
|
-
if (this.wrapper === window) {
|
|
171
|
-
this.width = window.innerWidth;
|
|
172
|
-
this.height = window.innerHeight;
|
|
173
|
-
} else {
|
|
174
|
-
this.width = this.wrapper.clientWidth;
|
|
175
|
-
this.height = this.wrapper.clientHeight;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
onContentResize = () => {
|
|
180
|
-
if (this.wrapper === window) {
|
|
181
|
-
this.scrollHeight = this.content.scrollHeight;
|
|
182
|
-
this.scrollWidth = this.content.scrollWidth;
|
|
183
|
-
} else {
|
|
184
|
-
this.scrollHeight = this.wrapper.scrollHeight;
|
|
185
|
-
this.scrollWidth = this.wrapper.scrollWidth;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
get limit() {
|
|
190
|
-
return {
|
|
191
|
-
x: this.scrollWidth - this.width,
|
|
192
|
-
y: this.scrollHeight - this.height,
|
|
193
|
-
}
|
|
194
|
-
}
|
|
131
|
+
class Dimensions {
|
|
132
|
+
constructor({
|
|
133
|
+
wrapper,
|
|
134
|
+
content,
|
|
135
|
+
autoResize = true,
|
|
136
|
+
debounce: debounceValue = 250,
|
|
137
|
+
} = {}) {
|
|
138
|
+
this.wrapper = wrapper;
|
|
139
|
+
this.content = content;
|
|
140
|
+
|
|
141
|
+
if (autoResize) {
|
|
142
|
+
this.debouncedResize = debounce(this.resize, debounceValue);
|
|
143
|
+
|
|
144
|
+
if (this.wrapper === window) {
|
|
145
|
+
window.addEventListener('resize', this.debouncedResize, false);
|
|
146
|
+
} else {
|
|
147
|
+
this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize);
|
|
148
|
+
this.wrapperResizeObserver.observe(this.wrapper);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this.contentResizeObserver = new ResizeObserver(this.debouncedResize);
|
|
152
|
+
this.contentResizeObserver.observe(this.content);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.resize();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
destroy() {
|
|
159
|
+
this.wrapperResizeObserver?.disconnect();
|
|
160
|
+
this.contentResizeObserver?.disconnect();
|
|
161
|
+
window.removeEventListener('resize', this.debouncedResize, false);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
resize = () => {
|
|
165
|
+
this.onWrapperResize();
|
|
166
|
+
this.onContentResize();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
onWrapperResize = () => {
|
|
170
|
+
if (this.wrapper === window) {
|
|
171
|
+
this.width = window.innerWidth;
|
|
172
|
+
this.height = window.innerHeight;
|
|
173
|
+
} else {
|
|
174
|
+
this.width = this.wrapper.clientWidth;
|
|
175
|
+
this.height = this.wrapper.clientHeight;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
onContentResize = () => {
|
|
180
|
+
if (this.wrapper === window) {
|
|
181
|
+
this.scrollHeight = this.content.scrollHeight;
|
|
182
|
+
this.scrollWidth = this.content.scrollWidth;
|
|
183
|
+
} else {
|
|
184
|
+
this.scrollHeight = this.wrapper.scrollHeight;
|
|
185
|
+
this.scrollWidth = this.wrapper.scrollWidth;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
get limit() {
|
|
190
|
+
return {
|
|
191
|
+
x: this.scrollWidth - this.width,
|
|
192
|
+
y: this.scrollHeight - this.height,
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
class Emitter {
|
|
198
|
-
constructor() {
|
|
199
|
-
this.events = {};
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
emit(event, ...args) {
|
|
203
|
-
let callbacks = this.events[event] || [];
|
|
204
|
-
for (let i = 0, length = callbacks.length; i < length; i++) {
|
|
205
|
-
callbacks[i](...args);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
on(event, cb) {
|
|
210
|
-
// Add the callback to the event's callback list, or create a new list with the callback
|
|
211
|
-
this.events[event]?.push(cb) || (this.events[event] = [cb]);
|
|
212
|
-
|
|
213
|
-
// Return an unsubscribe function
|
|
214
|
-
return () => {
|
|
215
|
-
this.events[event] = this.events[event]?.filter((i) => cb !== i);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
off(event, callback) {
|
|
220
|
-
this.events[event] = this.events[event]?.filter((i) => callback !== i);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
destroy() {
|
|
224
|
-
this.events = {};
|
|
225
|
-
}
|
|
197
|
+
class Emitter {
|
|
198
|
+
constructor() {
|
|
199
|
+
this.events = {};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
emit(event, ...args) {
|
|
203
|
+
let callbacks = this.events[event] || [];
|
|
204
|
+
for (let i = 0, length = callbacks.length; i < length; i++) {
|
|
205
|
+
callbacks[i](...args);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
on(event, cb) {
|
|
210
|
+
// Add the callback to the event's callback list, or create a new list with the callback
|
|
211
|
+
this.events[event]?.push(cb) || (this.events[event] = [cb]);
|
|
212
|
+
|
|
213
|
+
// Return an unsubscribe function
|
|
214
|
+
return () => {
|
|
215
|
+
this.events[event] = this.events[event]?.filter((i) => cb !== i);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
off(event, callback) {
|
|
220
|
+
this.events[event] = this.events[event]?.filter((i) => callback !== i);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
destroy() {
|
|
224
|
+
this.events = {};
|
|
225
|
+
}
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
const LINE_HEIGHT = 100 / 6;
|
|
229
|
-
|
|
230
|
-
class VirtualScroll {
|
|
231
|
-
constructor(element, { wheelMultiplier = 1, touchMultiplier = 1 }) {
|
|
232
|
-
this.element = element;
|
|
233
|
-
this.wheelMultiplier = wheelMultiplier;
|
|
234
|
-
this.touchMultiplier = touchMultiplier;
|
|
235
|
-
|
|
236
|
-
this.touchStart = {
|
|
237
|
-
x: null,
|
|
238
|
-
y: null,
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
this.emitter = new Emitter();
|
|
242
|
-
window.addEventListener('resize', this.onWindowResize, false);
|
|
243
|
-
this.onWindowResize();
|
|
244
|
-
|
|
245
|
-
this.element.addEventListener('wheel', this.onWheel, { passive: false });
|
|
246
|
-
this.element.addEventListener('touchstart', this.onTouchStart, {
|
|
247
|
-
passive: false,
|
|
248
|
-
});
|
|
249
|
-
this.element.addEventListener('touchmove', this.onTouchMove, {
|
|
250
|
-
passive: false,
|
|
251
|
-
});
|
|
252
|
-
this.element.addEventListener('touchend', this.onTouchEnd, {
|
|
253
|
-
passive: false,
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Add an event listener for the given event and callback
|
|
258
|
-
on(event, callback) {
|
|
259
|
-
return this.emitter.on(event, callback)
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Remove all event listeners and clean up
|
|
263
|
-
destroy() {
|
|
264
|
-
this.emitter.destroy();
|
|
265
|
-
|
|
266
|
-
window.removeEventListener('resize', this.onWindowResize, false);
|
|
267
|
-
|
|
268
|
-
this.element.removeEventListener('wheel', this.onWheel, {
|
|
269
|
-
passive: false,
|
|
270
|
-
});
|
|
271
|
-
this.element.removeEventListener('touchstart', this.onTouchStart, {
|
|
272
|
-
passive: false,
|
|
273
|
-
});
|
|
274
|
-
this.element.removeEventListener('touchmove', this.onTouchMove, {
|
|
275
|
-
passive: false,
|
|
276
|
-
});
|
|
277
|
-
this.element.removeEventListener('touchend', this.onTouchEnd, {
|
|
278
|
-
passive: false,
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Event handler for 'touchstart' event
|
|
283
|
-
onTouchStart = (event) => {
|
|
284
|
-
const { clientX, clientY } = event.targetTouches
|
|
285
|
-
? event.targetTouches[0]
|
|
286
|
-
: event;
|
|
287
|
-
|
|
288
|
-
this.touchStart.x = clientX;
|
|
289
|
-
this.touchStart.y = clientY;
|
|
290
|
-
|
|
291
|
-
this.lastDelta = {
|
|
292
|
-
x: 0,
|
|
293
|
-
y: 0,
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
this.emitter.emit('scroll', {
|
|
297
|
-
deltaX: 0,
|
|
298
|
-
deltaY: 0,
|
|
299
|
-
event,
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Event handler for 'touchmove' event
|
|
304
|
-
onTouchMove = (event) => {
|
|
305
|
-
const { clientX, clientY } = event.targetTouches
|
|
306
|
-
? event.targetTouches[0]
|
|
307
|
-
: event;
|
|
308
|
-
|
|
309
|
-
const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier;
|
|
310
|
-
const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier;
|
|
311
|
-
|
|
312
|
-
this.touchStart.x = clientX;
|
|
313
|
-
this.touchStart.y = clientY;
|
|
314
|
-
|
|
315
|
-
this.lastDelta = {
|
|
316
|
-
x: deltaX,
|
|
317
|
-
y: deltaY,
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
this.emitter.emit('scroll', {
|
|
321
|
-
deltaX,
|
|
322
|
-
deltaY,
|
|
323
|
-
event,
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
onTouchEnd = (event) => {
|
|
328
|
-
this.emitter.emit('scroll', {
|
|
329
|
-
deltaX: this.lastDelta.x,
|
|
330
|
-
deltaY: this.lastDelta.y,
|
|
331
|
-
event,
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Event handler for 'wheel' event
|
|
336
|
-
onWheel = (event) => {
|
|
337
|
-
let { deltaX, deltaY, deltaMode } = event;
|
|
338
|
-
|
|
339
|
-
const multiplierX =
|
|
340
|
-
deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowWidth : 1;
|
|
341
|
-
const multiplierY =
|
|
342
|
-
deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowHeight : 1;
|
|
343
|
-
|
|
344
|
-
deltaX *= multiplierX;
|
|
345
|
-
deltaY *= multiplierY;
|
|
346
|
-
|
|
347
|
-
deltaX *= this.wheelMultiplier;
|
|
348
|
-
deltaY *= this.wheelMultiplier;
|
|
349
|
-
|
|
350
|
-
this.emitter.emit('scroll', { deltaX, deltaY, event });
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
onWindowResize = () => {
|
|
354
|
-
this.windowWidth = window.innerWidth;
|
|
355
|
-
this.windowHeight = window.innerHeight;
|
|
356
|
-
}
|
|
228
|
+
const LINE_HEIGHT = 100 / 6;
|
|
229
|
+
|
|
230
|
+
class VirtualScroll {
|
|
231
|
+
constructor(element, { wheelMultiplier = 1, touchMultiplier = 1 }) {
|
|
232
|
+
this.element = element;
|
|
233
|
+
this.wheelMultiplier = wheelMultiplier;
|
|
234
|
+
this.touchMultiplier = touchMultiplier;
|
|
235
|
+
|
|
236
|
+
this.touchStart = {
|
|
237
|
+
x: null,
|
|
238
|
+
y: null,
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
this.emitter = new Emitter();
|
|
242
|
+
window.addEventListener('resize', this.onWindowResize, false);
|
|
243
|
+
this.onWindowResize();
|
|
244
|
+
|
|
245
|
+
this.element.addEventListener('wheel', this.onWheel, { passive: false });
|
|
246
|
+
this.element.addEventListener('touchstart', this.onTouchStart, {
|
|
247
|
+
passive: false,
|
|
248
|
+
});
|
|
249
|
+
this.element.addEventListener('touchmove', this.onTouchMove, {
|
|
250
|
+
passive: false,
|
|
251
|
+
});
|
|
252
|
+
this.element.addEventListener('touchend', this.onTouchEnd, {
|
|
253
|
+
passive: false,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Add an event listener for the given event and callback
|
|
258
|
+
on(event, callback) {
|
|
259
|
+
return this.emitter.on(event, callback)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Remove all event listeners and clean up
|
|
263
|
+
destroy() {
|
|
264
|
+
this.emitter.destroy();
|
|
265
|
+
|
|
266
|
+
window.removeEventListener('resize', this.onWindowResize, false);
|
|
267
|
+
|
|
268
|
+
this.element.removeEventListener('wheel', this.onWheel, {
|
|
269
|
+
passive: false,
|
|
270
|
+
});
|
|
271
|
+
this.element.removeEventListener('touchstart', this.onTouchStart, {
|
|
272
|
+
passive: false,
|
|
273
|
+
});
|
|
274
|
+
this.element.removeEventListener('touchmove', this.onTouchMove, {
|
|
275
|
+
passive: false,
|
|
276
|
+
});
|
|
277
|
+
this.element.removeEventListener('touchend', this.onTouchEnd, {
|
|
278
|
+
passive: false,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Event handler for 'touchstart' event
|
|
283
|
+
onTouchStart = (event) => {
|
|
284
|
+
const { clientX, clientY } = event.targetTouches
|
|
285
|
+
? event.targetTouches[0]
|
|
286
|
+
: event;
|
|
287
|
+
|
|
288
|
+
this.touchStart.x = clientX;
|
|
289
|
+
this.touchStart.y = clientY;
|
|
290
|
+
|
|
291
|
+
this.lastDelta = {
|
|
292
|
+
x: 0,
|
|
293
|
+
y: 0,
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
this.emitter.emit('scroll', {
|
|
297
|
+
deltaX: 0,
|
|
298
|
+
deltaY: 0,
|
|
299
|
+
event,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Event handler for 'touchmove' event
|
|
304
|
+
onTouchMove = (event) => {
|
|
305
|
+
const { clientX, clientY } = event.targetTouches
|
|
306
|
+
? event.targetTouches[0]
|
|
307
|
+
: event;
|
|
308
|
+
|
|
309
|
+
const deltaX = -(clientX - this.touchStart.x) * this.touchMultiplier;
|
|
310
|
+
const deltaY = -(clientY - this.touchStart.y) * this.touchMultiplier;
|
|
311
|
+
|
|
312
|
+
this.touchStart.x = clientX;
|
|
313
|
+
this.touchStart.y = clientY;
|
|
314
|
+
|
|
315
|
+
this.lastDelta = {
|
|
316
|
+
x: deltaX,
|
|
317
|
+
y: deltaY,
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
this.emitter.emit('scroll', {
|
|
321
|
+
deltaX,
|
|
322
|
+
deltaY,
|
|
323
|
+
event,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
onTouchEnd = (event) => {
|
|
328
|
+
this.emitter.emit('scroll', {
|
|
329
|
+
deltaX: this.lastDelta.x,
|
|
330
|
+
deltaY: this.lastDelta.y,
|
|
331
|
+
event,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Event handler for 'wheel' event
|
|
336
|
+
onWheel = (event) => {
|
|
337
|
+
let { deltaX, deltaY, deltaMode } = event;
|
|
338
|
+
|
|
339
|
+
const multiplierX =
|
|
340
|
+
deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowWidth : 1;
|
|
341
|
+
const multiplierY =
|
|
342
|
+
deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? this.windowHeight : 1;
|
|
343
|
+
|
|
344
|
+
deltaX *= multiplierX;
|
|
345
|
+
deltaY *= multiplierY;
|
|
346
|
+
|
|
347
|
+
deltaX *= this.wheelMultiplier;
|
|
348
|
+
deltaY *= this.wheelMultiplier;
|
|
349
|
+
|
|
350
|
+
this.emitter.emit('scroll', { deltaX, deltaY, event });
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
onWindowResize = () => {
|
|
354
|
+
this.windowWidth = window.innerWidth;
|
|
355
|
+
this.windowHeight = window.innerHeight;
|
|
356
|
+
}
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
var Lenis = /** @class */ (function () {
|