ソースを参照

Support the horizontal mouse wheel.

Naotoshi Fujita 2 年 前
コミット
ab0bcb25b7

ファイルの差分が大きいため隠しています
+ 0 - 0
dist/js/splide-renderer.min.js.map


+ 24 - 13
dist/js/splide.cjs.js

@@ -66,9 +66,6 @@ function toArray(value) {
 function forEach(values, iteratee) {
   toArray(values).forEach(iteratee);
 }
-function includes(array, value) {
-  return array.includes(value);
-}
 function push(array, items) {
   array.push(...toArray(items));
   return array;
@@ -77,6 +74,9 @@ const arrayProto = Array.prototype;
 function slice(arrayLike, start, end) {
   return arrayProto.slice.call(arrayLike, start, end);
 }
+function includes(arrayLike, value) {
+  return arrayProto.includes.call(arrayLike, value);
+}
 function toggleClass(elm, classes, force) {
   if (elm) {
     forEach(isString(classes) ? classes.split(" ") : classes, (className) => {
@@ -1216,9 +1216,8 @@ const Move = (Splide, Components, options, event) => {
   }
   function loop(position) {
     if (Splide.is(LOOP)) {
-      const index = toIndex(position);
-      const exceededMax = index > Components.Controller.getEnd();
-      const exceededMin = index < 0;
+      const exceededMax = exceededLimit(true, position);
+      const exceededMin = exceededLimit(false, position);
       if (exceededMin || exceededMax) {
         position = shift(position, exceededMax);
       }
@@ -1294,7 +1293,8 @@ const Move = (Splide, Components, options, event) => {
     getPosition,
     getLimit,
     exceededLimit,
-    reposition
+    reposition,
+    canShift
   };
 };
 
@@ -1341,7 +1341,9 @@ const Controller = (Splide, Components, options, event) => {
     if (!isBusy()) {
       const dest = parse(control);
       const index = loop(dest);
-      if (index > -1 && (allowSameIndex || index !== currIndex)) {
+      const validIndex = index > -1 && (allowSameIndex || index !== currIndex);
+      const canMove = dest === index || Move.canShift(dest > prevIndex);
+      if (validIndex && canMove) {
         setIndex(index);
         Move.move(dest, index, prevIndex, callback);
       }
@@ -1839,7 +1841,7 @@ const Drag = (Splide, Components, options, event) => {
     const rewind = options.rewind && options.rewindByDrag;
     reduce(false);
     if (isFree) {
-      Controller.scroll(destination, 0, options.snap);
+      Controller.scroll(destination, void 0, options.snap);
     } else if (Splide.is(FADE)) {
       Controller.go(orient(sign(velocity)) < 0 ? rewind ? "<" : "-" : rewind ? ">" : "+");
     } else if (Splide.is(SLIDE) && exceeded && rewind) {
@@ -2229,24 +2231,33 @@ const Sync = (Splide2, Components, options, event) => {
 const Wheel = (Splide, Components, options, event) => {
   let lastTime = 0;
   function mount() {
+    event.destroy();
     if (options.wheel) {
       event.bind(Components.Elements.track, "wheel", onWheel, SCROLL_LISTENER_OPTIONS);
     }
+    event.on(EVENT_UPDATED, mount);
   }
   function onWheel(e) {
     if (e.cancelable) {
-      const { deltaY } = e;
-      const backwards = deltaY < 0;
+      const delta = parse(e);
+      const backwards = delta < 0;
       const timeStamp = timeOf(e);
       const min = options.wheelMinThreshold || 0;
       const sleep = options.wheelSleep || 0;
-      if (abs(deltaY) > min && timeStamp - lastTime > sleep) {
-        Splide.go(backwards ? "<" : ">");
+      if (abs(delta) > min && timeStamp - lastTime > sleep) {
+        Splide.go(delta < 0 ? "<" : ">");
         lastTime = timeStamp;
       }
       shouldPrevent(backwards) && prevent(e);
     }
   }
+  function parse(e) {
+    const { wheelAxis = "y" } = options;
+    const { deltaX, deltaY } = e;
+    const x = includes(wheelAxis, "x") ? Components.Direction.orient(-deltaX) : 0;
+    const y = includes(wheelAxis, "y") ? deltaY : 0;
+    return x || y;
+  }
   function shouldPrevent(backwards) {
     return !options.releaseWheel || Splide.state.is(MOVING) || Components.Controller.getAdjacent(backwards) !== -1;
   }

+ 24 - 13
dist/js/splide.esm.js

@@ -62,9 +62,6 @@ function toArray(value) {
 function forEach(values, iteratee) {
   toArray(values).forEach(iteratee);
 }
-function includes(array, value) {
-  return array.includes(value);
-}
 function push(array, items) {
   array.push(...toArray(items));
   return array;
@@ -73,6 +70,9 @@ const arrayProto = Array.prototype;
 function slice(arrayLike, start, end) {
   return arrayProto.slice.call(arrayLike, start, end);
 }
+function includes(arrayLike, value) {
+  return arrayProto.includes.call(arrayLike, value);
+}
 function toggleClass(elm, classes, force) {
   if (elm) {
     forEach(isString(classes) ? classes.split(" ") : classes, (className) => {
@@ -1212,9 +1212,8 @@ const Move = (Splide, Components, options, event) => {
   }
   function loop(position) {
     if (Splide.is(LOOP)) {
-      const index = toIndex(position);
-      const exceededMax = index > Components.Controller.getEnd();
-      const exceededMin = index < 0;
+      const exceededMax = exceededLimit(true, position);
+      const exceededMin = exceededLimit(false, position);
       if (exceededMin || exceededMax) {
         position = shift(position, exceededMax);
       }
@@ -1290,7 +1289,8 @@ const Move = (Splide, Components, options, event) => {
     getPosition,
     getLimit,
     exceededLimit,
-    reposition
+    reposition,
+    canShift
   };
 };
 
@@ -1337,7 +1337,9 @@ const Controller = (Splide, Components, options, event) => {
     if (!isBusy()) {
       const dest = parse(control);
       const index = loop(dest);
-      if (index > -1 && (allowSameIndex || index !== currIndex)) {
+      const validIndex = index > -1 && (allowSameIndex || index !== currIndex);
+      const canMove = dest === index || Move.canShift(dest > prevIndex);
+      if (validIndex && canMove) {
         setIndex(index);
         Move.move(dest, index, prevIndex, callback);
       }
@@ -1835,7 +1837,7 @@ const Drag = (Splide, Components, options, event) => {
     const rewind = options.rewind && options.rewindByDrag;
     reduce(false);
     if (isFree) {
-      Controller.scroll(destination, 0, options.snap);
+      Controller.scroll(destination, void 0, options.snap);
     } else if (Splide.is(FADE)) {
       Controller.go(orient(sign(velocity)) < 0 ? rewind ? "<" : "-" : rewind ? ">" : "+");
     } else if (Splide.is(SLIDE) && exceeded && rewind) {
@@ -2225,24 +2227,33 @@ const Sync = (Splide2, Components, options, event) => {
 const Wheel = (Splide, Components, options, event) => {
   let lastTime = 0;
   function mount() {
+    event.destroy();
     if (options.wheel) {
       event.bind(Components.Elements.track, "wheel", onWheel, SCROLL_LISTENER_OPTIONS);
     }
+    event.on(EVENT_UPDATED, mount);
   }
   function onWheel(e) {
     if (e.cancelable) {
-      const { deltaY } = e;
-      const backwards = deltaY < 0;
+      const delta = parse(e);
+      const backwards = delta < 0;
       const timeStamp = timeOf(e);
       const min = options.wheelMinThreshold || 0;
       const sleep = options.wheelSleep || 0;
-      if (abs(deltaY) > min && timeStamp - lastTime > sleep) {
-        Splide.go(backwards ? "<" : ">");
+      if (abs(delta) > min && timeStamp - lastTime > sleep) {
+        Splide.go(delta < 0 ? "<" : ">");
         lastTime = timeStamp;
       }
       shouldPrevent(backwards) && prevent(e);
     }
   }
+  function parse(e) {
+    const { wheelAxis = "y" } = options;
+    const { deltaX, deltaY } = e;
+    const x = includes(wheelAxis, "x") ? Components.Direction.orient(-deltaX) : 0;
+    const y = includes(wheelAxis, "y") ? deltaY : 0;
+    return x || y;
+  }
   function shouldPrevent(backwards) {
     return !options.releaseWheel || Splide.state.is(MOVING) || Components.Controller.getAdjacent(backwards) !== -1;
   }

+ 23 - 12
dist/js/splide.js

@@ -68,9 +68,6 @@
   function forEach(values, iteratee) {
     toArray(values).forEach(iteratee);
   }
-  function includes(array, value) {
-    return array.includes(value);
-  }
   function push(array, items) {
     array.push(...toArray(items));
     return array;
@@ -79,6 +76,9 @@
   function slice(arrayLike, start, end) {
     return arrayProto.slice.call(arrayLike, start, end);
   }
+  function includes(arrayLike, value) {
+    return arrayProto.includes.call(arrayLike, value);
+  }
   function toggleClass(elm, classes, force) {
     if (elm) {
       forEach(isString(classes) ? classes.split(" ") : classes, (className) => {
@@ -1212,9 +1212,8 @@
     }
     function loop(position) {
       if (Splide.is(LOOP)) {
-        const index = toIndex(position);
-        const exceededMax = index > Components.Controller.getEnd();
-        const exceededMin = index < 0;
+        const exceededMax = exceededLimit(true, position);
+        const exceededMin = exceededLimit(false, position);
         if (exceededMin || exceededMax) {
           position = shift(position, exceededMax);
         }
@@ -1290,7 +1289,8 @@
       getPosition,
       getLimit,
       exceededLimit,
-      reposition
+      reposition,
+      canShift
     };
   };
 
@@ -1337,7 +1337,9 @@
       if (!isBusy()) {
         const dest = parse(control);
         const index = loop(dest);
-        if (index > -1 && (allowSameIndex || index !== currIndex)) {
+        const validIndex = index > -1 && (allowSameIndex || index !== currIndex);
+        const canMove = dest === index || Move.canShift(dest > prevIndex);
+        if (validIndex && canMove) {
           setIndex(index);
           Move.move(dest, index, prevIndex, callback);
         }
@@ -2225,24 +2227,33 @@
   const Wheel = (Splide, Components, options, event) => {
     let lastTime = 0;
     function mount() {
+      event.destroy();
       if (options.wheel) {
         event.bind(Components.Elements.track, "wheel", onWheel, SCROLL_LISTENER_OPTIONS);
       }
+      event.on(EVENT_UPDATED, mount);
     }
     function onWheel(e) {
       if (e.cancelable) {
-        const { deltaY } = e;
-        const backwards = deltaY < 0;
+        const delta = parse(e);
+        const backwards = delta < 0;
         const timeStamp = timeOf(e);
         const min = options.wheelMinThreshold || 0;
         const sleep = options.wheelSleep || 0;
-        if (abs(deltaY) > min && timeStamp - lastTime > sleep) {
-          Splide.go(backwards ? "<" : ">");
+        if (abs(delta) > min && timeStamp - lastTime > sleep) {
+          Splide.go(delta < 0 ? "<" : ">");
           lastTime = timeStamp;
         }
         shouldPrevent(backwards) && prevent(e);
       }
     }
+    function parse(e) {
+      const { wheelAxis = "y" } = options;
+      const { deltaX, deltaY } = e;
+      const x = includes(wheelAxis, "x") ? Components.Direction.orient(-deltaX) : 0;
+      const y = includes(wheelAxis, "y") ? deltaY : 0;
+      return x || y;
+    }
     function shouldPrevent(backwards) {
       return !options.releaseWheel || Splide.state.is(MOVING) || Components.Controller.getAdjacent(backwards) !== -1;
     }

ファイルの差分が大きいため隠しています
+ 0 - 0
dist/js/splide.min.js


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


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/js/splide.min.js.map


+ 6 - 1
dist/types/index.d.ts

@@ -221,6 +221,7 @@ interface MoveComponent extends BaseComponent {
     exceededLimit(max?: boolean | undefined, position?: number): boolean;
     /** @internal */
     reposition(): void;
+    canShift(backwards: boolean): boolean;
 }
 
 /**
@@ -474,9 +475,13 @@ interface Options extends ResponsiveOptions {
     keyboard?: boolean | 'global' | 'focused';
     /**
      * Enables navigation by the mouse wheel.
-     * Set `waitForTransition` to `ture` or provide the `wheelSleep` duration.
+     * You'll need to set `waitForTransition` to `ture` or provide the `wheelSleep` duration to avoid quick change.
      */
     wheel?: boolean;
+    /**
+     * Determines the wheel axis. The default value is 'y'.
+     */
+    wheelAxis?: 'x' | 'y' | 'xy';
     /**
      * The threshold to cut off the small delta produced by inertia scroll.
      */

+ 5 - 3
src/js/components/Controller/Controller.ts

@@ -134,10 +134,12 @@ export const Controller: ComponentConstructor<ControllerComponent> = ( Splide, C
    */
   function go( control: number | string, allowSameIndex?: boolean, callback?: AnyFunction ): void {
     if ( ! isBusy() ) {
-      const dest  = parse( control );
-      const index = loop( dest );
+      const dest       = parse( control );
+      const index      = loop( dest );
+      const validIndex = index > -1 && ( allowSameIndex || index !== currIndex );
+      const canMove    = dest === index || Move.canShift( dest > prevIndex );
 
-      if ( index > -1 && ( allowSameIndex || index !== currIndex ) ) {
+      if ( validIndex && canMove ) {
         setIndex( index );
         Move.move( dest, index, prevIndex, callback );
       }

+ 6 - 3
src/js/components/Move/Move.ts

@@ -32,6 +32,7 @@ export interface MoveComponent extends BaseComponent {
 
   /** @internal */
   reposition(): void;
+  canShift( backwards: boolean ): boolean;
 }
 
 /**
@@ -131,12 +132,13 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
    * Loops the provided position if it exceeds bounds (limit indices).
    *
    * @param position - A position to loop.
+   *
+   * @return A looped position.
    */
   function loop( position: number ): number {
     if ( Splide.is( LOOP ) ) {
-      const index       = toIndex( position );
-      const exceededMax = index > Components.Controller.getEnd();
-      const exceededMin = index < 0;
+      const exceededMax = exceededLimit( true, position );
+      const exceededMin = exceededLimit( false, position );
 
       if ( exceededMin || exceededMax ) {
         position = shift( position, exceededMax );
@@ -301,5 +303,6 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
     getLimit,
     exceededLimit,
     reposition,
+    canShift,
   };
 };

+ 24 - 5
src/js/components/Wheel/Wheel.ts

@@ -1,7 +1,8 @@
 import { SCROLL_LISTENER_OPTIONS } from '../../constants/listener-options';
 import { MOVING } from '../../constants/states';
 import { BaseComponent, ComponentConstructor } from '../../types';
-import { abs, prevent, timeOf } from '@splidejs/utils';
+import { abs, includes, prevent, timeOf } from '@splidejs/utils';
+import { EVENT_UPDATED } from '../../constants/events';
 
 
 /**
@@ -34,9 +35,13 @@ export const Wheel: ComponentConstructor<WheelComponent> = ( Splide, Components,
    * Called when the component is mounted.
    */
   function mount(): void {
+    event.destroy();
+
     if ( options.wheel ) {
       event.bind( Components.Elements.track, 'wheel', onWheel, SCROLL_LISTENER_OPTIONS );
     }
+
+    event.on( EVENT_UPDATED, mount );
   }
 
   /**
@@ -46,14 +51,14 @@ export const Wheel: ComponentConstructor<WheelComponent> = ( Splide, Components,
    */
   function onWheel( e: WheelEvent ): void {
     if ( e.cancelable ) {
-      const { deltaY } = e;
-      const backwards = deltaY < 0;
+      const delta     = parse( e );
+      const backwards = delta < 0;
       const timeStamp = timeOf( e );
       const min       = options.wheelMinThreshold || 0;
       const sleep     = options.wheelSleep || 0;
 
-      if ( abs( deltaY ) > min && timeStamp - lastTime > sleep ) {
-        Splide.go( backwards ? '<' : '>' );
+      if ( abs( delta ) > min && timeStamp - lastTime > sleep ) {
+        Splide.go( delta < 0 ? '<' : '>' );
         lastTime = timeStamp;
       }
 
@@ -61,6 +66,20 @@ export const Wheel: ComponentConstructor<WheelComponent> = ( Splide, Components,
     }
   }
 
+  /**
+   * Parses the wheel event and returns delta.
+   *
+   * @param e - A WheelEvent object.
+   */
+  function parse( e: WheelEvent ): number {
+    const { wheelAxis = 'y' } = options;
+    const { deltaX, deltaY } = e;
+    const x = includes( wheelAxis, 'x' ) ? Components.Direction.orient( -deltaX ) : 0;
+    const y = includes( wheelAxis, 'y' ) ? deltaY : 0;
+
+    return x || y;
+  }
+
   /**
    * Checks whether the component should prevent the default action of the wheel event or not.
    *

+ 3 - 0
src/js/test/utils/utils.ts

@@ -92,6 +92,9 @@ export function init( options: Options = {}, args: InitArgs = {} ): Splide {
 
   if ( mount ) {
     splide.mount();
+
+    // Can not simulate this method.
+    splide.Components.Move.canShift = () => true;
   }
 
   return splide;

+ 6 - 1
src/js/types/options.ts

@@ -104,10 +104,15 @@ export interface Options extends ResponsiveOptions {
 
   /**
    * Enables navigation by the mouse wheel.
-   * Set `waitForTransition` to `ture` or provide the `wheelSleep` duration.
+   * You'll need to set `waitForTransition` to `ture` or provide the `wheelSleep` duration to avoid quick change.
    */
   wheel?: boolean;
 
+  /**
+   * Determines the wheel axis. The default value is 'y'.
+   */
+  wheelAxis?: 'x' | 'y' | 'xy';
+
   /**
    * The threshold to cut off the small delta produced by inertia scroll.
    */

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません