vevet 5.0.10 → 5.1.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.
Files changed (156) hide show
  1. package/README.md +18 -16
  2. package/lib/cdn/vevet.iife.min.js +9 -9
  3. package/lib/cjs/base/Module/index.js +2 -1
  4. package/lib/cjs/base/Module/index.js.map +1 -1
  5. package/lib/cjs/components/Canvas/index.js +1 -1
  6. package/lib/cjs/components/CanvasMedia/index.js +1 -1
  7. package/lib/cjs/components/Cursor/index.js +28 -13
  8. package/lib/cjs/components/Cursor/index.js.map +1 -1
  9. package/lib/cjs/components/InView/index.js +1 -1
  10. package/lib/cjs/components/Marquee/index.js +1 -1
  11. package/lib/cjs/components/Pointers/index.js +4 -1
  12. package/lib/cjs/components/Pointers/index.js.map +1 -1
  13. package/lib/cjs/components/Preloader/index.js +1 -1
  14. package/lib/cjs/components/ProgressPreloader/index.js +1 -1
  15. package/lib/cjs/components/Raf/index.js +1 -1
  16. package/lib/cjs/components/ScrollProgress/index.js +1 -1
  17. package/lib/cjs/components/Scrollbar/index.js +2 -1
  18. package/lib/cjs/components/Scrollbar/index.js.map +1 -1
  19. package/lib/cjs/components/Snap/Slide/index.js +1 -0
  20. package/lib/cjs/components/Snap/Slide/index.js.map +1 -1
  21. package/lib/cjs/components/Snap/Swipe/index.js +120 -23
  22. package/lib/cjs/components/Snap/Swipe/index.js.map +1 -1
  23. package/lib/cjs/components/Snap/Track/index.js +12 -1
  24. package/lib/cjs/components/Snap/Track/index.js.map +1 -1
  25. package/lib/cjs/components/Snap/Wheel/index.js +247 -54
  26. package/lib/cjs/components/Snap/Wheel/index.js.map +1 -1
  27. package/lib/cjs/components/Snap/index.js +98 -40
  28. package/lib/cjs/components/Snap/index.js.map +1 -1
  29. package/lib/cjs/components/SplitText/index.js +1 -1
  30. package/lib/cjs/components/Swipe/index.js +97 -47
  31. package/lib/cjs/components/Swipe/index.js.map +1 -1
  32. package/lib/cjs/components/Timeline/index.js +1 -1
  33. package/lib/cjs/internal/mergeWithNoUndefined.js +24 -0
  34. package/lib/cjs/internal/mergeWithNoUndefined.js.map +1 -0
  35. package/lib/cjs/manifest.json +1 -1
  36. package/lib/cjs/utils/common/toPixels.js +3 -0
  37. package/lib/cjs/utils/common/toPixels.js.map +1 -1
  38. package/lib/cjs/utils/listeners/onResize.js +1 -1
  39. package/lib/cjs/utils/listeners/onResize.js.map +1 -1
  40. package/lib/cjs/utils/math/clamp.js +3 -1
  41. package/lib/cjs/utils/math/clamp.js.map +1 -1
  42. package/lib/cjs/utils/math/inRange.js +4 -4
  43. package/lib/esm/base/Module/index.js +2 -1
  44. package/lib/esm/base/Module/index.js.map +1 -1
  45. package/lib/esm/components/Canvas/index.js +1 -1
  46. package/lib/esm/components/CanvasMedia/index.js +1 -1
  47. package/lib/esm/components/Cursor/index.js +28 -13
  48. package/lib/esm/components/Cursor/index.js.map +1 -1
  49. package/lib/esm/components/InView/index.js +1 -1
  50. package/lib/esm/components/Marquee/index.js +1 -1
  51. package/lib/esm/components/Pointers/index.js +4 -1
  52. package/lib/esm/components/Pointers/index.js.map +1 -1
  53. package/lib/esm/components/Preloader/index.js +1 -1
  54. package/lib/esm/components/ProgressPreloader/index.js +1 -1
  55. package/lib/esm/components/Raf/index.js +1 -1
  56. package/lib/esm/components/ScrollProgress/index.js +1 -1
  57. package/lib/esm/components/Scrollbar/index.js +2 -1
  58. package/lib/esm/components/Scrollbar/index.js.map +1 -1
  59. package/lib/esm/components/Snap/Slide/index.js +1 -0
  60. package/lib/esm/components/Snap/Slide/index.js.map +1 -1
  61. package/lib/esm/components/Snap/Swipe/index.js +104 -23
  62. package/lib/esm/components/Snap/Swipe/index.js.map +1 -1
  63. package/lib/esm/components/Snap/Track/index.js +12 -1
  64. package/lib/esm/components/Snap/Track/index.js.map +1 -1
  65. package/lib/esm/components/Snap/Wheel/index.js +224 -55
  66. package/lib/esm/components/Snap/Wheel/index.js.map +1 -1
  67. package/lib/esm/components/Snap/index.js +84 -29
  68. package/lib/esm/components/Snap/index.js.map +1 -1
  69. package/lib/esm/components/SplitText/index.js +1 -1
  70. package/lib/esm/components/Swipe/index.js +93 -43
  71. package/lib/esm/components/Swipe/index.js.map +1 -1
  72. package/lib/esm/components/Timeline/index.js +1 -1
  73. package/lib/esm/internal/mergeWithNoUndefined.js +10 -0
  74. package/lib/esm/internal/mergeWithNoUndefined.js.map +1 -0
  75. package/lib/esm/manifest.json +1 -1
  76. package/lib/esm/utils/common/toPixels.js +3 -0
  77. package/lib/esm/utils/common/toPixels.js.map +1 -1
  78. package/lib/esm/utils/listeners/onResize.js +1 -1
  79. package/lib/esm/utils/listeners/onResize.js.map +1 -1
  80. package/lib/esm/utils/math/clamp.js +3 -1
  81. package/lib/esm/utils/math/clamp.js.map +1 -1
  82. package/lib/esm/utils/math/inRange.js +4 -4
  83. package/lib/types/base/Module/index.d.ts.map +1 -1
  84. package/lib/types/components/Canvas/index.d.ts +1 -1
  85. package/lib/types/components/CanvasMedia/index.d.ts +1 -1
  86. package/lib/types/components/Cursor/index.d.ts +5 -1
  87. package/lib/types/components/Cursor/index.d.ts.map +1 -1
  88. package/lib/types/components/InView/index.d.ts +1 -1
  89. package/lib/types/components/Marquee/index.d.ts +1 -1
  90. package/lib/types/components/Pointers/index.d.ts +1 -1
  91. package/lib/types/components/Pointers/index.d.ts.map +1 -1
  92. package/lib/types/components/Preloader/index.d.ts +1 -1
  93. package/lib/types/components/ProgressPreloader/index.d.ts +1 -1
  94. package/lib/types/components/Raf/index.d.ts +1 -1
  95. package/lib/types/components/ScrollProgress/index.d.ts +1 -1
  96. package/lib/types/components/Scrollbar/index.d.ts +1 -1
  97. package/lib/types/components/Scrollbar/index.d.ts.map +1 -1
  98. package/lib/types/components/Snap/Slide/index.d.ts.map +1 -1
  99. package/lib/types/components/Snap/Swipe/index.d.ts +12 -1
  100. package/lib/types/components/Snap/Swipe/index.d.ts.map +1 -1
  101. package/lib/types/components/Snap/Swipe/types.d.ts +10 -0
  102. package/lib/types/components/Snap/Swipe/types.d.ts.map +1 -1
  103. package/lib/types/components/Snap/Track/index.d.ts +2 -0
  104. package/lib/types/components/Snap/Track/index.d.ts.map +1 -1
  105. package/lib/types/components/Snap/Wheel/index.d.ts +28 -6
  106. package/lib/types/components/Snap/Wheel/index.d.ts.map +1 -1
  107. package/lib/types/components/Snap/Wheel/types.d.ts +9 -3
  108. package/lib/types/components/Snap/Wheel/types.d.ts.map +1 -1
  109. package/lib/types/components/Snap/index.d.ts +12 -8
  110. package/lib/types/components/Snap/index.d.ts.map +1 -1
  111. package/lib/types/components/Snap/types.d.ts +19 -5
  112. package/lib/types/components/Snap/types.d.ts.map +1 -1
  113. package/lib/types/components/SplitText/index.d.ts +1 -1
  114. package/lib/types/components/Swipe/index.d.ts +3 -7
  115. package/lib/types/components/Swipe/index.d.ts.map +1 -1
  116. package/lib/types/components/Swipe/types.d.ts +16 -2
  117. package/lib/types/components/Swipe/types.d.ts.map +1 -1
  118. package/lib/types/components/Timeline/index.d.ts +1 -1
  119. package/lib/types/internal/mergeWithNoUndefined.d.ts +2 -0
  120. package/lib/types/internal/mergeWithNoUndefined.d.ts.map +1 -0
  121. package/lib/types/utils/common/toPixels.d.ts.map +1 -1
  122. package/lib/types/utils/listeners/onResize.d.ts +1 -0
  123. package/lib/types/utils/listeners/onResize.d.ts.map +1 -1
  124. package/lib/types/utils/math/clamp.d.ts.map +1 -1
  125. package/lib/types/utils/math/inRange.d.ts +4 -4
  126. package/package.json +1 -1
  127. package/src/base/Module/index.ts +8 -5
  128. package/src/components/Canvas/index.ts +1 -1
  129. package/src/components/CanvasMedia/index.ts +1 -1
  130. package/src/components/Cursor/index.ts +35 -15
  131. package/src/components/InView/index.ts +1 -1
  132. package/src/components/Marquee/index.ts +1 -1
  133. package/src/components/Pointers/index.ts +5 -1
  134. package/src/components/Preloader/index.ts +1 -1
  135. package/src/components/ProgressPreloader/index.ts +1 -1
  136. package/src/components/Raf/index.ts +1 -1
  137. package/src/components/ScrollProgress/index.ts +1 -1
  138. package/src/components/Scrollbar/index.ts +2 -1
  139. package/src/components/Snap/Slide/index.ts +1 -0
  140. package/src/components/Snap/Swipe/index.ts +138 -25
  141. package/src/components/Snap/Swipe/types.ts +12 -0
  142. package/src/components/Snap/Track/index.ts +15 -1
  143. package/src/components/Snap/Wheel/index.ts +291 -60
  144. package/src/components/Snap/Wheel/types.ts +10 -3
  145. package/src/components/Snap/index.ts +81 -39
  146. package/src/components/Snap/types.ts +24 -5
  147. package/src/components/SplitText/index.ts +1 -1
  148. package/src/components/Swipe/index.ts +123 -55
  149. package/src/components/Swipe/types.ts +20 -2
  150. package/src/components/Timeline/index.ts +1 -1
  151. package/src/internal/mergeWithNoUndefined.ts +20 -0
  152. package/src/manifest.json +1 -1
  153. package/src/utils/common/toPixels.ts +2 -0
  154. package/src/utils/listeners/onResize.ts +2 -1
  155. package/src/utils/math/clamp.ts +4 -1
  156. package/src/utils/math/inRange.ts +4 -4
@@ -1,5 +1,8 @@
1
- import { addEventListener, normalizeWheel } from '@/utils';
1
+ import { addEventListener, clamp, normalizeWheel } from '@/utils';
2
2
  import { Snap } from '..';
3
+ import { initVevet } from '@/global/initVevet';
4
+
5
+ const deltasCount = 6;
3
6
 
4
7
  export class SnapWheel {
5
8
  /** Listeners to destruct */
@@ -11,11 +14,11 @@ export class SnapWheel {
11
14
  /** Debounce wheel end event */
12
15
  protected _debounceEnd?: NodeJS.Timeout;
13
16
 
14
- /** Accummulated wheel value for `followWheel=false` */
15
- protected _accum = 0;
17
+ /** Deltas history */
18
+ protected _deltas: number[] = [];
16
19
 
17
20
  /** Last time wheel event was fired */
18
- protected _lastNoFollowTime = 0;
21
+ protected _lastWheelTime = 0;
19
22
 
20
23
  constructor(protected _snap: Snap) {
21
24
  _snap.on('destroy', () => this._destroy(), { protected: true });
@@ -25,46 +28,53 @@ export class SnapWheel {
25
28
  );
26
29
  }
27
30
 
31
+ /** Destroy wheel listeners */
32
+ protected _destroy() {
33
+ this._destructor();
34
+
35
+ if (this._debounceEnd) {
36
+ clearTimeout(this._debounceEnd);
37
+ }
38
+ }
39
+
28
40
  /** Snap component */
29
41
  protected get snap() {
30
42
  return this._snap;
31
43
  }
32
44
 
45
+ /** Get absolute deltas */
46
+ protected get absDeltas() {
47
+ return this._deltas.map((d) => Math.abs(d));
48
+ }
49
+
50
+ /** Get last wheel time */
51
+ protected get lastWheelTime() {
52
+ return this._lastWheelTime;
53
+ }
54
+
33
55
  /**
34
56
  * Handles wheel events
35
57
  */
36
58
  protected _handleWheel(event: WheelEvent) {
37
59
  const { snap } = this;
60
+ const { props } = snap;
38
61
 
39
- if (!snap.props.wheel) {
62
+ if (!props.wheel) {
40
63
  return;
41
64
  }
42
65
 
43
66
  event.preventDefault();
44
67
 
45
- const { wheelAxis } = snap.props;
46
-
47
- // Start callback
48
- if (!this._hasStarted) {
49
- this._hasStarted = true;
50
- snap.callbacks.emit('wheelStart', undefined);
51
- }
52
-
53
- // Move callback
54
- snap.callbacks.emit('wheel', event);
55
-
56
- // Normalize wheel data
57
- const axis = wheelAxis === 'auto' ? snap.axis : wheelAxis;
68
+ // Get delta
58
69
  const wheelData = normalizeWheel(event);
59
- const wheelDelta = axis === 'x' ? wheelData.pixelX : wheelData.pixelY;
60
- const delta = wheelDelta * snap.props.wheelSpeed;
70
+ const wheelAxis = props.wheelAxis === 'auto' ? snap.axis : props.wheelAxis;
71
+ const delta = wheelAxis === 'x' ? wheelData.pixelX : wheelData.pixelY;
61
72
 
62
- // Update wheel target
63
- if (snap.props.followWheel) {
64
- this._handleFollow(delta);
65
- } else {
66
- this._handleNotFollow(delta);
67
- }
73
+ // Start
74
+ this._handleStart(delta);
75
+
76
+ // Start
77
+ this._handleMove(delta, event);
68
78
 
69
79
  // Debounce End
70
80
  if (this._debounceEnd) {
@@ -72,8 +82,40 @@ export class SnapWheel {
72
82
  }
73
83
 
74
84
  // End callback
75
- if (snap.props.stickOnWheelEnd) {
76
- this._debounceEnd = setTimeout(() => this._handleEnd(), 100);
85
+ this._debounceEnd = setTimeout(() => this._handleEnd(), 200);
86
+ }
87
+
88
+ /** Handle wheel start */
89
+ protected _handleStart(delta: number) {
90
+ if (this._hasStarted || Math.abs(delta) < 2) {
91
+ return;
92
+ }
93
+
94
+ this._hasStarted = true;
95
+
96
+ this.snap.callbacks.emit('wheelStart', undefined);
97
+ }
98
+
99
+ /** Handle wheel move */
100
+ protected _handleMove(delta: number, event: WheelEvent) {
101
+ if (!this._hasStarted) {
102
+ return;
103
+ }
104
+
105
+ const { snap } = this;
106
+ const { props } = snap;
107
+
108
+ // Save delta
109
+ this._addDelta(delta);
110
+
111
+ // Move callback
112
+ snap.callbacks.emit('wheel', event);
113
+
114
+ // Handle wheel logic
115
+ if (props.followWheel) {
116
+ this._handleFollow(delta);
117
+ } else {
118
+ this._handleNoFollow(delta);
77
119
  }
78
120
  }
79
121
 
@@ -85,71 +127,260 @@ export class SnapWheel {
85
127
  snap.cancelTransition();
86
128
 
87
129
  // Update track target
88
- snap.track.iterateTarget(delta);
130
+ snap.track.iterateTarget(delta * snap.props.wheelSpeed);
89
131
  snap.track.clampTarget();
90
132
  }
91
133
 
92
134
  /** Handle `followWheel=false` */
93
- protected _handleNotFollow(delta: number) {
94
- const { snap } = this;
135
+ protected _handleNoFollow(delta: number) {
136
+ // vars
137
+ const { snap, isTouchPad, isGainingDelta } = this;
138
+ const { track, activeSlide, domSize } = snap;
95
139
 
96
- if (Math.abs(delta) < 10) {
140
+ // Detect wheel throttling
141
+ if (this._detectNoFollowThrottle()) {
97
142
  return;
98
143
  }
99
144
 
100
- if (snap.props.wheelThrottle === 'auto' && snap.isTransitioning) {
101
- return;
145
+ // Detect if need to throttle or follow
146
+
147
+ let shouldFollow = false;
148
+ let isThrottled = true;
149
+
150
+ if (!shouldFollow) {
151
+ if (track.isSlideScrolling) {
152
+ if (activeSlide.coord === 0) {
153
+ if (delta > 0) {
154
+ shouldFollow = true;
155
+ }
156
+ } else if (activeSlide.coord === domSize - activeSlide.size) {
157
+ if (delta < 0) {
158
+ shouldFollow = true;
159
+ }
160
+ } else {
161
+ shouldFollow = true;
162
+ isThrottled = false;
163
+ }
164
+ }
102
165
  }
103
166
 
104
- const timeDiff = +new Date() - this._lastNoFollowTime;
167
+ // Throttle
168
+
169
+ if (isThrottled) {
170
+ if (
171
+ !isTouchPad ||
172
+ (isTouchPad && (isGainingDelta || this.absDeltas.length === 1))
173
+ ) {
174
+ const direction = Math.sign(delta);
175
+
176
+ if (shouldFollow) {
177
+ snap.cancelTransition();
178
+
179
+ track.iterateTarget(direction);
180
+ track.clampTarget();
181
+
182
+ if (!isTouchPad) {
183
+ track.current = track.target;
184
+ }
185
+ } else if (direction === 1) {
186
+ if (!snap.props.loop && snap.activeIndex === snap.slides.length - 1) {
187
+ return;
188
+ }
189
+
190
+ this._lastWheelTime = +new Date();
191
+
192
+ snap.next();
193
+ } else {
194
+ if (!snap.props.loop && snap.activeIndex === 0) {
195
+ return;
196
+ }
197
+
198
+ this._lastWheelTime = +new Date();
199
+
200
+ snap.prev();
201
+ }
202
+ }
105
203
 
106
- if (
107
- typeof snap.props.wheelThrottle === 'number' &&
108
- timeDiff < snap.props.wheelThrottle
109
- ) {
110
204
  return;
111
205
  }
112
206
 
113
- this._accum += Math.abs(delta) / 2;
114
- const direction = Math.sign(delta);
207
+ // Follow wheel
115
208
 
116
- if (Math.abs(this._accum) < 100) {
117
- return;
209
+ if (shouldFollow) {
210
+ snap.cancelTransition();
211
+
212
+ const deltaWithSpeed = delta * snap.props.wheelSpeed;
213
+
214
+ const start = Math.min(...activeSlide.magnets);
215
+ const end = Math.max(...activeSlide.magnets);
216
+
217
+ const loopedTarget = track.loopCoord(track.target);
218
+
219
+ const clampedLoopedTarget = clamp(
220
+ loopedTarget + deltaWithSpeed,
221
+ start,
222
+ end,
223
+ );
224
+
225
+ track.target += clampedLoopedTarget - loopedTarget;
226
+ track.clampTarget();
118
227
  }
228
+ }
119
229
 
120
- if (direction === 1) {
121
- if (!snap.next()) {
122
- return;
123
- }
124
- } else if (!snap.prev()) {
125
- return;
230
+ /** Detect if wheel should be throttled */
231
+ protected _detectNoFollowThrottle() {
232
+ const { isTouchPad, snap } = this;
233
+ const { wheelThrottle } = snap.props;
234
+ const timeDiff = +new Date() - this._lastWheelTime;
235
+
236
+ // NUMBER
237
+
238
+ if (typeof wheelThrottle === 'number') {
239
+ return timeDiff < wheelThrottle;
126
240
  }
127
241
 
128
- this._accum = 0;
129
- this._lastNoFollowTime = +new Date();
242
+ // AUTO
243
+
244
+ if (isTouchPad) {
245
+ return this.snap.isTransitioning;
246
+ }
247
+
248
+ const visibleScrollableSlides = snap.scrollableSlides.filter(
249
+ (slide) => slide.isVisible,
250
+ );
251
+
252
+ if (visibleScrollableSlides.length && snap.isTransitioning) {
253
+ return true;
254
+ }
255
+
256
+ if (timeDiff < 500) {
257
+ return true;
258
+ }
259
+
260
+ return false;
130
261
  }
131
262
 
132
263
  /** Handle wheel end */
133
264
  protected _handleEnd() {
265
+ if (!this._hasStarted) {
266
+ return;
267
+ }
268
+
134
269
  const { snap } = this;
135
- const { freemode: isFreemode, followWheel: isFollow } = snap.props;
270
+ const { props, activeSlide, track } = snap;
271
+
272
+ const lastThreeDeltas = this._deltas.slice(-3).reduce((a, b) => a + b, 0);
136
273
 
274
+ // Reset states
275
+
276
+ this._deltas = [];
137
277
  this._hasStarted = false;
138
- this._accum = 0;
139
278
 
140
- if (!isFreemode && isFollow) {
141
- snap.stick();
279
+ // Stick to the nearest magnet
280
+
281
+ if (!props.freemode || props.freemode === 'sticky') {
282
+ if (props.followWheel && props.stickOnWheelEnd) {
283
+ // Classic stick when scrolling stops
284
+
285
+ const slideThreshold =
286
+ Math.abs(props.stickOnWheelEndThreshold) / activeSlide.size;
287
+
288
+ if (
289
+ activeSlide.progress > slideThreshold &&
290
+ !track.isSlideScrolling &&
291
+ lastThreeDeltas > 0
292
+ ) {
293
+ snap.next();
294
+ } else if (
295
+ activeSlide.progress < -slideThreshold &&
296
+ !track.isSlideScrolling &&
297
+ lastThreeDeltas < 0
298
+ ) {
299
+ snap.prev();
300
+ } else {
301
+ snap.stick();
302
+ }
303
+ } else if (!props.followWheel && !snap.isTransitioning) {
304
+ // Stick if something goes wrong when followWheel is disabled
305
+ snap.stick();
306
+ }
142
307
  }
143
308
 
144
309
  snap.callbacks.emit('wheelEnd', undefined);
145
310
  }
146
311
 
147
- /** Destroy wheel listeners */
148
- protected _destroy() {
149
- this._destructor();
312
+ /** Save delta */
313
+ protected _addDelta(delta: number) {
314
+ if (this._deltas.length >= deltasCount) {
315
+ this._deltas.shift();
316
+ }
150
317
 
151
- if (this._debounceEnd) {
152
- clearTimeout(this._debounceEnd);
318
+ this._deltas.push(delta);
319
+ }
320
+
321
+ /** Detect if touchpad */
322
+ protected get isTouchPad() {
323
+ return !this.isStableDelta || this.isSmallDelta;
324
+ }
325
+
326
+ /** Detects if deltas are stable */
327
+ protected get isStableDelta() {
328
+ const deltas = this.absDeltas;
329
+ const precision = 0.8;
330
+
331
+ // get difference between deltas
332
+ const diffs = deltas.map((d, i) => {
333
+ const prev = deltas[i - 1];
334
+ if (!deltas[i - 1]) {
335
+ return 0;
336
+ }
337
+
338
+ return d - prev;
339
+ });
340
+
341
+ const zeroDiffs = diffs.filter((d) => d === 0);
342
+
343
+ return zeroDiffs.length > diffs.length * precision;
344
+ }
345
+
346
+ /** Detects if the latest delta is small */
347
+ protected get isSmallDelta() {
348
+ const deltas = this.absDeltas;
349
+
350
+ if (deltas.length === 0) {
351
+ return true;
352
+ }
353
+
354
+ const last = deltas[deltas.length - 1];
355
+
356
+ return last < 50;
357
+ }
358
+
359
+ /** Detect if delta is gaining its value */
360
+ protected get isGainingDelta() {
361
+ const vevet = initVevet();
362
+ const deltas = this.absDeltas;
363
+ const precision = vevet.osName.includes('window') ? 1.5 : 1.2;
364
+
365
+ if (deltas.length < deltasCount) {
366
+ return false;
153
367
  }
368
+
369
+ const lastDeltas = deltas.slice(-deltasCount);
370
+
371
+ const half1 = lastDeltas.slice(0, Math.floor(lastDeltas.length / 2));
372
+ const half2 = lastDeltas.slice(Math.floor(lastDeltas.length / 2));
373
+
374
+ const avg1 = this._getAverage(half1);
375
+ const avg2 = this._getAverage(half2);
376
+
377
+ const isGaining = avg2 > avg1 * precision;
378
+
379
+ return isGaining;
380
+ }
381
+
382
+ /** Get average value in an array */
383
+ protected _getAverage(array: number[]) {
384
+ return array.length ? array.reduce((a, b) => a + b, 0) / array.length : 0;
154
385
  }
155
386
  }
@@ -18,7 +18,8 @@ export interface ISnapWheelProps {
18
18
  wheelAxis?: 'x' | 'y' | 'auto';
19
19
 
20
20
  /**
21
- * If disabled, then slider will be animated only when you stop scrolling the wheel.
21
+ * If `false`, disables smooth, continuous scrolling behavior from the mouse wheel
22
+ * and instead updates the snap position in discrete steps (like pagination).
22
23
  * @default true
23
24
  */
24
25
  followWheel?: boolean;
@@ -27,7 +28,7 @@ export interface ISnapWheelProps {
27
28
  * Throttle wheel events, value in milliseconds.
28
29
  * Works only if `followWheel` is disabled.
29
30
  *
30
- * - `auto` - value based on transition duration
31
+ * - `auto` - automatic detection when `wheel` is enabled
31
32
  * - `number - value in milliseconds
32
33
  *
33
34
  * @default `auto`
@@ -35,8 +36,14 @@ export interface ISnapWheelProps {
35
36
  wheelThrottle?: number | 'auto';
36
37
 
37
38
  /**
38
- * Enable snapping on wheel stop
39
+ * Enable snapping on wheel stop. Works with `followWheel` enabled.
39
40
  * @default true
40
41
  */
41
42
  stickOnWheelEnd?: boolean;
43
+
44
+ /**
45
+ * Snapping threshold for `stickOnWheelEnd`
46
+ * @default 30
47
+ */
48
+ stickOnWheelEndThreshold?: number;
42
49
  }