Parcourir la source

Add the `rewindByDrag` option (#636, #663).

NaotoshiFujita il y a 3 ans
Parent
commit
cf9b2c96f7

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 6
dist/js/splide-renderer.min.js


+ 71 - 62
dist/js/splide.cjs.js

@@ -1,6 +1,6 @@
 /*!
  * Splide.js
- * Version  : 3.6.12
+ * Version  : 3.6.14
  * License  : MIT
  * Copyright: 2022 Naotoshi Fujita
  */
@@ -12,12 +12,14 @@ const CREATED = 1;
 const MOUNTED = 2;
 const IDLE = 3;
 const MOVING = 4;
-const DESTROYED = 5;
+const DRAGGING = 5;
+const DESTROYED = 6;
 const STATES = {
   CREATED,
   MOUNTED,
   IDLE,
   MOVING,
+  DRAGGING,
   DESTROYED
 };
 
@@ -262,9 +264,9 @@ function unit(value) {
 const PROJECT_CODE = "splide";
 const DATA_ATTRIBUTE = `data-${PROJECT_CODE}`;
 
-function assert(condition, message = "") {
+function assert(condition, message) {
   if (!condition) {
-    throw new Error(`[${PROJECT_CODE}] ${message}`);
+    throw new Error(`[${PROJECT_CODE}] ${message || ""}`);
   }
 }
 
@@ -1749,6 +1751,7 @@ const POINTER_UP_EVENTS = "touchend touchcancel mouseup";
 
 function Drag(Splide2, Components2, options) {
   const { on, emit, bind, unbind } = EventInterface(Splide2);
+  const { state } = Splide2;
   const { Move, Scroll, Controller } = Components2;
   const { track } = Components2.Elements;
   const { resolve, orient } = Components2.Direction;
@@ -1756,10 +1759,9 @@ function Drag(Splide2, Components2, options) {
   let basePosition;
   let baseEvent;
   let prevBaseEvent;
-  let lastEvent;
   let isFree;
   let dragging;
-  let hasExceeded = false;
+  let exceeded = false;
   let clickPrevented;
   let disabled;
   let target;
@@ -1777,16 +1779,16 @@ function Drag(Splide2, Components2, options) {
     isFree = drag === "free";
   }
   function onPointerDown(e) {
+    clickPrevented = false;
     if (!disabled) {
       const { noDrag } = options;
       const isTouch = isTouchEvent(e);
       const isDraggable = !noDrag || !matches(e.target, noDrag);
-      clickPrevented = false;
       if (isDraggable && (isTouch || !e.button)) {
         if (!Move.isBusy()) {
           target = isTouch ? track : window;
+          dragging = state.is(MOVING);
           prevBaseEvent = null;
-          lastEvent = null;
           bind(target, POINTER_MOVE_EVENTS, onPointerMove, SCROLL_LISTENER_OPTIONS);
           bind(target, POINTER_UP_EVENTS, onPointerUp, SCROLL_LISTENER_OPTIONS);
           Move.cancel();
@@ -1799,80 +1801,81 @@ function Drag(Splide2, Components2, options) {
     }
   }
   function onPointerMove(e) {
-    if (!lastEvent) {
+    if (!state.is(DRAGGING)) {
+      state.set(DRAGGING);
       emit(EVENT_DRAG);
     }
-    lastEvent = e;
     if (e.cancelable) {
-      const diff = coordOf(e) - coordOf(baseEvent);
       if (dragging) {
-        Move.translate(basePosition + constrain(diff));
-        const expired = timeOf(e) - timeOf(baseEvent) > LOG_INTERVAL;
-        const exceeded = hasExceeded !== (hasExceeded = exceededLimit());
-        if (expired || exceeded) {
+        Move.translate(basePosition + constrain(diffCoord(e)));
+        const expired = diffTime(e) > LOG_INTERVAL;
+        const hasExceeded = exceeded !== (exceeded = exceededLimit());
+        if (expired || hasExceeded) {
           save(e);
         }
-        emit(EVENT_DRAGGING);
         clickPrevented = true;
+        emit(EVENT_DRAGGING);
+        prevent(e);
+      } else if (isSliderDirection(e)) {
+        dragging = shouldStart(e);
         prevent(e);
-      } else {
-        let { dragMinThreshold: thresholds } = options;
-        thresholds = isObject(thresholds) ? thresholds : { mouse: 0, touch: +thresholds || 10 };
-        dragging = abs(diff) > (isTouchEvent(e) ? thresholds.touch : thresholds.mouse);
-        if (isSliderDirection()) {
-          prevent(e);
-        }
       }
     }
   }
   function onPointerUp(e) {
-    unbind(target, POINTER_MOVE_EVENTS, onPointerMove);
-    unbind(target, POINTER_UP_EVENTS, onPointerUp);
-    const { index } = Splide2;
-    if (lastEvent) {
-      if (dragging || e.cancelable && isSliderDirection()) {
-        const velocity = computeVelocity(e);
-        const destination = computeDestination(velocity);
-        if (isFree) {
-          Controller.scroll(destination);
-        } else if (Splide2.is(FADE)) {
-          Controller.go(index + orient(sign(velocity)));
-        } else {
-          Controller.go(Controller.toDest(destination), true);
-        }
-        prevent(e);
-      }
+    if (state.is(DRAGGING)) {
+      state.set(IDLE);
       emit(EVENT_DRAGGED);
-    } else {
-      if (!isFree && getPosition() !== Move.toPosition(index)) {
-        Controller.go(index, true);
-      }
     }
+    if (dragging) {
+      move(e);
+      prevent(e);
+    }
+    unbind(target, POINTER_MOVE_EVENTS, onPointerMove);
+    unbind(target, POINTER_UP_EVENTS, onPointerUp);
     dragging = false;
   }
+  function onClick(e) {
+    if (!disabled && clickPrevented) {
+      prevent(e, true);
+    }
+  }
   function save(e) {
     prevBaseEvent = baseEvent;
     baseEvent = e;
     basePosition = getPosition();
   }
-  function onClick(e) {
-    if (!disabled && clickPrevented) {
-      prevent(e, true);
+  function move(e) {
+    const velocity = computeVelocity(e);
+    const destination = computeDestination(velocity);
+    const rewind = options.rewind && options.rewindByDrag;
+    if (isFree) {
+      Controller.scroll(destination);
+    } else if (Splide2.is(FADE)) {
+      const { length } = Splide2;
+      const index = Splide2.index + orient(sign(velocity));
+      Controller.go(rewind ? (index + length) % length : index);
+    } else if (Splide2.is(SLIDE) && exceeded && rewind) {
+      Controller.go(exceededLimit(true) ? ">" : "<");
+    } else {
+      Controller.go(Controller.toDest(destination), true);
     }
   }
-  function isSliderDirection() {
-    const diffX = abs(coordOf(lastEvent) - coordOf(baseEvent));
-    const diffY = abs(coordOf(lastEvent, true) - coordOf(baseEvent, true));
-    return diffX > diffY;
+  function shouldStart(e) {
+    const { dragMinThreshold: thresholds } = options;
+    const isObj = isObject(thresholds);
+    const mouse = isObj && thresholds.mouse || 0;
+    const touch = (isObj ? thresholds.touch : +thresholds) || 10;
+    return abs(diffCoord(e)) > (isTouchEvent(e) ? touch : mouse);
+  }
+  function isSliderDirection(e) {
+    return abs(diffCoord(e)) > abs(diffCoord(e, true));
   }
   function computeVelocity(e) {
-    if (Splide2.is(LOOP) || !hasExceeded) {
-      const base = baseEvent === lastEvent && prevBaseEvent || baseEvent;
-      const diffCoord = coordOf(lastEvent) - coordOf(base);
-      const diffTime = timeOf(e) - timeOf(base);
-      const isFlick = timeOf(e) - timeOf(lastEvent) < LOG_INTERVAL;
-      if (diffTime && isFlick) {
-        return diffCoord / diffTime;
+    if (Splide2.is(LOOP) || !exceeded) {
+      const time = diffTime(e);
+      if (time && time < LOG_INTERVAL) {
+        return diffCoord(e) / time;
       }
     }
     return 0;
@@ -1880,14 +1883,20 @@ function Drag(Splide2, Components2, options) {
   function computeDestination(velocity) {
     return getPosition() + sign(velocity) * min(abs(velocity) * (options.flickPower || 600), isFree ? Infinity : Components2.Layout.listSize() * (options.flickMaxPages || 1));
   }
-  function coordOf(e, orthogonal) {
-    return (isTouchEvent(e) ? e.touches[0] : e)[`page${resolve(orthogonal ? "Y" : "X")}`];
+  function diffCoord(e, orthogonal) {
+    return coordOf(e, orthogonal) - coordOf(getBaseEvent(e), orthogonal);
   }
-  function timeOf(e) {
-    return e.timeStamp;
+  function diffTime(e) {
+    return e.timeStamp - getBaseEvent(e).timeStamp;
+  }
+  function getBaseEvent(e) {
+    return baseEvent === e && prevBaseEvent || baseEvent;
+  }
+  function coordOf(e, orthogonal) {
+    return (isTouchEvent(e) ? e.changedTouches[0] : e)[`page${resolve(orthogonal ? "Y" : "X")}`];
   }
   function constrain(diff) {
-    return diff / (hasExceeded && Splide2.is(SLIDE) ? FRICTION : 1);
+    return diff / (exceeded && Splide2.is(SLIDE) ? FRICTION : 1);
   }
   function isTouchEvent(e) {
     return typeof TouchEvent !== "undefined" && e instanceof TouchEvent;

+ 71 - 62
dist/js/splide.esm.js

@@ -1,6 +1,6 @@
 /*!
  * Splide.js
- * Version  : 3.6.12
+ * Version  : 3.6.14
  * License  : MIT
  * Copyright: 2022 Naotoshi Fujita
  */
@@ -8,12 +8,14 @@ const CREATED = 1;
 const MOUNTED = 2;
 const IDLE = 3;
 const MOVING = 4;
-const DESTROYED = 5;
+const DRAGGING = 5;
+const DESTROYED = 6;
 const STATES = {
   CREATED,
   MOUNTED,
   IDLE,
   MOVING,
+  DRAGGING,
   DESTROYED
 };
 
@@ -258,9 +260,9 @@ function unit(value) {
 const PROJECT_CODE = "splide";
 const DATA_ATTRIBUTE = `data-${PROJECT_CODE}`;
 
-function assert(condition, message = "") {
+function assert(condition, message) {
   if (!condition) {
-    throw new Error(`[${PROJECT_CODE}] ${message}`);
+    throw new Error(`[${PROJECT_CODE}] ${message || ""}`);
   }
 }
 
@@ -1745,6 +1747,7 @@ const POINTER_UP_EVENTS = "touchend touchcancel mouseup";
 
 function Drag(Splide2, Components2, options) {
   const { on, emit, bind, unbind } = EventInterface(Splide2);
+  const { state } = Splide2;
   const { Move, Scroll, Controller } = Components2;
   const { track } = Components2.Elements;
   const { resolve, orient } = Components2.Direction;
@@ -1752,10 +1755,9 @@ function Drag(Splide2, Components2, options) {
   let basePosition;
   let baseEvent;
   let prevBaseEvent;
-  let lastEvent;
   let isFree;
   let dragging;
-  let hasExceeded = false;
+  let exceeded = false;
   let clickPrevented;
   let disabled;
   let target;
@@ -1773,16 +1775,16 @@ function Drag(Splide2, Components2, options) {
     isFree = drag === "free";
   }
   function onPointerDown(e) {
+    clickPrevented = false;
     if (!disabled) {
       const { noDrag } = options;
       const isTouch = isTouchEvent(e);
       const isDraggable = !noDrag || !matches(e.target, noDrag);
-      clickPrevented = false;
       if (isDraggable && (isTouch || !e.button)) {
         if (!Move.isBusy()) {
           target = isTouch ? track : window;
+          dragging = state.is(MOVING);
           prevBaseEvent = null;
-          lastEvent = null;
           bind(target, POINTER_MOVE_EVENTS, onPointerMove, SCROLL_LISTENER_OPTIONS);
           bind(target, POINTER_UP_EVENTS, onPointerUp, SCROLL_LISTENER_OPTIONS);
           Move.cancel();
@@ -1795,80 +1797,81 @@ function Drag(Splide2, Components2, options) {
     }
   }
   function onPointerMove(e) {
-    if (!lastEvent) {
+    if (!state.is(DRAGGING)) {
+      state.set(DRAGGING);
       emit(EVENT_DRAG);
     }
-    lastEvent = e;
     if (e.cancelable) {
-      const diff = coordOf(e) - coordOf(baseEvent);
       if (dragging) {
-        Move.translate(basePosition + constrain(diff));
-        const expired = timeOf(e) - timeOf(baseEvent) > LOG_INTERVAL;
-        const exceeded = hasExceeded !== (hasExceeded = exceededLimit());
-        if (expired || exceeded) {
+        Move.translate(basePosition + constrain(diffCoord(e)));
+        const expired = diffTime(e) > LOG_INTERVAL;
+        const hasExceeded = exceeded !== (exceeded = exceededLimit());
+        if (expired || hasExceeded) {
           save(e);
         }
-        emit(EVENT_DRAGGING);
         clickPrevented = true;
+        emit(EVENT_DRAGGING);
+        prevent(e);
+      } else if (isSliderDirection(e)) {
+        dragging = shouldStart(e);
         prevent(e);
-      } else {
-        let { dragMinThreshold: thresholds } = options;
-        thresholds = isObject(thresholds) ? thresholds : { mouse: 0, touch: +thresholds || 10 };
-        dragging = abs(diff) > (isTouchEvent(e) ? thresholds.touch : thresholds.mouse);
-        if (isSliderDirection()) {
-          prevent(e);
-        }
       }
     }
   }
   function onPointerUp(e) {
-    unbind(target, POINTER_MOVE_EVENTS, onPointerMove);
-    unbind(target, POINTER_UP_EVENTS, onPointerUp);
-    const { index } = Splide2;
-    if (lastEvent) {
-      if (dragging || e.cancelable && isSliderDirection()) {
-        const velocity = computeVelocity(e);
-        const destination = computeDestination(velocity);
-        if (isFree) {
-          Controller.scroll(destination);
-        } else if (Splide2.is(FADE)) {
-          Controller.go(index + orient(sign(velocity)));
-        } else {
-          Controller.go(Controller.toDest(destination), true);
-        }
-        prevent(e);
-      }
+    if (state.is(DRAGGING)) {
+      state.set(IDLE);
       emit(EVENT_DRAGGED);
-    } else {
-      if (!isFree && getPosition() !== Move.toPosition(index)) {
-        Controller.go(index, true);
-      }
     }
+    if (dragging) {
+      move(e);
+      prevent(e);
+    }
+    unbind(target, POINTER_MOVE_EVENTS, onPointerMove);
+    unbind(target, POINTER_UP_EVENTS, onPointerUp);
     dragging = false;
   }
+  function onClick(e) {
+    if (!disabled && clickPrevented) {
+      prevent(e, true);
+    }
+  }
   function save(e) {
     prevBaseEvent = baseEvent;
     baseEvent = e;
     basePosition = getPosition();
   }
-  function onClick(e) {
-    if (!disabled && clickPrevented) {
-      prevent(e, true);
+  function move(e) {
+    const velocity = computeVelocity(e);
+    const destination = computeDestination(velocity);
+    const rewind = options.rewind && options.rewindByDrag;
+    if (isFree) {
+      Controller.scroll(destination);
+    } else if (Splide2.is(FADE)) {
+      const { length } = Splide2;
+      const index = Splide2.index + orient(sign(velocity));
+      Controller.go(rewind ? (index + length) % length : index);
+    } else if (Splide2.is(SLIDE) && exceeded && rewind) {
+      Controller.go(exceededLimit(true) ? ">" : "<");
+    } else {
+      Controller.go(Controller.toDest(destination), true);
     }
   }
-  function isSliderDirection() {
-    const diffX = abs(coordOf(lastEvent) - coordOf(baseEvent));
-    const diffY = abs(coordOf(lastEvent, true) - coordOf(baseEvent, true));
-    return diffX > diffY;
+  function shouldStart(e) {
+    const { dragMinThreshold: thresholds } = options;
+    const isObj = isObject(thresholds);
+    const mouse = isObj && thresholds.mouse || 0;
+    const touch = (isObj ? thresholds.touch : +thresholds) || 10;
+    return abs(diffCoord(e)) > (isTouchEvent(e) ? touch : mouse);
+  }
+  function isSliderDirection(e) {
+    return abs(diffCoord(e)) > abs(diffCoord(e, true));
   }
   function computeVelocity(e) {
-    if (Splide2.is(LOOP) || !hasExceeded) {
-      const base = baseEvent === lastEvent && prevBaseEvent || baseEvent;
-      const diffCoord = coordOf(lastEvent) - coordOf(base);
-      const diffTime = timeOf(e) - timeOf(base);
-      const isFlick = timeOf(e) - timeOf(lastEvent) < LOG_INTERVAL;
-      if (diffTime && isFlick) {
-        return diffCoord / diffTime;
+    if (Splide2.is(LOOP) || !exceeded) {
+      const time = diffTime(e);
+      if (time && time < LOG_INTERVAL) {
+        return diffCoord(e) / time;
       }
     }
     return 0;
@@ -1876,14 +1879,20 @@ function Drag(Splide2, Components2, options) {
   function computeDestination(velocity) {
     return getPosition() + sign(velocity) * min(abs(velocity) * (options.flickPower || 600), isFree ? Infinity : Components2.Layout.listSize() * (options.flickMaxPages || 1));
   }
-  function coordOf(e, orthogonal) {
-    return (isTouchEvent(e) ? e.touches[0] : e)[`page${resolve(orthogonal ? "Y" : "X")}`];
+  function diffCoord(e, orthogonal) {
+    return coordOf(e, orthogonal) - coordOf(getBaseEvent(e), orthogonal);
   }
-  function timeOf(e) {
-    return e.timeStamp;
+  function diffTime(e) {
+    return e.timeStamp - getBaseEvent(e).timeStamp;
+  }
+  function getBaseEvent(e) {
+    return baseEvent === e && prevBaseEvent || baseEvent;
+  }
+  function coordOf(e, orthogonal) {
+    return (isTouchEvent(e) ? e.changedTouches[0] : e)[`page${resolve(orthogonal ? "Y" : "X")}`];
   }
   function constrain(diff) {
-    return diff / (hasExceeded && Splide2.is(SLIDE) ? FRICTION : 1);
+    return diff / (exceeded && Splide2.is(SLIDE) ? FRICTION : 1);
   }
   function isTouchEvent(e) {
     return typeof TouchEvent !== "undefined" && e instanceof TouchEvent;

+ 78 - 77
dist/js/splide.js

@@ -4,7 +4,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
 /*!
  * Splide.js
- * Version  : 3.6.13
+ * Version  : 3.6.14
  * License  : MIT
  * Copyright: 2022 Naotoshi Fujita
  */
@@ -17,12 +17,14 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var MOUNTED = 2;
   var IDLE = 3;
   var MOVING = 4;
-  var DESTROYED = 5;
+  var DRAGGING = 5;
+  var DESTROYED = 6;
   var STATES = {
     CREATED: CREATED,
     MOUNTED: MOUNTED,
     IDLE: IDLE,
     MOVING: MOVING,
+    DRAGGING: DRAGGING,
     DESTROYED: DESTROYED
   };
   var DEFAULT_EVENT_PRIORITY = 10;
@@ -289,12 +291,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var DATA_ATTRIBUTE = "data-" + PROJECT_CODE;
 
   function assert(condition, message) {
-    if (message === void 0) {
-      message = "";
-    }
-
     if (!condition) {
-      throw new Error("[" + PROJECT_CODE + "] " + message);
+      throw new Error("[" + PROJECT_CODE + "] " + (message || ""));
     }
   }
 
@@ -2101,6 +2099,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
         bind = _EventInterface12.bind,
         unbind = _EventInterface12.unbind;
 
+    var state = Splide2.state;
     var Move = Components2.Move,
         Scroll = Components2.Scroll,
         Controller = Components2.Controller;
@@ -2113,10 +2112,9 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var basePosition;
     var baseEvent;
     var prevBaseEvent;
-    var lastEvent;
     var isFree;
     var dragging;
-    var hasExceeded = false;
+    var exceeded = false;
     var clickPrevented;
     var disabled;
     var target;
@@ -2139,17 +2137,18 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function onPointerDown(e) {
+      clickPrevented = false;
+
       if (!disabled) {
         var noDrag = options.noDrag;
         var isTouch = isTouchEvent(e);
         var isDraggable = !noDrag || !matches(e.target, noDrag);
-        clickPrevented = false;
 
         if (isDraggable && (isTouch || !e.button)) {
           if (!Move.isBusy()) {
             target = isTouch ? track : window;
+            dragging = state.is(MOVING);
             prevBaseEvent = null;
-            lastEvent = null;
             bind(target, POINTER_MOVE_EVENTS, onPointerMove, SCROLL_LISTENER_OPTIONS);
             bind(target, POINTER_UP_EVENTS, onPointerUp, SCROLL_LISTENER_OPTIONS);
             Move.cancel();
@@ -2163,100 +2162,95 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function onPointerMove(e) {
-      if (!lastEvent) {
+      if (!state.is(DRAGGING)) {
+        state.set(DRAGGING);
         emit(EVENT_DRAG);
       }
 
-      lastEvent = e;
-
       if (e.cancelable) {
-        var diff = coordOf(e) - coordOf(baseEvent);
-
         if (dragging) {
-          Move.translate(basePosition + constrain(diff));
-          var expired = timeOf(e) - timeOf(baseEvent) > LOG_INTERVAL;
-          var exceeded = hasExceeded !== (hasExceeded = exceededLimit());
+          Move.translate(basePosition + constrain(diffCoord(e)));
+          var expired = diffTime(e) > LOG_INTERVAL;
+          var hasExceeded = exceeded !== (exceeded = exceededLimit());
 
-          if (expired || exceeded) {
+          if (expired || hasExceeded) {
             save(e);
           }
 
-          emit(EVENT_DRAGGING);
           clickPrevented = true;
+          emit(EVENT_DRAGGING);
+          prevent(e);
+        } else if (isSliderDirection(e)) {
+          dragging = shouldStart(e);
           prevent(e);
-        } else {
-          var thresholds = options.dragMinThreshold;
-          thresholds = isObject(thresholds) ? thresholds : {
-            mouse: 0,
-            touch: +thresholds || 10
-          };
-          dragging = abs(diff) > (isTouchEvent(e) ? thresholds.touch : thresholds.mouse);
-
-          if (isSliderDirection()) {
-            prevent(e);
-          }
         }
       }
     }
 
     function onPointerUp(e) {
-      unbind(target, POINTER_MOVE_EVENTS, onPointerMove);
-      unbind(target, POINTER_UP_EVENTS, onPointerUp);
-      var index = Splide2.index;
-
-      if (lastEvent) {
-        if (dragging || e.cancelable && isSliderDirection()) {
-          var velocity = computeVelocity(e);
-          var destination = computeDestination(velocity);
-
-          if (isFree) {
-            Controller.scroll(destination);
-          } else if (Splide2.is(FADE)) {
-            Controller.go(index + orient(sign(velocity)));
-          } else {
-            Controller.go(Controller.toDest(destination), true);
-          }
-
-          prevent(e);
-        }
-
+      if (state.is(DRAGGING)) {
+        state.set(IDLE);
         emit(EVENT_DRAGGED);
-      } else {
-        if (!isFree && getPosition() !== Move.toPosition(index)) {
-          Controller.go(index, true);
-        }
       }
 
+      if (dragging) {
+        move(e);
+        prevent(e);
+      }
+
+      unbind(target, POINTER_MOVE_EVENTS, onPointerMove);
+      unbind(target, POINTER_UP_EVENTS, onPointerUp);
       dragging = false;
     }
 
+    function onClick(e) {
+      if (!disabled && clickPrevented) {
+        prevent(e, true);
+      }
+    }
+
     function save(e) {
       prevBaseEvent = baseEvent;
       baseEvent = e;
       basePosition = getPosition();
     }
 
-    function onClick(e) {
-      if (!disabled && clickPrevented) {
-        prevent(e, true);
+    function move(e) {
+      var velocity = computeVelocity(e);
+      var destination = computeDestination(velocity);
+      var rewind = options.rewind && options.rewindByDrag;
+
+      if (isFree) {
+        Controller.scroll(destination);
+      } else if (Splide2.is(FADE)) {
+        var length = Splide2.length;
+        var index = Splide2.index + orient(sign(velocity));
+        Controller.go(rewind ? (index + length) % length : index);
+      } else if (Splide2.is(SLIDE) && exceeded && rewind) {
+        Controller.go(exceededLimit(true) ? ">" : "<");
+      } else {
+        Controller.go(Controller.toDest(destination), true);
       }
     }
 
-    function isSliderDirection() {
-      var diffX = abs(coordOf(lastEvent) - coordOf(baseEvent));
-      var diffY = abs(coordOf(lastEvent, true) - coordOf(baseEvent, true));
-      return diffX > diffY;
+    function shouldStart(e) {
+      var thresholds = options.dragMinThreshold;
+      var isObj = isObject(thresholds);
+      var mouse = isObj && thresholds.mouse || 0;
+      var touch = (isObj ? thresholds.touch : +thresholds) || 10;
+      return abs(diffCoord(e)) > (isTouchEvent(e) ? touch : mouse);
+    }
+
+    function isSliderDirection(e) {
+      return abs(diffCoord(e)) > abs(diffCoord(e, true));
     }
 
     function computeVelocity(e) {
-      if (Splide2.is(LOOP) || !hasExceeded) {
-        var base = baseEvent === lastEvent && prevBaseEvent || baseEvent;
-        var diffCoord = coordOf(lastEvent) - coordOf(base);
-        var diffTime = timeOf(e) - timeOf(base);
-        var isFlick = timeOf(e) - timeOf(lastEvent) < LOG_INTERVAL;
-
-        if (diffTime && isFlick) {
-          return diffCoord / diffTime;
+      if (Splide2.is(LOOP) || !exceeded) {
+        var time = diffTime(e);
+
+        if (time && time < LOG_INTERVAL) {
+          return diffCoord(e) / time;
         }
       }
 
@@ -2267,16 +2261,24 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       return getPosition() + sign(velocity) * min(abs(velocity) * (options.flickPower || 600), isFree ? Infinity : Components2.Layout.listSize() * (options.flickMaxPages || 1));
     }
 
-    function coordOf(e, orthogonal) {
-      return (isTouchEvent(e) ? e.touches[0] : e)["page" + resolve(orthogonal ? "Y" : "X")];
+    function diffCoord(e, orthogonal) {
+      return coordOf(e, orthogonal) - coordOf(getBaseEvent(e), orthogonal);
+    }
+
+    function diffTime(e) {
+      return e.timeStamp - getBaseEvent(e).timeStamp;
     }
 
-    function timeOf(e) {
-      return e.timeStamp;
+    function getBaseEvent(e) {
+      return baseEvent === e && prevBaseEvent || baseEvent;
+    }
+
+    function coordOf(e, orthogonal) {
+      return (isTouchEvent(e) ? e.changedTouches[0] : e)["page" + resolve(orthogonal ? "Y" : "X")];
     }
 
     function constrain(diff) {
-      return diff / (hasExceeded && Splide2.is(SLIDE) ? FRICTION : 1);
+      return diff / (exceeded && Splide2.is(SLIDE) ? FRICTION : 1);
     }
 
     function isTouchEvent(e) {
@@ -3036,4 +3038,3 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   Splide.STATES = STATES;
   return Splide;
 });
-//# sourceMappingURL=splide.js.map

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/js/splide.js.map


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 7
dist/js/splide.min.js


BIN
dist/js/splide.min.js.gz


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/js/splide.min.js.map


+ 10 - 5
dist/types/index.d.ts

@@ -409,18 +409,23 @@ interface ResponsiveOptions {
      * Accepts arbitrary properties for extensions, although it's not ideal typing.
      */
     [key: string]: any;
-    /**
-     * Determines whether to rewind the slider or not.
-     */
-    rewind?: boolean;
     /**
      * The transition speed in milliseconds.
      */
     speed?: number;
+    /**
+     * Determines whether to rewind the slider or not.
+     */
+    rewind?: boolean;
     /**
      * The transition speed on rewind in milliseconds.
      */
     rewindSpeed?: number;
+    /**
+     * Allows to rewind by drag.
+     * The slider `type` must be `slide` (or `undefined`) and the `drag` option must be enabled.
+     */
+    rewindByDrag?: boolean;
     /**
      * Defines the slider max width, accepting the CSS format such as 10em, 80vw.
      */
@@ -515,7 +520,7 @@ interface ResponsiveOptions {
      */
     easingFunc?: (t: number) => number;
     /**
-     * Determines whether to allow to drag the slider or not.
+     * Allows to drag the slider by a mouse or swipe.
      * If `free`, the slider does not snap to a slide after drag.
      */
     drag?: boolean | 'free';

+ 1 - 1
src/css/core/object/modifiers/draggable.scss

@@ -4,8 +4,8 @@
   &--draggable {
     > #{ $root }__slider > #{ $root }__track,
     > #{ $root }__track {
-      user-select: none;
       -webkit-touch-callout: none;
+      user-select: none;
     }
   }
 }

+ 26 - 13
src/js/components/Drag/Drag.ts

@@ -124,8 +124,8 @@ export function Drag( Splide: Splide, Components: Components, options: Options )
       if ( isDraggable && ( isTouch || ! e.button ) ) {
         if ( ! Move.isBusy() ) {
           target        = isTouch ? track : window;
-          prevBaseEvent = null;
           dragging      = state.is( MOVING );
+          prevBaseEvent = null;
 
           bind( target, POINTER_MOVE_EVENTS, onPointerMove, SCROLL_LISTENER_OPTIONS );
           bind( target, POINTER_UP_EVENTS, onPointerUp, SCROLL_LISTENER_OPTIONS );
@@ -186,17 +186,7 @@ export function Drag( Splide: Splide, Components: Components, options: Options )
     }
 
     if ( dragging ) {
-      const velocity    = computeVelocity( e );
-      const destination = computeDestination( velocity );
-
-      if ( isFree ) {
-        Controller.scroll( destination );
-      } else if ( Splide.is( FADE ) ) {
-        Controller.go( Splide.index + orient( sign( velocity ) ) );
-      } else {
-        Controller.go( Controller.toDest( destination ), true );
-      }
-
+      move( e );
       prevent( e );
     }
 
@@ -220,7 +210,7 @@ export function Drag( Splide: Splide, Components: Components, options: Options )
   /**
    * Saves data at the specific moment.
    *
-   * @param e - A TouchEvent or MouseEvent object
+   * @param e - A TouchEvent or MouseEvent object.
    */
   function save( e: TouchEvent | MouseEvent ): void {
     prevBaseEvent = baseEvent;
@@ -228,6 +218,29 @@ export function Drag( Splide: Splide, Components: Components, options: Options )
     basePosition  = getPosition();
   }
 
+  /**
+   * Moves the slider according to the drag result.
+   *
+   * @param e - A TouchEvent or MouseEvent object.
+   */
+  function move( e: TouchEvent | MouseEvent ): void {
+    const velocity    = computeVelocity( e );
+    const destination = computeDestination( velocity );
+    const rewind      = options.rewind && options.rewindByDrag;
+
+    if ( isFree ) {
+      Controller.scroll( destination );
+    } else if ( Splide.is( FADE ) ) {
+      const { length } = Splide;
+      const index = Splide.index + orient( sign( velocity ) );
+      Controller.go( rewind ? ( index + length ) % length : index );
+    } else if ( Splide.is( SLIDE ) && exceeded && rewind ) {
+      Controller.go( exceededLimit( true ) ? '>' : '<' );
+    } else {
+      Controller.go( Controller.toDest( destination ), true );
+    }
+  }
+
   /**
    * Checks if the drag distance exceeds the defined threshold.
    *

+ 80 - 0
src/js/components/Drag/test/rewind.test.ts

@@ -0,0 +1,80 @@
+import { fire, init, wait } from '../../../test';
+import { assign } from '../../../utils';
+
+
+describe( 'Drag', () => {
+  test( 'can rewind the slider if `rewind` and `rewindByDrag` are enabled.', () => {
+    const splide = init( { speed: 0, rewind: true, rewindByDrag: true } );
+    const track  = splide.Components.Elements.track;
+
+    expect( splide.index ).toBe( 0 );
+
+    // On the first slide, drags backwards a bit.
+    drag( track, true );
+    expect( splide.index ).toBe( splide.length - 1 );
+
+    // On the last slide, drags forwards a bit.
+    drag( track, false ); // Forwards
+    expect( splide.index ).toBe( 0 );
+  } );
+
+  test( 'should not rewind the slider if `rewindByDrag` is disabled.', () => {
+    const splide = init( { speed: 0, rewind: true, rewindByDrag: false } );
+    const track  = splide.Components.Elements.track;
+
+    expect( splide.index ).toBe( 0 );
+
+    drag( track, true );
+    expect( splide.index ).toBe( 0 );
+  } );
+
+  test( 'should not rewind the slider if `rewind` is disabled.', () => {
+    const splide = init( { speed: 0, rewind: false, rewindByDrag: true } );
+    const track  = splide.Components.Elements.track;
+
+    expect( splide.index ).toBe( 0 );
+
+    drag( track, true );
+    expect( splide.index ).toBe( 0 );
+  } );
+
+  test( 'can rewind the fade slider if `rewind` and `rewindByDrag` are enabled.', async () => {
+    const splide = init( { type: 'fade', speed: 0, rewind: true, rewindByDrag: true } );
+    const track  = splide.Components.Elements.track;
+
+    expect( splide.index ).toBe( 0 );
+
+    drag( track, true );
+    expect( splide.index ).toBe( splide.length - 1 );
+
+    await wait(); // Wait `nextTick`.
+
+    drag( track, false );
+    expect( splide.index ).toBe( 0 );
+  } );
+} );
+
+function fireCancelable( elm: Element | Window, event: string, data: any = {} ): void {
+  fire( elm, event, data, { cancelable: true } );
+}
+
+function fireWithCoord( elm: Element | Window, event: string, data: any = {} ): void {
+  const { x: pageX = 0, y: pageY = 0 } = data;
+
+  fireCancelable( elm, event, assign( data, {
+    pageX,
+    pageY,
+    touches: [
+      { pageX, pageY },
+    ],
+  } ) );
+}
+
+function drag( track: HTMLElement, backwards?: boolean ): void {
+  const to = backwards ? 10 : -10;
+
+  fireWithCoord( track, 'mousedown', { x: 0, timeStamp: 1 } );
+  fireWithCoord( window, 'mousemove', { x: 1, timeStamp: 1 } );
+  fireWithCoord( window, 'mousemove', { x: to, timeStamp: 20 } );
+  fireWithCoord( window, 'mouseup', { x: to, timeStamp: 20 } );
+}

+ 54 - 27
src/js/test/php/examples/default.php

@@ -19,44 +19,71 @@ $settings = get_settings();
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
-        type   : 'loop',
-        perPage: 3,
+        // type   : 'loop',
+        perPage: 2,
         // perMove: 1,
-        // rewind: true,
+        rewind: true,
+	      rewindByDrag: true,
         // padding: {
         //   right: 0,
         //   left: 40,
         // },
         // updateOnMove: true,
-        focus: 'center',
-        noDrag: 'button',
+        // focus: 'center',
+	      dragMinThreshold: {
+					mouse: 20,
+		      touch: 0,
+	      },
+	      speed: 1000,
+				waitForTransition: false,
+        // noDrag: 'button',
       } );
 
-      splide.on( 'moved', () => {
-        console.log( 'moved' );
-      } );
-
-      splide.on( 'visible', Slide => {
-        console.log( 'visible', Slide.index );
-      } );
-
-      splide.on( 'hidden', Slide => {
-        console.log( 'hidden', Slide.index );
-      } );
-
-      splide.on( 'click', () => {
-        console.log( 'click' );
-      } );
-
-      splide.on( 'shifted', () => {
-        console.log( 'shifted' );
-      } );
+	    // splide.on( 'move', () => {
+		  //   console.log( 'move' );
+	    // } );
+	    //
+      // splide.on( 'moved', () => {
+      //   console.log( 'moved' );
+      // } );
+	    //
+      // splide.on( 'visible', Slide => {
+      //   console.log( 'visible', Slide.index );
+      // } );
+	    //
+      // splide.on( 'hidden', Slide => {
+      //   console.log( 'hidden', Slide.index );
+      // } );
+	    //
+      // splide.on( 'click', () => {
+      //   console.log( 'click' );
+      // } );
+	    //
+      // splide.on( 'shifted', () => {
+      //   console.log( 'shifted' );
+      // } );
+	    //
+	    // splide.on( 'drag', () => {
+		  //   console.log( 'drag' );
+	    // } );
+	    //
+	    // splide.on( 'dragged', () => {
+		  //   console.log( 'dragged' );
+	    // } );
 
       splide.mount();
 
-			// Array.from( document.getElementsByTagName( 'button' ) ).forEach( button => {
-			// 	button.addEventListener( 'click', () => alert( 'click' ) );
+	    const pre = document.querySelector( 'pre' );
+
+	    // Array.from( document.getElementsByTagName( 'button' ) ).forEach( button => {
+			// 	button.addEventListener( 'click', () => {
+			// 		alert( 'click' );
+			// 	} );
 			// } );
+
+			// console.log = ( ...args ) => {
+			// 	pre.textContent = args.join( ' ' ) + '\n' + pre.textContent;
+			// };
     } );
   </script>
 
@@ -67,7 +94,7 @@ $settings = get_settings();
   </style>
 </head>
 <body>
-
+3444556
 <?php render( 'splide01', 11 ); ?>
 
 <pre></pre>

+ 2 - 2
src/js/test/php/examples/drag-free.php

@@ -19,8 +19,8 @@ $settings = get_settings();
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
-        perPage: 4,
-        gap    : '1.5rem',
+        perPage: 2,
+        gap    : '0.5em',
         drag   : 'free',
         // height : 400,
         type   : 'loop',

+ 4 - 0
src/js/test/php/examples/fade.php

@@ -21,6 +21,10 @@ $settings = get_settings();
       var splide = new Splide( '#splide01', {
         width: 800,
         type : 'fade',
+	      rewind: false,
+	      // rewindByDrag: true,
+	      autoplay: true,
+	      interval: 1000,
         breakpoints: {
           640: {
             width: '100%',

+ 11 - 5
src/js/types/options.ts

@@ -204,20 +204,26 @@ export interface ResponsiveOptions {
   [ key: string ]: any;
 
   /**
-   * Determines whether to rewind the slider or not.
+   * The transition speed in milliseconds.
    */
-  rewind?: boolean;
+  speed?: number;
 
   /**
-   * The transition speed in milliseconds.
+   * Determines whether to rewind the slider or not.
    */
-  speed?: number;
+  rewind?: boolean;
 
   /**
    * The transition speed on rewind in milliseconds.
    */
   rewindSpeed?: number;
 
+  /**
+   * Allows to rewind by drag.
+   * The slider `type` must be `slide` (or `undefined`) and the `drag` option must be enabled.
+   */
+  rewindByDrag?: boolean;
+
   /**
    * Defines the slider max width, accepting the CSS format such as 10em, 80vw.
    */
@@ -326,7 +332,7 @@ export interface ResponsiveOptions {
   easingFunc?: ( t: number ) => number;
 
   /**
-   * Determines whether to allow to drag the slider or not.
+   * Allows to drag the slider by a mouse or swipe.
    * If `free`, the slider does not snap to a slide after drag.
    */
   drag?: boolean | 'free';

+ 2 - 2
src/js/utils/error/assert/assert.ts

@@ -7,8 +7,8 @@ import { PROJECT_CODE } from '../../../constants/project';
  * @param condition - If falsy, an error is thrown.
  * @param message   - Optional. A message to display.
  */
-export function assert( condition: any, message = '' ): void {
+export function assert( condition: any, message?: string ): void {
   if ( ! condition ) {
-    throw new Error( `[${ PROJECT_CODE }] ${ message }` );
+    throw new Error( `[${ PROJECT_CODE }] ${ message || '' }` );
   }
 }

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff