Browse code

Remove old version 5

Benjamin Roth authored on14/03/2021 15:27:00
Showing1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,424 +0,0 @@
1
-import { window, document } from 'ssr-window';
2
-import $ from '../../utils/dom';
3
-import Utils from '../../utils/utils';
4
-
5
-function isEventSupported() {
6
-  const eventName = 'onwheel';
7
-  let isSupported = eventName in document;
8
-
9
-  if (!isSupported) {
10
-    const element = document.createElement('div');
11
-    element.setAttribute(eventName, 'return;');
12
-    isSupported = typeof element[eventName] === 'function';
13
-  }
14
-
15
-  if (!isSupported
16
-    && document.implementation
17
-    && document.implementation.hasFeature
18
-    // always returns true in newer browsers as per the standard.
19
-    // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
20
-    && document.implementation.hasFeature('', '') !== true
21
-  ) {
22
-    // This is the only way to test support for the `wheel` event in IE9+.
23
-    isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
24
-  }
25
-
26
-  return isSupported;
27
-}
28
-const Mousewheel = {
29
-  lastScrollTime: Utils.now(),
30
-  lastEventBeforeSnap: undefined,
31
-  recentWheelEvents: [],
32
-  event() {
33
-    if (window.navigator.userAgent.indexOf('firefox') > -1) return 'DOMMouseScroll';
34
-    return isEventSupported() ? 'wheel' : 'mousewheel';
35
-  },
36
-  normalize(e) {
37
-    // Reasonable defaults
38
-    const PIXEL_STEP = 10;
39
-    const LINE_HEIGHT = 40;
40
-    const PAGE_HEIGHT = 800;
41
-
42
-    let sX = 0;
43
-    let sY = 0; // spinX, spinY
44
-    let pX = 0;
45
-    let pY = 0; // pixelX, pixelY
46
-
47
-    // Legacy
48
-    if ('detail' in e) {
49
-      sY = e.detail;
50
-    }
51
-    if ('wheelDelta' in e) {
52
-      sY = -e.wheelDelta / 120;
53
-    }
54
-    if ('wheelDeltaY' in e) {
55
-      sY = -e.wheelDeltaY / 120;
56
-    }
57
-    if ('wheelDeltaX' in e) {
58
-      sX = -e.wheelDeltaX / 120;
59
-    }
60
-
61
-    // side scrolling on FF with DOMMouseScroll
62
-    if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
63
-      sX = sY;
64
-      sY = 0;
65
-    }
66
-
67
-    pX = sX * PIXEL_STEP;
68
-    pY = sY * PIXEL_STEP;
69
-
70
-    if ('deltaY' in e) {
71
-      pY = e.deltaY;
72
-    }
73
-    if ('deltaX' in e) {
74
-      pX = e.deltaX;
75
-    }
76
-
77
-    if (e.shiftKey && !pX) { // if user scrolls with shift he wants horizontal scroll
78
-      pX = pY;
79
-      pY = 0;
80
-    }
81
-
82
-    if ((pX || pY) && e.deltaMode) {
83
-      if (e.deltaMode === 1) { // delta in LINE units
84
-        pX *= LINE_HEIGHT;
85
-        pY *= LINE_HEIGHT;
86
-      } else { // delta in PAGE units
87
-        pX *= PAGE_HEIGHT;
88
-        pY *= PAGE_HEIGHT;
89
-      }
90
-    }
91
-
92
-    // Fall-back if spin cannot be determined
93
-    if (pX && !sX) {
94
-      sX = (pX < 1) ? -1 : 1;
95
-    }
96
-    if (pY && !sY) {
97
-      sY = (pY < 1) ? -1 : 1;
98
-    }
99
-
100
-    return {
101
-      spinX: sX,
102
-      spinY: sY,
103
-      pixelX: pX,
104
-      pixelY: pY,
105
-    };
106
-  },
107
-  handleMouseEnter() {
108
-    const swiper = this;
109
-    swiper.mouseEntered = true;
110
-  },
111
-  handleMouseLeave() {
112
-    const swiper = this;
113
-    swiper.mouseEntered = false;
114
-  },
115
-  handle(event) {
116
-    let e = event;
117
-    const swiper = this;
118
-    const params = swiper.params.mousewheel;
119
-
120
-    if (swiper.params.cssMode) {
121
-      e.preventDefault();
122
-    }
123
-
124
-    let target = swiper.$el;
125
-    if (swiper.params.mousewheel.eventsTarged !== 'container') {
126
-      target = $(swiper.params.mousewheel.eventsTarged);
127
-    }
128
-    if (!swiper.mouseEntered && !target[0].contains(e.target) && !params.releaseOnEdges) return true;
129
-
130
-    if (e.originalEvent) e = e.originalEvent; // jquery fix
131
-    let delta = 0;
132
-    const rtlFactor = swiper.rtlTranslate ? -1 : 1;
133
-
134
-    const data = Mousewheel.normalize(e);
135
-
136
-    if (params.forceToAxis) {
137
-      if (swiper.isHorizontal()) {
138
-        if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = data.pixelX * rtlFactor;
139
-        else return true;
140
-      } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = data.pixelY;
141
-      else return true;
142
-    } else {
143
-      delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
144
-    }
145
-
146
-    if (delta === 0) return true;
147
-
148
-    if (params.invert) delta = -delta;
149
-
150
-    if (!swiper.params.freeMode) {
151
-      // Register the new event in a variable which stores the relevant data
152
-      const newEvent = {
153
-        time: Utils.now(),
154
-        delta: Math.abs(delta),
155
-        direction: Math.sign(delta),
156
-        raw: event,
157
-      };
158
-
159
-      // Keep the most recent events
160
-      const recentWheelEvents = swiper.mousewheel.recentWheelEvents;
161
-      if (recentWheelEvents.length >= 2) {
162
-        recentWheelEvents.shift(); // only store the last N events
163
-      }
164
-      const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
165
-      recentWheelEvents.push(newEvent);
166
-
167
-      // If there is at least one previous recorded event:
168
-      //   If direction has changed or
169
-      //   if the scroll is quicker than the previous one:
170
-      //     Animate the slider.
171
-      // Else (this is the first time the wheel is moved):
172
-      //     Animate the slider.
173
-      if (prevEvent) {
174
-        if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
175
-          swiper.mousewheel.animateSlider(newEvent);
176
-        }
177
-      } else {
178
-        swiper.mousewheel.animateSlider(newEvent);
179
-      }
180
-
181
-      // If it's time to release the scroll:
182
-      //   Return now so you don't hit the preventDefault.
183
-      if (swiper.mousewheel.releaseScroll(newEvent)) {
184
-        return true;
185
-      }
186
-    } else {
187
-      // Freemode or scrollContainer:
188
-
189
-      // If we recently snapped after a momentum scroll, then ignore wheel events
190
-      // to give time for the deceleration to finish. Stop ignoring after 500 msecs
191
-      // or if it's a new scroll (larger delta or inverse sign as last event before
192
-      // an end-of-momentum snap).
193
-      const newEvent = { time: Utils.now(), delta: Math.abs(delta), direction: Math.sign(delta) };
194
-      const { lastEventBeforeSnap } = swiper.mousewheel;
195
-      const ignoreWheelEvents = lastEventBeforeSnap
196
-        && newEvent.time < lastEventBeforeSnap.time + 500
197
-        && newEvent.delta <= lastEventBeforeSnap.delta
198
-        && newEvent.direction === lastEventBeforeSnap.direction;
199
-      if (!ignoreWheelEvents) {
200
-        swiper.mousewheel.lastEventBeforeSnap = undefined;
201
-
202
-        if (swiper.params.loop) {
203
-          swiper.loopFix();
204
-        }
205
-        let position = swiper.getTranslate() + (delta * params.sensitivity);
206
-        const wasBeginning = swiper.isBeginning;
207
-        const wasEnd = swiper.isEnd;
208
-
209
-        if (position >= swiper.minTranslate()) position = swiper.minTranslate();
210
-        if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
211
-
212
-        swiper.setTransition(0);
213
-        swiper.setTranslate(position);
214
-        swiper.updateProgress();
215
-        swiper.updateActiveIndex();
216
-        swiper.updateSlidesClasses();
217
-
218
-        if ((!wasBeginning && swiper.isBeginning) || (!wasEnd && swiper.isEnd)) {
219
-          swiper.updateSlidesClasses();
220
-        }
221
-
222
-        if (swiper.params.freeModeSticky) {
223
-          // When wheel scrolling starts with sticky (aka snap) enabled, then detect
224
-          // the end of a momentum scroll by storing recent (N=15?) wheel events.
225
-          // 1. do all N events have decreasing or same (absolute value) delta?
226
-          // 2. did all N events arrive in the last M (M=500?) msecs?
227
-          // 3. does the earliest event have an (absolute value) delta that's
228
-          //    at least P (P=1?) larger than the most recent event's delta?
229
-          // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
230
-          // If 1-4 are "yes" then we're near the end of a momuntum scroll deceleration.
231
-          // Snap immediately and ignore remaining wheel events in this scroll.
232
-          // See comment above for "remaining wheel events in this scroll" determination.
233
-          // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
234
-          clearTimeout(swiper.mousewheel.timeout);
235
-          swiper.mousewheel.timeout = undefined;
236
-          const recentWheelEvents = swiper.mousewheel.recentWheelEvents;
237
-          if (recentWheelEvents.length >= 15) {
238
-            recentWheelEvents.shift(); // only store the last N events
239
-          }
240
-          const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
241
-          const firstEvent = recentWheelEvents[0];
242
-          recentWheelEvents.push(newEvent);
243
-          if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
244
-            // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
245
-            recentWheelEvents.splice(0);
246
-          } else if (recentWheelEvents.length >= 15
247
-              && newEvent.time - firstEvent.time < 500
248
-              && firstEvent.delta - newEvent.delta >= 1
249
-              && newEvent.delta <= 6
250
-          ) {
251
-            // We're at the end of the deceleration of a momentum scroll, so there's no need
252
-            // to wait for more events. Snap ASAP on the next tick.
253
-            // Also, because there's some remaining momentum we'll bias the snap in the
254
-            // direction of the ongoing scroll because it's better UX for the scroll to snap
255
-            // in the same direction as the scroll instead of reversing to snap.  Therefore,
256
-            // if it's already scrolled more than 20% in the current direction, keep going.
257
-            const snapToThreshold = delta > 0 ? 0.8 : 0.2;
258
-            swiper.mousewheel.lastEventBeforeSnap = newEvent;
259
-            recentWheelEvents.splice(0);
260
-            swiper.mousewheel.timeout = Utils.nextTick(() => {
261
-              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
262
-            }, 0); // no delay; move on next tick
263
-          }
264
-          if (!swiper.mousewheel.timeout) {
265
-            // if we get here, then we haven't detected the end of a momentum scroll, so
266
-            // we'll consider a scroll "complete" when there haven't been any wheel events
267
-            // for 500ms.
268
-            swiper.mousewheel.timeout = Utils.nextTick(() => {
269
-              const snapToThreshold = 0.5;
270
-              swiper.mousewheel.lastEventBeforeSnap = newEvent;
271
-              recentWheelEvents.splice(0);
272
-              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
273
-            }, 500);
274
-          }
275
-        }
276
-
277
-        // Emit event
278
-        if (!ignoreWheelEvents) swiper.emit('scroll', e);
279
-
280
-        // Stop autoplay
281
-        if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop();
282
-        // Return page scroll on edge positions
283
-        if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true;
284
-      }
285
-    }
286
-
287
-    if (e.preventDefault) e.preventDefault();
288
-    else e.returnValue = false;
289
-    return false;
290
-  },
291
-  animateSlider(newEvent) {
292
-    const swiper = this;
293
-    // If the movement is NOT big enough and
294
-    // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
295
-    //   Don't go any further (avoid insignificant scroll movement).
296
-    if (newEvent.delta >= 6 && Utils.now() - swiper.mousewheel.lastScrollTime < 60) {
297
-      // Return false as a default
298
-      return true;
299
-    }
300
-    // If user is scrolling towards the end:
301
-    //   If the slider hasn't hit the latest slide or
302
-    //   if the slider is a loop and
303
-    //   if the slider isn't moving right now:
304
-    //     Go to next slide and
305
-    //     emit a scroll event.
306
-    // Else (the user is scrolling towards the beginning) and
307
-    // if the slider hasn't hit the first slide or
308
-    // if the slider is a loop and
309
-    // if the slider isn't moving right now:
310
-    //   Go to prev slide and
311
-    //   emit a scroll event.
312
-    if (newEvent.direction < 0) {
313
-      if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
314
-        swiper.slideNext();
315
-        swiper.emit('scroll', newEvent.raw);
316
-      }
317
-    } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
318
-      swiper.slidePrev();
319
-      swiper.emit('scroll', newEvent.raw);
320
-    }
321
-    // If you got here is because an animation has been triggered so store the current time
322
-    swiper.mousewheel.lastScrollTime = (new window.Date()).getTime();
323
-    // Return false as a default
324
-    return false;
325
-  },
326
-  releaseScroll(newEvent) {
327
-    const swiper = this;
328
-    const params = swiper.params.mousewheel;
329
-    if (newEvent.direction < 0) {
330
-      if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
331
-        // Return true to animate scroll on edges
332
-        return true;
333
-      }
334
-    } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
335
-      // Return true to animate scroll on edges
336
-      return true;
337
-    }
338
-    return false;
339
-  },
340
-  enable() {
341
-    const swiper = this;
342
-    const event = Mousewheel.event();
343
-    if (swiper.params.cssMode) {
344
-      swiper.wrapperEl.removeEventListener(event, swiper.mousewheel.handle);
345
-      return true;
346
-    }
347
-    if (!event) return false;
348
-    if (swiper.mousewheel.enabled) return false;
349
-    let target = swiper.$el;
350
-    if (swiper.params.mousewheel.eventsTarged !== 'container') {
351
-      target = $(swiper.params.mousewheel.eventsTarged);
352
-    }
353
-    target.on('mouseenter', swiper.mousewheel.handleMouseEnter);
354
-    target.on('mouseleave', swiper.mousewheel.handleMouseLeave);
355
-    target.on(event, swiper.mousewheel.handle);
356
-    swiper.mousewheel.enabled = true;
357
-    return true;
358
-  },
359
-  disable() {
360
-    const swiper = this;
361
-    const event = Mousewheel.event();
362
-    if (swiper.params.cssMode) {
363
-      swiper.wrapperEl.addEventListener(event, swiper.mousewheel.handle);
364
-      return true;
365
-    }
366
-    if (!event) return false;
367
-    if (!swiper.mousewheel.enabled) return false;
368
-    let target = swiper.$el;
369
-    if (swiper.params.mousewheel.eventsTarged !== 'container') {
370
-      target = $(swiper.params.mousewheel.eventsTarged);
371
-    }
372
-    target.off(event, swiper.mousewheel.handle);
373
-    swiper.mousewheel.enabled = false;
374
-    return true;
375
-  },
376
-};
377
-
378
-export default {
379
-  name: 'mousewheel',
380
-  params: {
381
-    mousewheel: {
382
-      enabled: false,
383
-      releaseOnEdges: false,
384
-      invert: false,
385
-      forceToAxis: false,
386
-      sensitivity: 1,
387
-      eventsTarged: 'container',
388
-    },
389
-  },
390
-  create() {
391
-    const swiper = this;
392
-    Utils.extend(swiper, {
393
-      mousewheel: {
394
-        enabled: false,
395
-        enable: Mousewheel.enable.bind(swiper),
396
-        disable: Mousewheel.disable.bind(swiper),
397
-        handle: Mousewheel.handle.bind(swiper),
398
-        handleMouseEnter: Mousewheel.handleMouseEnter.bind(swiper),
399
-        handleMouseLeave: Mousewheel.handleMouseLeave.bind(swiper),
400
-        animateSlider: Mousewheel.animateSlider.bind(swiper),
401
-        releaseScroll: Mousewheel.releaseScroll.bind(swiper),
402
-        lastScrollTime: Utils.now(),
403
-        lastEventBeforeSnap: undefined,
404
-        recentWheelEvents: [],
405
-      },
406
-    });
407
-  },
408
-  on: {
409
-    init() {
410
-      const swiper = this;
411
-      if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
412
-        swiper.mousewheel.disable();
413
-      }
414
-      if (swiper.params.mousewheel.enabled) swiper.mousewheel.enable();
415
-    },
416
-    destroy() {
417
-      const swiper = this;
418
-      if (swiper.params.cssMode) {
419
-        swiper.mousewheel.enable();
420
-      }
421
-      if (swiper.mousewheel.enabled) swiper.mousewheel.disable();
422
-    },
423
-  },
424
-};
Browse code

Initial commit

Benjamin Roth authored on19/05/2020 21:59:44
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,424 @@
1
+import { window, document } from 'ssr-window';
2
+import $ from '../../utils/dom';
3
+import Utils from '../../utils/utils';
4
+
5
+function isEventSupported() {
6
+  const eventName = 'onwheel';
7
+  let isSupported = eventName in document;
8
+
9
+  if (!isSupported) {
10
+    const element = document.createElement('div');
11
+    element.setAttribute(eventName, 'return;');
12
+    isSupported = typeof element[eventName] === 'function';
13
+  }
14
+
15
+  if (!isSupported
16
+    && document.implementation
17
+    && document.implementation.hasFeature
18
+    // always returns true in newer browsers as per the standard.
19
+    // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
20
+    && document.implementation.hasFeature('', '') !== true
21
+  ) {
22
+    // This is the only way to test support for the `wheel` event in IE9+.
23
+    isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
24
+  }
25
+
26
+  return isSupported;
27
+}
28
+const Mousewheel = {
29
+  lastScrollTime: Utils.now(),
30
+  lastEventBeforeSnap: undefined,
31
+  recentWheelEvents: [],
32
+  event() {
33
+    if (window.navigator.userAgent.indexOf('firefox') > -1) return 'DOMMouseScroll';
34
+    return isEventSupported() ? 'wheel' : 'mousewheel';
35
+  },
36
+  normalize(e) {
37
+    // Reasonable defaults
38
+    const PIXEL_STEP = 10;
39
+    const LINE_HEIGHT = 40;
40
+    const PAGE_HEIGHT = 800;
41
+
42
+    let sX = 0;
43
+    let sY = 0; // spinX, spinY
44
+    let pX = 0;
45
+    let pY = 0; // pixelX, pixelY
46
+
47
+    // Legacy
48
+    if ('detail' in e) {
49
+      sY = e.detail;
50
+    }
51
+    if ('wheelDelta' in e) {
52
+      sY = -e.wheelDelta / 120;
53
+    }
54
+    if ('wheelDeltaY' in e) {
55
+      sY = -e.wheelDeltaY / 120;
56
+    }
57
+    if ('wheelDeltaX' in e) {
58
+      sX = -e.wheelDeltaX / 120;
59
+    }
60
+
61
+    // side scrolling on FF with DOMMouseScroll
62
+    if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
63
+      sX = sY;
64
+      sY = 0;
65
+    }
66
+
67
+    pX = sX * PIXEL_STEP;
68
+    pY = sY * PIXEL_STEP;
69
+
70
+    if ('deltaY' in e) {
71
+      pY = e.deltaY;
72
+    }
73
+    if ('deltaX' in e) {
74
+      pX = e.deltaX;
75
+    }
76
+
77
+    if (e.shiftKey && !pX) { // if user scrolls with shift he wants horizontal scroll
78
+      pX = pY;
79
+      pY = 0;
80
+    }
81
+
82
+    if ((pX || pY) && e.deltaMode) {
83
+      if (e.deltaMode === 1) { // delta in LINE units
84
+        pX *= LINE_HEIGHT;
85
+        pY *= LINE_HEIGHT;
86
+      } else { // delta in PAGE units
87
+        pX *= PAGE_HEIGHT;
88
+        pY *= PAGE_HEIGHT;
89
+      }
90
+    }
91
+
92
+    // Fall-back if spin cannot be determined
93
+    if (pX && !sX) {
94
+      sX = (pX < 1) ? -1 : 1;
95
+    }
96
+    if (pY && !sY) {
97
+      sY = (pY < 1) ? -1 : 1;
98
+    }
99
+
100
+    return {
101
+      spinX: sX,
102
+      spinY: sY,
103
+      pixelX: pX,
104
+      pixelY: pY,
105
+    };
106
+  },
107
+  handleMouseEnter() {
108
+    const swiper = this;
109
+    swiper.mouseEntered = true;
110
+  },
111
+  handleMouseLeave() {
112
+    const swiper = this;
113
+    swiper.mouseEntered = false;
114
+  },
115
+  handle(event) {
116
+    let e = event;
117
+    const swiper = this;
118
+    const params = swiper.params.mousewheel;
119
+
120
+    if (swiper.params.cssMode) {
121
+      e.preventDefault();
122
+    }
123
+
124
+    let target = swiper.$el;
125
+    if (swiper.params.mousewheel.eventsTarged !== 'container') {
126
+      target = $(swiper.params.mousewheel.eventsTarged);
127
+    }
128
+    if (!swiper.mouseEntered && !target[0].contains(e.target) && !params.releaseOnEdges) return true;
129
+
130
+    if (e.originalEvent) e = e.originalEvent; // jquery fix
131
+    let delta = 0;
132
+    const rtlFactor = swiper.rtlTranslate ? -1 : 1;
133
+
134
+    const data = Mousewheel.normalize(e);
135
+
136
+    if (params.forceToAxis) {
137
+      if (swiper.isHorizontal()) {
138
+        if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = data.pixelX * rtlFactor;
139
+        else return true;
140
+      } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = data.pixelY;
141
+      else return true;
142
+    } else {
143
+      delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
144
+    }
145
+
146
+    if (delta === 0) return true;
147
+
148
+    if (params.invert) delta = -delta;
149
+
150
+    if (!swiper.params.freeMode) {
151
+      // Register the new event in a variable which stores the relevant data
152
+      const newEvent = {
153
+        time: Utils.now(),
154
+        delta: Math.abs(delta),
155
+        direction: Math.sign(delta),
156
+        raw: event,
157
+      };
158
+
159
+      // Keep the most recent events
160
+      const recentWheelEvents = swiper.mousewheel.recentWheelEvents;
161
+      if (recentWheelEvents.length >= 2) {
162
+        recentWheelEvents.shift(); // only store the last N events
163
+      }
164
+      const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
165
+      recentWheelEvents.push(newEvent);
166
+
167
+      // If there is at least one previous recorded event:
168
+      //   If direction has changed or
169
+      //   if the scroll is quicker than the previous one:
170
+      //     Animate the slider.
171
+      // Else (this is the first time the wheel is moved):
172
+      //     Animate the slider.
173
+      if (prevEvent) {
174
+        if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
175
+          swiper.mousewheel.animateSlider(newEvent);
176
+        }
177
+      } else {
178
+        swiper.mousewheel.animateSlider(newEvent);
179
+      }
180
+
181
+      // If it's time to release the scroll:
182
+      //   Return now so you don't hit the preventDefault.
183
+      if (swiper.mousewheel.releaseScroll(newEvent)) {
184
+        return true;
185
+      }
186
+    } else {
187
+      // Freemode or scrollContainer:
188
+
189
+      // If we recently snapped after a momentum scroll, then ignore wheel events
190
+      // to give time for the deceleration to finish. Stop ignoring after 500 msecs
191
+      // or if it's a new scroll (larger delta or inverse sign as last event before
192
+      // an end-of-momentum snap).
193
+      const newEvent = { time: Utils.now(), delta: Math.abs(delta), direction: Math.sign(delta) };
194
+      const { lastEventBeforeSnap } = swiper.mousewheel;
195
+      const ignoreWheelEvents = lastEventBeforeSnap
196
+        && newEvent.time < lastEventBeforeSnap.time + 500
197
+        && newEvent.delta <= lastEventBeforeSnap.delta
198
+        && newEvent.direction === lastEventBeforeSnap.direction;
199
+      if (!ignoreWheelEvents) {
200
+        swiper.mousewheel.lastEventBeforeSnap = undefined;
201
+
202
+        if (swiper.params.loop) {
203
+          swiper.loopFix();
204
+        }
205
+        let position = swiper.getTranslate() + (delta * params.sensitivity);
206
+        const wasBeginning = swiper.isBeginning;
207
+        const wasEnd = swiper.isEnd;
208
+
209
+        if (position >= swiper.minTranslate()) position = swiper.minTranslate();
210
+        if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
211
+
212
+        swiper.setTransition(0);
213
+        swiper.setTranslate(position);
214
+        swiper.updateProgress();
215
+        swiper.updateActiveIndex();
216
+        swiper.updateSlidesClasses();
217
+
218
+        if ((!wasBeginning && swiper.isBeginning) || (!wasEnd && swiper.isEnd)) {
219
+          swiper.updateSlidesClasses();
220
+        }
221
+
222
+        if (swiper.params.freeModeSticky) {
223
+          // When wheel scrolling starts with sticky (aka snap) enabled, then detect
224
+          // the end of a momentum scroll by storing recent (N=15?) wheel events.
225
+          // 1. do all N events have decreasing or same (absolute value) delta?
226
+          // 2. did all N events arrive in the last M (M=500?) msecs?
227
+          // 3. does the earliest event have an (absolute value) delta that's
228
+          //    at least P (P=1?) larger than the most recent event's delta?
229
+          // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
230
+          // If 1-4 are "yes" then we're near the end of a momuntum scroll deceleration.
231
+          // Snap immediately and ignore remaining wheel events in this scroll.
232
+          // See comment above for "remaining wheel events in this scroll" determination.
233
+          // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
234
+          clearTimeout(swiper.mousewheel.timeout);
235
+          swiper.mousewheel.timeout = undefined;
236
+          const recentWheelEvents = swiper.mousewheel.recentWheelEvents;
237
+          if (recentWheelEvents.length >= 15) {
238
+            recentWheelEvents.shift(); // only store the last N events
239
+          }
240
+          const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
241
+          const firstEvent = recentWheelEvents[0];
242
+          recentWheelEvents.push(newEvent);
243
+          if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
244
+            // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
245
+            recentWheelEvents.splice(0);
246
+          } else if (recentWheelEvents.length >= 15
247
+              && newEvent.time - firstEvent.time < 500
248
+              && firstEvent.delta - newEvent.delta >= 1
249
+              && newEvent.delta <= 6
250
+          ) {
251
+            // We're at the end of the deceleration of a momentum scroll, so there's no need
252
+            // to wait for more events. Snap ASAP on the next tick.
253
+            // Also, because there's some remaining momentum we'll bias the snap in the
254
+            // direction of the ongoing scroll because it's better UX for the scroll to snap
255
+            // in the same direction as the scroll instead of reversing to snap.  Therefore,
256
+            // if it's already scrolled more than 20% in the current direction, keep going.
257
+            const snapToThreshold = delta > 0 ? 0.8 : 0.2;
258
+            swiper.mousewheel.lastEventBeforeSnap = newEvent;
259
+            recentWheelEvents.splice(0);
260
+            swiper.mousewheel.timeout = Utils.nextTick(() => {
261
+              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
262
+            }, 0); // no delay; move on next tick
263
+          }
264
+          if (!swiper.mousewheel.timeout) {
265
+            // if we get here, then we haven't detected the end of a momentum scroll, so
266
+            // we'll consider a scroll "complete" when there haven't been any wheel events
267
+            // for 500ms.
268
+            swiper.mousewheel.timeout = Utils.nextTick(() => {
269
+              const snapToThreshold = 0.5;
270
+              swiper.mousewheel.lastEventBeforeSnap = newEvent;
271
+              recentWheelEvents.splice(0);
272
+              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
273
+            }, 500);
274
+          }
275
+        }
276
+
277
+        // Emit event
278
+        if (!ignoreWheelEvents) swiper.emit('scroll', e);
279
+
280
+        // Stop autoplay
281
+        if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop();
282
+        // Return page scroll on edge positions
283
+        if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true;
284
+      }
285
+    }
286
+
287
+    if (e.preventDefault) e.preventDefault();
288
+    else e.returnValue = false;
289
+    return false;
290
+  },
291
+  animateSlider(newEvent) {
292
+    const swiper = this;
293
+    // If the movement is NOT big enough and
294
+    // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
295
+    //   Don't go any further (avoid insignificant scroll movement).
296
+    if (newEvent.delta >= 6 && Utils.now() - swiper.mousewheel.lastScrollTime < 60) {
297
+      // Return false as a default
298
+      return true;
299
+    }
300
+    // If user is scrolling towards the end:
301
+    //   If the slider hasn't hit the latest slide or
302
+    //   if the slider is a loop and
303
+    //   if the slider isn't moving right now:
304
+    //     Go to next slide and
305
+    //     emit a scroll event.
306
+    // Else (the user is scrolling towards the beginning) and
307
+    // if the slider hasn't hit the first slide or
308
+    // if the slider is a loop and
309
+    // if the slider isn't moving right now:
310
+    //   Go to prev slide and
311
+    //   emit a scroll event.
312
+    if (newEvent.direction < 0) {
313
+      if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
314
+        swiper.slideNext();
315
+        swiper.emit('scroll', newEvent.raw);
316
+      }
317
+    } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
318
+      swiper.slidePrev();
319
+      swiper.emit('scroll', newEvent.raw);
320
+    }
321
+    // If you got here is because an animation has been triggered so store the current time
322
+    swiper.mousewheel.lastScrollTime = (new window.Date()).getTime();
323
+    // Return false as a default
324
+    return false;
325
+  },
326
+  releaseScroll(newEvent) {
327
+    const swiper = this;
328
+    const params = swiper.params.mousewheel;
329
+    if (newEvent.direction < 0) {
330
+      if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
331
+        // Return true to animate scroll on edges
332
+        return true;
333
+      }
334
+    } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
335
+      // Return true to animate scroll on edges
336
+      return true;
337
+    }
338
+    return false;
339
+  },
340
+  enable() {
341
+    const swiper = this;
342
+    const event = Mousewheel.event();
343
+    if (swiper.params.cssMode) {
344
+      swiper.wrapperEl.removeEventListener(event, swiper.mousewheel.handle);
345
+      return true;
346
+    }
347
+    if (!event) return false;
348
+    if (swiper.mousewheel.enabled) return false;
349
+    let target = swiper.$el;
350
+    if (swiper.params.mousewheel.eventsTarged !== 'container') {
351
+      target = $(swiper.params.mousewheel.eventsTarged);
352
+    }
353
+    target.on('mouseenter', swiper.mousewheel.handleMouseEnter);
354
+    target.on('mouseleave', swiper.mousewheel.handleMouseLeave);
355
+    target.on(event, swiper.mousewheel.handle);
356
+    swiper.mousewheel.enabled = true;
357
+    return true;
358
+  },
359
+  disable() {
360
+    const swiper = this;
361
+    const event = Mousewheel.event();
362
+    if (swiper.params.cssMode) {
363
+      swiper.wrapperEl.addEventListener(event, swiper.mousewheel.handle);
364
+      return true;
365
+    }
366
+    if (!event) return false;
367
+    if (!swiper.mousewheel.enabled) return false;
368
+    let target = swiper.$el;
369
+    if (swiper.params.mousewheel.eventsTarged !== 'container') {
370
+      target = $(swiper.params.mousewheel.eventsTarged);
371
+    }
372
+    target.off(event, swiper.mousewheel.handle);
373
+    swiper.mousewheel.enabled = false;
374
+    return true;
375
+  },
376
+};
377
+
378
+export default {
379
+  name: 'mousewheel',
380
+  params: {
381
+    mousewheel: {
382
+      enabled: false,
383
+      releaseOnEdges: false,
384
+      invert: false,
385
+      forceToAxis: false,
386
+      sensitivity: 1,
387
+      eventsTarged: 'container',
388
+    },
389
+  },
390
+  create() {
391
+    const swiper = this;
392
+    Utils.extend(swiper, {
393
+      mousewheel: {
394
+        enabled: false,
395
+        enable: Mousewheel.enable.bind(swiper),
396
+        disable: Mousewheel.disable.bind(swiper),
397
+        handle: Mousewheel.handle.bind(swiper),
398
+        handleMouseEnter: Mousewheel.handleMouseEnter.bind(swiper),
399
+        handleMouseLeave: Mousewheel.handleMouseLeave.bind(swiper),
400
+        animateSlider: Mousewheel.animateSlider.bind(swiper),
401
+        releaseScroll: Mousewheel.releaseScroll.bind(swiper),
402
+        lastScrollTime: Utils.now(),
403
+        lastEventBeforeSnap: undefined,
404
+        recentWheelEvents: [],
405
+      },
406
+    });
407
+  },
408
+  on: {
409
+    init() {
410
+      const swiper = this;
411
+      if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
412
+        swiper.mousewheel.disable();
413
+      }
414
+      if (swiper.params.mousewheel.enabled) swiper.mousewheel.enable();
415
+    },
416
+    destroy() {
417
+      const swiper = this;
418
+      if (swiper.params.cssMode) {
419
+        swiper.mousewheel.enable();
420
+      }
421
+      if (swiper.mousewheel.enabled) swiper.mousewheel.disable();
422
+    },
423
+  },
424
+};