Przeglądaj źródła

Add the `getRate()` method.

Naotoshi Fujita 2 lat temu
rodzic
commit
97f287bf79

Plik diff jest za duży
+ 0 - 0
dist/js/splide-renderer.min.js


Plik diff jest za duży
+ 0 - 0
dist/js/splide-renderer.min.js.map


+ 46 - 18
dist/js/splide.js

@@ -1171,6 +1171,7 @@
     const { resolve, orient } = Components.Direction;
     const { list, track } = Components.Elements;
     let Transition;
+    let indices;
     function mount() {
       Transition = Components.Transition;
       on([EVENT_MOUNTED, EVENT_RESIZED, EVENT_UPDATED, EVENT_REFRESH], reposition);
@@ -1183,12 +1184,11 @@
       }
     }
     function move(dest, index, prev, callback) {
+      Transition.cancel();
       if (dest !== index && canShift(dest > prev)) {
-        cancel();
         translate(shift(getPosition(), dest > prev), true);
-      } else {
-        Transition.cancel();
       }
+      indices = [index, prev, dest];
       set(MOVING);
       emit(EVENT_MOVE, index, prev, dest);
       Transition.start(index, () => {
@@ -1209,10 +1209,9 @@
     }
     function loop(position) {
       if (Splide.is(LOOP)) {
-        const exceededMax = exceededLimit(true, position);
-        const exceededMin = exceededLimit(false, position);
-        if (exceededMin || exceededMax) {
-          position = shift(position, exceededMax);
+        const diff = orient(position) - orient(getPosition());
+        if (diff && exceededLimit(diff > 0, position)) {
+          position = shift(position, diff > 0);
         }
       }
       return position;
@@ -1224,8 +1223,11 @@
       return position;
     }
     function cancel() {
-      translate(getPosition(), true);
-      Transition.cancel();
+      if (Splide.state.is(MOVING) && indices) {
+        translate(getPosition(), true);
+        Transition.cancel();
+        emit(EVENT_MOVED, ...indices);
+      }
     }
     function toIndex(position) {
       const slides = Slides.get();
@@ -1251,6 +1253,25 @@
       const left = resolve("left");
       return rect(list)[left] - rect(track)[left] + orient(getPadding(false));
     }
+    function getRate() {
+      let rate;
+      if (Splide.is(FADE)) {
+        rate = Splide.index / (Splide.length - 1);
+      } else {
+        const isLoop = Splide.is(LOOP);
+        const position = orient(getPosition());
+        const min = orient(getLimit(false));
+        const max = orient(getLimit(true));
+        const size = sliderSize();
+        const curr = (position - min) % size;
+        const base = isLoop ? size : max - min;
+        rate = curr / base || 0;
+        if (isLoop && rate < 0) {
+          rate += 1;
+        }
+      }
+      return clamp(rate, 0, 1);
+    }
     function trim(position) {
       if (options.trimSpace && Splide.is(SLIDE)) {
         position = clamp(position, 0, orient(sliderSize(true) - listSize()));
@@ -1284,6 +1305,7 @@
       toIndex,
       toPosition,
       getPosition,
+      getRate,
       getLimit,
       exceededLimit,
       reposition,
@@ -1676,22 +1698,28 @@
       on([EVENT_UPDATED, EVENT_REFRESH], cancel);
     }
     function scroll(destination, duration, snap, onScrolled, noConstrain) {
-      const from = getPosition();
       clear();
-      if (snap && (!isSlide || !exceededLimit())) {
-        const size = Components.Layout.sliderSize();
-        const offset = sign(destination) * size * floor(abs(destination) / size) || 0;
-        destination = Move.toPosition(Components.Controller.toDest(destination % size)) + offset;
-      }
-      const immediately = approximatelyEqual(from, destination, 1) || duration === 0;
+      const dest = computeDestination(destination, snap);
+      const from = getPosition();
+      const immediately = approximatelyEqual(from, dest, 1) || duration === 0;
       friction = 1;
-      duration = immediately ? 0 : duration || max(abs(destination - from) / BASE_VELOCITY, MIN_DURATION);
+      duration = immediately ? 0 : duration || max(abs(dest - from) / BASE_VELOCITY, MIN_DURATION);
       callback = onScrolled;
-      interval = RequestInterval(duration, onEnd, apply(update, from, destination, noConstrain), 1);
+      interval = RequestInterval(duration, onEnd, apply(update, from, dest, noConstrain), 1);
       set(SCROLLING);
       emit(EVENT_SCROLL);
       interval.start();
     }
+    function computeDestination(destination, snap) {
+      if (snap) {
+        if (!isSlide || !exceededLimit()) {
+          const position = destination % Components.Layout.sliderSize();
+          const snapped = Move.toPosition(Components.Controller.toDest(position));
+          destination -= position - snapped;
+        }
+      }
+      return destination;
+    }
     function onEnd() {
       set(IDLE);
       callback && callback();

Plik diff jest za duży
+ 0 - 0
dist/js/splide.min.js


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


Plik diff jest za duży
+ 0 - 0
dist/js/splide.min.js.map


+ 1 - 1
src/css/core/object/objects/sr.scss

@@ -9,4 +9,4 @@
     position: absolute !important;
     width: 1px !important;
   }
-}
+}

+ 44 - 5
src/js/components/Move/Move.ts

@@ -27,6 +27,7 @@ export interface MoveComponent extends BaseComponent {
   toIndex( position: number ): number;
   toPosition( index: number, trimming?: boolean ): number;
   getPosition(): number;
+  getRate(): number;
   getLimit( max: boolean ): number;
   exceededLimit( max?: boolean | undefined, position?: number ): boolean;
 
@@ -60,6 +61,11 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
    */
   let Transition: TransitionComponent;
 
+  /**
+   * Keeps the latest indices.
+   */
+  let indices: [ number, number, number ];
+
   /**
    * Called when the component is mounted.
    */
@@ -90,13 +96,13 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
    * @param callback - Optional. A callback function invoked after transition ends.
    */
   function move( dest: number, index: number, prev: number, callback?: AnyFunction ): void {
+    Transition.cancel();
+
     if ( dest !== index && canShift( dest > prev ) ) {
-      cancel();
       translate( shift( getPosition(), dest > prev ), true );
-    } else {
-      Transition.cancel();
     }
 
+    indices = [ index, prev, dest ];
     set( MOVING );
     emit( EVENT_MOVE, index, prev, dest );
 
@@ -168,8 +174,11 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
    * Cancels transition.
    */
   function cancel(): void {
-    translate( getPosition(), true );
-    Transition.cancel();
+    if ( Splide.state.is( MOVING ) && indices ) {
+      translate( getPosition(), true );
+      Transition.cancel();
+      emit( EVENT_MOVED, ...indices );
+    }
   }
 
   /**
@@ -223,6 +232,35 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
     return rect( list )[ left ] - rect( track )[ left ] + orient( getPadding( false ) );
   }
 
+  /**
+   * Returns the carousel progress rate.
+   *
+   * @return The progress rate.
+   */
+  function getRate(): number {
+    let rate;
+
+    if ( Splide.is( FADE ) ) {
+      rate = Splide.index / ( Splide.length - 1 );
+    } else {
+      const isLoop   = Splide.is( LOOP );
+      const position = orient( getPosition() );
+      const min      = orient( getLimit( false ) );
+      const max      = orient( getLimit( true ) );
+      const size     = sliderSize();
+      const curr     = ( position - min ) % size;
+      const base     = isLoop ? size : max - min;
+
+      rate = ( curr / base ) || 0;
+
+      if ( isLoop && rate < 0 ) {
+        rate += 1;
+      }
+    }
+
+    return clamp( rate, 0, 1 );
+  }
+
   /**
    * Trims spaces on the edge of the slider.
    *
@@ -301,6 +339,7 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
     toIndex,
     toPosition,
     getPosition,
+    getRate,
     getLimit,
     exceededLimit,
     reposition,

+ 51 - 0
src/js/components/Move/test/getRate.test.ts

@@ -0,0 +1,51 @@
+import { init } from '../../../test';
+
+
+describe( 'Move#getRate()', () => {
+  test( 'can return the current progress rate.', () => {
+    // To make the calculation simple, set the length to 11 so that the base number becomes 10.
+    const splide = init( { width: 200, speed: 0 }, { length: 11 } );
+    const { getRate, translate } = splide.Components.Move;
+
+    translate( -100 ); // Middle in the first slide
+    expect( getRate() ).toBe( 0.05 );
+
+    translate( -150 );
+    expect( getRate() ).toBe( 0.075 );
+
+    translate( -200 ); // On the first slide
+    expect( getRate() ).toBe( 0.1 );
+
+    translate( -250 );
+    expect( getRate() ).toBe( 0.125 );
+
+    splide.destroy();
+  } );
+
+  test( 'can return 1 when the current index is the end index.', () => {
+    const splide = init( { width: 200, speed: 0, perPage: 3 } );
+    const { getRate } = splide.Components.Move;
+    const end = splide.Components.Controller.getEnd();
+
+    splide.go( end );
+    expect( getRate() ).toBe( 1 );
+
+    splide.destroy();
+  } );
+
+  test( 'should work for fade carousels.', () => {
+    const splide = init( { width: 200, speed: 0, type: 'fade' } );
+    const { length } = splide;
+    const { getRate } = splide.Components.Move;
+
+    expect( getRate() ).toBe( 0 );
+
+    splide.go( 1 );
+    expect( getRate() ).toBe( splide.index / ( length - 1 ) );
+
+    splide.go( length - 1 );
+    expect( getRate() ).toBe( splide.index / ( length - 1 ) );
+
+    splide.destroy();
+  } );
+} );

+ 8 - 0
src/js/test/php/examples/drag-free.php

@@ -31,6 +31,11 @@ $settings = get_settings();
 
       splide.on( 'move', () => console.log( 'move' ) );
       splide.on( 'moved', () => console.log( 'moved' ) );
+      splide.on( 'dragging scrolling', () => {
+        const bar = document.querySelector( '.bar' );
+        bar.style.width = `${ splide.Components.Move.getRate() * 100 }%`;
+        splide.Components.Move.getRate()
+      } );
 
       splide.mount();
     } );
@@ -46,5 +51,8 @@ $settings = get_settings();
 
 <?php render( 'splide01', 10 ); ?>
 
+<div class="bar" style="height: 3px; background: #00bbff">
+</div>
+
 </body>
 </html>

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików