Explorar el Código

Snap the position to the close slide if necessary.

NaotoshiFujita hace 3 años
padre
commit
c2eaafbc35

+ 9 - 31
dist/js/splide.js

@@ -1372,14 +1372,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function sliderSize() {
-      var firstSlide = getAt(0);
-      var lastSlide = getAt(Slides.getLength(true) - 1);
-
-      if (firstSlide && lastSlide) {
-        return rect(lastSlide.slide)[resolve("right")] - rect(firstSlide.slide)[resolve("left")];
-      }
-
-      return 0;
+      return totalSize(Splide2.length - 1, true) - totalSize(-1, true);
     }
 
     function getGap() {
@@ -1423,35 +1416,20 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var looping;
     var waiting;
     var currPosition = 0;
-    var positionRate = 0;
+    var shouldSnap = true;
 
     function mount() {
       on([EVENT_RESIZE, EVENT_RESIZED, EVENT_UPDATED, EVENT_REFRESH], reposition, DEFAULT_EVENT_PRIORITY - 1);
     }
 
     function reposition() {
-      if (options.drag !== "free") {
+      if (shouldSnap || (shouldSnap = canSnap(getPosition()))) {
         jump(Splide2.index);
-      } else {
-        if (!options[resolve("fixedWidth")] && !options[resolve("autoWidth")]) {
-          translate(listSize() * positionRate);
-        }
-
-        if (exceededLimit(true)) {
-          translate(getLimit(true));
-        } else {
-          snap(SNAP_THRESHOLD);
-        }
       }
     }
 
-    function snap(threshold) {
-      var position = getPosition();
-      var index = toIndex(position);
-
-      if (abs(position - toPosition(index)) < threshold) {
-        jump(index);
-      }
+    function canSnap(position) {
+      return abs(position - toPosition(toIndex(position), true)) < SNAP_THRESHOLD;
     }
 
     function move(dest, index, prev) {
@@ -1490,8 +1468,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
     function translate(position) {
       currPosition = loop(position);
-      positionRate = currPosition / listSize();
-      Components2.Style.ruleBy(list, "transform", "translate" + resolve("X") + "(" + currPosition + "px)");
+      shouldSnap = canSnap(position);
+      Components2.Style.ruleBy(list, "transform", "translate" + resolve("X") + "(" + 100 * currPosition / listSize() + "%)");
     }
 
     function loop(position) {
@@ -1558,7 +1536,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
         return (listSize() - slideSize(index, true)) / 2;
       }
 
-      return (+focus || 0) * slideSize(index);
+      return +focus * slideSize(index) || 0;
     }
 
     function getLimit(max) {
@@ -2026,7 +2004,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var BOUNCE_DIFF_THRESHOLD = 10;
   var BOUNCE_DURATION = 600;
   var FRICTION_FACTOR = 0.6;
-  var BASE_VELOCITY = 1.2;
+  var BASE_VELOCITY = 1.5;
   var MIN_DURATION = 800;
 
   function Scroll(Splide2, Components2, options) {

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
dist/js/splide.js.map


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
dist/js/splide.min.js


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


+ 5 - 11
src/js/components/Layout/Layout.ts

@@ -183,7 +183,8 @@ export function Layout( Splide: Splide, Components: Components, options: Options
   }
 
   /**
-   * Returns the total width or height of slides from 0 to the specified index.
+   * Returns the total width or height of slides from the head of the slider to the specified index.
+   * This includes sizes of clones before the first slide.
    *
    * @param index      - A slide index. If omitted, uses the last index.
    * @param withoutGap - Optional. Determines whether to exclude the last gap or not.
@@ -203,19 +204,12 @@ export function Layout( Splide: Splide, Components: Components, options: Options
   }
 
   /**
-   * Returns the slider size without clones.
+   * Returns the slider size without clones before the first slide.
    *
-   * @return The slider size.
+   * @return The width or height of the slider without clones.
    */
   function sliderSize(): number {
-    const firstSlide = getAt( 0 );
-    const lastSlide  = getAt( Slides.getLength( true ) - 1 );
-
-    if ( firstSlide && lastSlide ) {
-      return rect( lastSlide.slide )[ resolve( 'right' ) ] - rect( firstSlide.slide )[ resolve( 'left' ) ];
-    }
-
-    return 0;
+    return totalSize( Splide.length - 1, true ) - totalSize( -1, true );
   }
 
   /**

+ 18 - 60
src/js/components/Move/Move.ts

@@ -67,9 +67,9 @@ export function Move( Splide: Splide, Components: Components, options: Options )
   let currPosition = 0;
 
   /**
-   * Keeps the rate of position to the slider width.
+   * Indicates whether the the slider should snap the position to the specific slide or not.
    */
-  let positionRate = 0;
+  let shouldSnap = true;
 
   /**
    * Called when the component is mounted.
@@ -83,33 +83,20 @@ export function Move( Splide: Splide, Components: Components, options: Options )
    * This must be called before the Slide component checks the visibility.
    */
   function reposition(): void {
-    if ( options.drag !== 'free' ) {
+    if ( shouldSnap || ( shouldSnap = canSnap( getPosition() ) ) ) {
       jump( Splide.index );
-    } else {
-      if ( ! options[ resolve( 'fixedWidth' ) ] && ! options[ resolve( 'autoWidth' ) ] ) {
-        translate( listSize() * positionRate );
-      }
-
-      if ( exceededLimit( true ) ) {
-        translate( getLimit( true ) );
-      } else {
-        snap( SNAP_THRESHOLD );
-      }
     }
   }
 
   /**
-   * Snaps the slider position to the closest slide if the difference between them is less than the threshold.
+   * Checks if the provided position is enough close to some slide to snap or not.
+   *
+   * @param position - A position to test.
    *
-   * @param threshold - The threshold value.
+   * @return `true` if found the slide to snap, or otherwise `false`.
    */
-  function snap( threshold: number ): void {
-    const position = getPosition();
-    const index    = toIndex( position );
-
-    if ( abs( position - toPosition( index ) ) < threshold ) {
-      jump( index );
-    }
+  function canSnap( position: number ): boolean {
+    return abs( position - toPosition( toIndex( position ), true ) ) < SNAP_THRESHOLD;
   }
 
   /**
@@ -123,7 +110,7 @@ export function Move( Splide: Splide, Components: Components, options: Options )
     if ( ! isBusy() ) {
       const position = getPosition();
 
-      looping = dest !== index;
+      looping = dest !== index; // todo
       waiting = options.waitForTransition;
 
       Splide.state.set( MOVING );
@@ -176,8 +163,13 @@ export function Move( Splide: Splide, Components: Components, options: Options )
    */
   function translate( position: number ): void {
     currPosition = loop( position );
-    positionRate = currPosition / listSize();
-    Components.Style.ruleBy( list, 'transform', `translate${ resolve( 'X' ) }(${ currPosition }px)` );
+    shouldSnap   = canSnap( position );
+
+    Components.Style.ruleBy(
+      list,
+      'transform',
+      `translate${ resolve( 'X' ) }(${ 100 * currPosition / listSize() }%)`
+    );
   }
 
   /**
@@ -285,7 +277,7 @@ export function Move( Splide: Splide, Components: Components, options: Options )
       return ( listSize() - slideSize( index, true ) ) / 2;
     }
 
-    return ( +focus || 0 ) * slideSize( index );
+    return +focus * slideSize( index ) || 0;
   }
 
   /**
@@ -323,37 +315,6 @@ export function Move( Splide: Splide, Components: Components, options: Options )
     return exceededMin || exceededMax;
   }
 
-  // /**
-  //  * Checks if the provided position exceeds the minimum limit or not.
-  //  *
-  //  * @param position - A position to test.
-  //  *
-  //  * @return `true` if the position exceeds the limit, or otherwise `false`.
-  //  */
-  // function isExceededMin( position: number ): boolean {
-  //   return orient( position ) < orient( getLimit( false ) );
-  // }
-  //
-  // /**
-  //  * Checks if the provided position exceeds the maximum limit or not.
-  //  *
-  //  * @param position - A position to test.
-  //  *
-  //  * @return `true` if the position exceeds the limit, or otherwise `false`.
-  //  */
-  // function isExceededMax( position: number ): boolean {
-  //   return orient( position ) > orient( getLimit( true ) );
-  // }
-  //
-  // /**
-  //  * Checks if the slider position exceeds borders or not.
-  //  *
-  //  * @return `true` if the position is over borders, or otherwise `false`.
-  //  */
-  // function isExceeded(): boolean {
-  //   return isExceededMin( currPosition ) || isExceededMax( currPosition );
-  // }
-
   return {
     mount,
     move,
@@ -366,8 +327,5 @@ export function Move( Splide: Splide, Components: Components, options: Options )
     getLimit,
     isBusy,
     exceededLimit,
-    // isExceededMin,
-    // isExceededMax,
-    // isExceeded,
   };
 }

+ 13 - 25
src/js/components/Move/test/general.test.ts

@@ -9,10 +9,10 @@ describe( 'Move', () => {
     const rule = findRuleBy( list );
 
     Move.jump( 2 );
-    expect( rule.style.transform ).toBe( 'translateX(-400px)' );
+    expect( rule.style.transform ).toBe( 'translateX(-200%)' );
 
     Move.jump( 4 );
-    expect( rule.style.transform ).toBe( 'translateX(-800px)' );
+    expect( rule.style.transform ).toBe( 'translateX(-400%)' );
 
     splide.destroy();
   } );
@@ -24,27 +24,30 @@ describe( 'Move', () => {
     const rule = findRuleBy( list );
 
     Move.translate( 100 );
-    expect( rule.style.transform ).toBe( 'translateX(100px)' );
+    expect( rule.style.transform ).toBe( 'translateX(50%)' );
 
     Move.translate( 500 );
-    expect( rule.style.transform ).toBe( 'translateX(500px)' );
+    expect( rule.style.transform ).toBe( 'translateX(250%)' );
 
     splide.destroy();
   } );
 
   test( 'can loop the slider if it exceeds bounds.', () => {
     // Note: All clones do not have dimensions.
-    const splide    = init( { type: 'loop', width: 200, height: 100 } );
-    const totalSize = 200 * splide.length;
+    const width     = 200;
+    const splide    = init( { type: 'loop', width, height: 100 } );
+    const totalSize = width * splide.length;
     const { Move }  = splide.Components;
     const { list }  = splide.Components.Elements;
     const rule = findRuleBy( list );
 
-    Move.translate( 50 );
-    expect( rule.style.transform ).toBe( `translateX(${ 50 - totalSize }px)` );
+    Move.translate( width );
+    expect( rule.style.transform ).toBe( `translateX(${ -100 * ( splide.length - 1 ) }%)` );
+
+    Move.translate( 0 );
 
-    Move.translate( - totalSize - 50 );
-    expect( rule.style.transform ).toBe( `translateX(-50px)` );
+    Move.translate( - totalSize );
+    expect( rule.style.transform ).toBe( `translateX(-100%)` ); // 1 slide
 
     splide.destroy();
   } );
@@ -109,21 +112,6 @@ describe( 'Move', () => {
     splide.destroy();
   } );
 
-  test( 'can loop the slider when the position exceeds bounds.', () => {
-    const width     = 200;
-    const splide    = init( { type: 'loop', width, height: 100 } );
-    const totalSize = width * splide.length;
-    const { Move }  = splide.Components;
-
-    Move.translate( 10 );
-    expect( Move.getPosition() ).toBe( - ( totalSize - 10 ) );
-
-    Move.translate( - totalSize - 10 );
-    expect( Move.getPosition() ).toBe( -10 );
-
-    splide.destroy();
-  } );
-
   test( 'can check if the slider can move or not.', () => {
     const splide   = init( { width: 200, height: 100 } );
     const { Move } = splide.Components;

+ 2 - 2
src/js/components/Move/test/move.test.ts

@@ -12,11 +12,11 @@ describe( 'Move#move()', () => {
 
     Move.move( 1, 1, -1 );
     fire( list, 'transitionend' );
-    expect( rule.style.transform ).toBe( 'translateX(-200px)' );
+    expect( rule.style.transform ).toBe( 'translateX(-100%)' );
 
     Move.move( 2, 2, -1 );
     fire( list, 'transitionend' );
-    expect( rule.style.transform ).toBe( 'translateX(-400px)' );
+    expect( rule.style.transform ).toBe( 'translateX(-200%)' );
   } );
 
   test( 'can change the state.', () => {

+ 1 - 1
src/js/components/Scroll/constants.ts

@@ -24,7 +24,7 @@ export const FRICTION_FACTOR = 0.6;
  *
  * @since 3.0.0
  */
-export const BASE_VELOCITY = 1.2;
+export const BASE_VELOCITY = 1.5;
 
 /**
  * The minimum duration of scroll.

+ 1 - 1
src/js/components/Style/test/general.test.ts

@@ -16,7 +16,7 @@ describe( 'Style', () => {
       } );
 
       expect( listRule ).not.toBeUndefined();
-      expect( listRule.style.transform ).toBe( 'translateX(0px)' );
+      expect( listRule.style.transform ).toBe( 'translateX(0%)' );
     }
 
     splide.destroy();

+ 3 - 2
src/js/test/php/examples/autoWidth.php

@@ -17,16 +17,17 @@ $settings = get_settings();
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide01 = new Splide( '#splide01', {
-        width     : 1000,
+        // width     : 1000,
         autoWidth : true,
         gap       : '1rem',
         trimSpace : 'move',
+        drag      : 'free',
       } );
 
       splide01.mount();
 
       var splide02 = new Splide( '#splide02', {
-        width     : 1000,
+        // width     : 1000,
         autoWidth : true,
         gap       : '1rem',
         focus     : 'center',

+ 2 - 2
src/js/test/php/examples/default.php

@@ -20,8 +20,8 @@ $settings = get_settings();
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
         type   : 'loop',
-        perPage: 1,
-        gap    : '1rem',
+        perPage: 2,
+        gap    : '1.5rem',
         drag   : 'free',
         height : 200,
       } );

+ 12 - 4
src/js/test/php/examples/fixedSize.php

@@ -1,5 +1,5 @@
 <?php
-require_once '../settings.php';
+require_once '../parts.php';
 require_once '../settings.php';
 
 $settings = get_settings();
@@ -18,19 +18,27 @@ $settings = get_settings();
 
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
-      var splide = new Splide( '#splide01', {
+      var splide01 = new Splide( '#splide01', {
         type       : 'loop',
         fixedWidth : 100,
         gap        : 10,
       } );
 
-      splide.mount();
+      splide01.mount();
+
+      var splide02 = new Splide( '#splide02', {
+        fixedWidth : 200,
+        gap        : '1rem',
+      } );
+
+      splide02.mount();
     } );
   </script>
 </head>
 <body>
 
-<?php render(); ?>
+<?php render( 'splide01' ); ?>
+<?php render( 'splide02' ); ?>
 
 </body>
 </html>

+ 17 - 6
src/js/test/utils/utils.ts

@@ -79,12 +79,15 @@ export function init( options: Options = {}, args: InitArgs = {} ): Splide {
   };
 
   list.getBoundingClientRect = (): DOMRect => {
-    return assign( {}, domRect, { width: +width, ...parseTransform( list as HTMLElement ) } );
+    return assign( {}, domRect, {
+      width: +width,
+      ...parseTransform( list as HTMLElement, +width, +height )
+    } );
   };
 
   slides.forEach( ( slide, index ) => {
     slide.getBoundingClientRect = (): DOMRect => {
-      const offsets = parseTransform( list as HTMLElement );
+      const offsets = parseTransform( list as HTMLElement, +width, +height );
 
       return assign( {}, domRect, {
         width : slideWidth,
@@ -107,11 +110,17 @@ export function init( options: Options = {}, args: InitArgs = {} ): Splide {
 /**
  * Converts translate values to positions.
  *
- * @param elm - An element to parse.
+ * @param elm        - An element to parse.
+ * @param baseWidth  - The width of the element.
+ * @param baseHeight - The height of the element.
  *
  * @return An object with left and top offsets.
  */
-export function parseTransform( elm: HTMLElement ): { left: number, top: number } {
+export function parseTransform(
+  elm: HTMLElement,
+  baseWidth: number,
+  baseHeight: number
+): { left: number, top: number } {
   const rule     = findRuleBy( elm );
   const position = { left: 0, top: 0 };
 
@@ -119,11 +128,13 @@ export function parseTransform( elm: HTMLElement ): { left: number, top: number
     const { transform } = rule.style;
 
     if ( transform.includes( 'translateX' ) ) {
-      position.left = parseFloat( transform.replace( /translateX\(|\)/g, '' ) ) || 0;
+      const percent = parseFloat( transform.replace( /translateX\(|\)/g, '' ) ) || 0;
+      position.left = baseWidth * percent / 100;
     }
 
     if ( transform.includes( 'translateY' ) ) {
-      position.top = parseFloat( transform.replace( /translateY\(|\)/g, '' ) ) || 0;
+      const percent = parseFloat( transform.replace( /translateY\(|\)/g, '' ) ) || 0;
+      position.top = baseHeight * percent / 100;
     }
   }
 

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio