瀏覽代碼

Add a function to convert CSS relative units to pixel.

NaotoshiFujita 5 年之前
父節點
當前提交
74a10f0be5

文件差異過大導致無法顯示
+ 1 - 1
dist/js/splide.min.js


二進制
dist/js/splide.min.js.gz


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@splidejs/splide",
   "name": "@splidejs/splide",
-  "version": "1.0.13",
+  "version": "1.0.14",
   "description": "Splide is a lightweight and powerful slider without any dependencies.",
   "description": "Splide is a lightweight and powerful slider without any dependencies.",
   "author": "Naotoshi Fujita",
   "author": "Naotoshi Fujita",
   "license": "MIT",
   "license": "MIT",

+ 15 - 5
src/js/components/layout/index.js

@@ -96,6 +96,15 @@ export default ( Splide, Components ) => {
 			return Resolver.width;
 			return Resolver.width;
 		},
 		},
 
 
+		/**
+		 * Return slider height without padding.
+		 *
+		 * @return {number}
+		 */
+		get height() {
+			return Resolver.height;
+		},
+
 		/**
 		/**
 		 * Return list width.
 		 * Return list width.
 		 *
 		 *
@@ -121,7 +130,7 @@ export default ( Splide, Components ) => {
 		 * @return {number} - Current slide width including gap size.
 		 * @return {number} - Current slide width including gap size.
 		 */
 		 */
 		get slideWidth() {
 		get slideWidth() {
-			return Resolver.getSlideWidth( true );
+			return Resolver.slideWidth;
 		},
 		},
 
 
 		/**
 		/**
@@ -130,7 +139,7 @@ export default ( Splide, Components ) => {
 		 * @return {number} - Computed slide height.
 		 * @return {number} - Computed slide height.
 		 */
 		 */
 		get slideHeight() {
 		get slideHeight() {
-			return Resolver.getSlideHeight( true );
+			return Resolver.slideHeight;
 		},
 		},
 
 
 		/**
 		/**
@@ -195,9 +204,10 @@ export default ( Splide, Components ) => {
 	 */
 	 */
 	function resize() {
 	function resize() {
 		applyStyle( list, { width: unit( Layout.listWidth ), height: unit( Layout.listHeight ) } );
 		applyStyle( list, { width: unit( Layout.listWidth ), height: unit( Layout.listHeight ) } );
+		applyStyle( Components.Elements.track, { height: unit( Layout.height ) } );
 
 
-		const slideWidth  = unit( Resolver.getSlideWidth( false ) );
-		const slideHeight = unit( Resolver.getSlideHeight( false ) );
+		const slideWidth  = unit( Resolver.slideWidth );
+		const slideHeight = unit( Resolver.slideHeight );
 
 
 		for ( let i in Slides ) {
 		for ( let i in Slides ) {
 			const { slide, container } = Slides[ i ];
 			const { slide, container } = Slides[ i ];
@@ -214,7 +224,7 @@ export default ( Splide, Components ) => {
 		const options = Splide.options;
 		const options = Splide.options;
 
 
 		if ( options.fixedWidth ) {
 		if ( options.fixedWidth ) {
-			const perPage = Math.floor( ( Layout.width + Resolver.gap ) / Layout.slideWidth ) || 1;
+			const perPage = Math.floor( ( Layout.width + Resolver.gap ) / ( Layout.slideWidth + Resolver.gap ) ) || 1;
 
 
 			if ( options.perPage !== perPage ) {
 			if ( options.perPage !== perPage ) {
 				Splide.options = { perPage };
 				Splide.options = { perPage };

+ 41 - 59
src/js/components/layout/resolvers/horizontal.js

@@ -6,7 +6,7 @@
  */
  */
 
 
 import { applyStyle } from "../../../utils/dom";
 import { applyStyle } from "../../../utils/dom";
-import { unit } from "../../../utils/utils";
+import { unit, toPixel } from "../../../utils/utils";
 import { RTL } from '../../../constants/directions';
 import { RTL } from '../../../constants/directions';
 
 
 
 
@@ -34,20 +34,6 @@ export default ( Splide, Components, options ) => {
 	 */
 	 */
 	const track = Elements.track;
 	const track = Elements.track;
 
 
-	/**
-	 * Keep the fixed width if available.
-	 *
-	 * @type {number}
-	 */
-	let fixedWidth;
-
-	/**
-	 * Keep the fixed height if available.
-	 *
-	 * @type {number}
-	 */
-	let fixedHeight;
-
 	return {
 	return {
 		/**
 		/**
 		 * Margin property name.
 		 * Margin property name.
@@ -56,6 +42,13 @@ export default ( Splide, Components, options ) => {
 		 */
 		 */
 		marginProp: options.direction === RTL ? 'marginLeft' : 'marginRight',
 		marginProp: options.direction === RTL ? 'marginLeft' : 'marginRight',
 
 
+		/**
+		 * Always 0 because the height will be determined by inner contents.
+		 *
+		 * @type {number}
+		 */
+		height: 0,
+
 		/**
 		/**
 		 * Always 0 because the height will be determined by inner contents.
 		 * Always 0 because the height will be determined by inner contents.
 		 *
 		 *
@@ -68,71 +61,60 @@ export default ( Splide, Components, options ) => {
 		 */
 		 */
 		init() {
 		init() {
 			const { left = 0, right = 0 } = options.padding;
 			const { left = 0, right = 0 } = options.padding;
-
 			applyStyle( track, { paddingLeft : unit( left ), paddingRight: unit( right ) } );
 			applyStyle( track, { paddingLeft : unit( left ), paddingRight: unit( right ) } );
-
-			const firstSlide = Elements.slides[ 0 ];
-			const width      = options.fixedWidth;
-			const height     = options.height || options.fixedHeight;
-			const position   = firstSlide.style.position;
-
-			applyStyle( firstSlide, { position: 'absolute' } );
-
-			if ( width ) {
-				applyStyle( firstSlide, { width: unit( width ) } );
-				fixedWidth = parseFloat( getComputedStyle( firstSlide ).width );
-			}
-
-			if ( height ) {
-				applyStyle( firstSlide, { height: unit( height ) } );
-				fixedHeight = parseFloat( getComputedStyle( firstSlide ).height );
-			}
-
-			// Restore the position.
-			applyStyle( firstSlide, { position } );
 		},
 		},
 
 
 		/**
 		/**
-		 * Return the slide width with/without a gap space.
-		 *
-		 * @param {boolean} includeGap - Whether to include a gap space or not.
+		 * Return slider width without padding.
 		 *
 		 *
-		 * @return {number} - Slide width in px.
+		 * @return {number} - Current slider width.
 		 */
 		 */
-		getSlideWidth( includeGap ) {
-			if ( fixedWidth ) {
-				return includeGap ? fixedWidth + this.gap : fixedWidth;
-			}
-
-			const width = ( this.width + this.gap ) / options.perPage;
-			return includeGap ? width : width - this.gap;
+		get width() {
+			return track.clientWidth - this.padding.left - this.padding.right;
 		},
 		},
 
 
 		/**
 		/**
-		 * Return the slide height.
+		 * Return slide height without padding.
+		 *
+		 * @return {number} - Slider height.
+		 */
+		// get height() {
+		// 	const height = options.height || options.fixedHeight || this.width * options.heightRatio;
+		// 	return toPixel( Splide.root, height );
+		// },
+
+		/**
+		 * Return list width.
 		 *
 		 *
-		 * @return {number} - Slide height in px.
+		 * @return {number} - Current list width.
 		 */
 		 */
-		getSlideHeight() {
-			return fixedHeight || this.width * options.heightRatio || 0;
+		get listWidth() {
+			return ( this.slideWidth + this.gap ) * Components.Slides.total;
 		},
 		},
 
 
 		/**
 		/**
-		 * Return slider width without padding.
+		 * Return the slide width in px.
 		 *
 		 *
-		 * @return {number} - Current slide width.
+		 * @return {number} - The slide width.
 		 */
 		 */
-		get width() {
-			return track.clientWidth - this.padding.left - this.padding.right;
+		get slideWidth() {
+			let width = options.fixedWidth;
+
+			if ( ! width ) {
+				width = ( ( this.width + this.gap ) / options.perPage ) - this.gap;
+			}
+
+			return toPixel( Splide.root, width );
 		},
 		},
 
 
 		/**
 		/**
-		 * Return list width.
+		 * Return the slide height in px.
 		 *
 		 *
-		 * @return {number} - Current list width.
+		 * @return {number} - The slide height.
 		 */
 		 */
-		get listWidth() {
-			return this.getSlideWidth( true ) * Components.Slides.total;
+		get slideHeight() {
+			const height = options.height || options.fixedHeight || this.width * options.heightRatio;
+			return toPixel( Splide.root, height );
 		},
 		},
 
 
 		/**
 		/**

+ 37 - 70
src/js/components/layout/resolvers/vertical.js

@@ -4,8 +4,9 @@
  * @author    Naotoshi Fujita
  * @author    Naotoshi Fujita
  * @copyright Naotoshi Fujita. All rights reserved.
  * @copyright Naotoshi Fujita. All rights reserved.
  */
  */
+
 import { applyStyle } from "../../../utils/dom";
 import { applyStyle } from "../../../utils/dom";
-import { unit } from "../../../utils/utils";
+import { toPixel, unit } from "../../../utils/utils";
 import { exist } from "../../../utils/error";
 import { exist } from "../../../utils/error";
 
 
 
 
@@ -33,27 +34,6 @@ export default ( Splide, Components, options ) => {
 	 */
 	 */
 	const track = Elements.track;
 	const track = Elements.track;
 
 
-	/**
-	 * Keep the fixed width if available.
-	 *
-	 * @type {number}
-	 */
-	let fixedWidth;
-
-	/**
-	 * Keep the fixed height if available.
-	 *
-	 * @type {number}
-	 */
-	let fixedHeight;
-
-	/**
-	 * Keep the temporary listHeight.
-	 *
-	 * @type {number}
-	 */
-	let listHeight;
-
 	return {
 	return {
 		/**
 		/**
 		 * Margin property name.
 		 * Margin property name.
@@ -67,62 +47,27 @@ export default ( Splide, Components, options ) => {
 		 */
 		 */
 		init() {
 		init() {
 			const { top = 0, bottom = 0 } = options.padding;
 			const { top = 0, bottom = 0 } = options.padding;
-
 			applyStyle( track, { paddingTop: unit( top ), paddingBottom: unit( bottom ) } );
 			applyStyle( track, { paddingTop: unit( top ), paddingBottom: unit( bottom ) } );
-
-			const firstSlide = Elements.slides[ 0 ];
-			const position   = firstSlide.style.position;
-			const { fixedWidth: fixedW, fixedHeight: fixedH, height } = options;
-
-			applyStyle( firstSlide, { position: 'absolute' } );
-
-			if ( fixedW ) {
-				applyStyle( firstSlide, { width: unit( fixedW ) } );
-				fixedWidth = parseFloat( getComputedStyle( firstSlide ).width );
-			}
-
-			if ( fixedH ) {
-				applyStyle( firstSlide, { height: unit( fixedH ) } );
-				fixedHeight = parseFloat( getComputedStyle( firstSlide ).height );
-			}
-
-			applyStyle( firstSlide, { position } );
-
-			if ( height ) {
-				const list = Elements.list;
-				applyStyle( list, { height: unit( height ) } );
-				listHeight = parseFloat( getComputedStyle( list ).height );
-			}
-		},
-
-		/**
-		 * Return the slide width with/without a gap space.
-		 *
-		 * @return {number} - Slide width in px.
-		 */
-		getSlideWidth() {
-			return fixedWidth || this.width;
 		},
 		},
 
 
 		/**
 		/**
-		 * Return the slide height with/without a gap space.
-		 *
-		 * @param {boolean} includeGap - Whether to include a gap space or not.
+		 * Return slider width without padding.
 		 *
 		 *
-		 * @return {number} - Slide height in px.
+		 * @return {number} - Current slider width.
 		 */
 		 */
-		getSlideHeight( includeGap ) {
-			const height = fixedHeight || ( this.listHeight + this.gap ) / options.perPage;
-			return includeGap ? height : height - this.gap;
+		get width() {
+			return track.clientWidth;
 		},
 		},
 
 
 		/**
 		/**
-		 * Return slider width without padding.
+		 * Return slide height without padding.
 		 *
 		 *
-		 * @return {number} - Current slide width.
+		 * @return {number} - Slider height.
 		 */
 		 */
-		get width() {
-			return track.clientWidth;
+		get height() {
+			const height = options.height || this.width * options.heightRatio;
+			exist( height, '"height" or "heightRatio" must be given in TTB mode.' );
+			return toPixel( Splide.root, height );
 		},
 		},
 
 
 		/**
 		/**
@@ -140,9 +85,31 @@ export default ( Splide, Components, options ) => {
 		 * @return {number} - Current list height.
 		 * @return {number} - Current list height.
 		 */
 		 */
 		get listHeight() {
 		get listHeight() {
-			const height = listHeight || this.width * options.heightRatio;
-			exist( height, '"height" or "heightRatio" must be given in TTB mode.' );
-			return height - this.padding.top - this.padding.bottom;
+			return ( this.slideHeight + this.gap ) * Components.Slides.total;
+		},
+
+		/**
+		 * Return the slide width in px.
+		 *
+		 * @return {number} - The slide width.
+		 */
+		get slideWidth() {
+			return toPixel( Splide.root, options.fixedWidth || this.width );
+		},
+
+		/**
+		 * Return the slide height in px.
+		 *
+		 * @return {number} - The slide height.
+		 */
+		get slideHeight() {
+			let height = options.fixedHeight;
+
+			if ( ! height ) {
+				height = ( this.height + this.gap ) / options.perPage - this.gap;
+			}
+
+			return toPixel( Splide.root, height );
 		},
 		},
 
 
 		/**
 		/**

+ 5 - 5
src/js/components/track/resolvers/horizontal.js

@@ -44,7 +44,7 @@ export default ( Splide, Components ) => {
 		 * @return {Object} - Calculated position.
 		 * @return {Object} - Calculated position.
 		 */
 		 */
 		toPosition( index ) {
 		toPosition( index ) {
-			return this.sign * ( index * Layout.slideWidth + this.offset )
+			return this.sign * ( index * ( Layout.slideWidth + Layout.gap ) + this.offset )
 		},
 		},
 
 
 		/**
 		/**
@@ -53,7 +53,7 @@ export default ( Splide, Components ) => {
 		 * @return {number} - The closest slide position.
 		 * @return {number} - The closest slide position.
 		 */
 		 */
 		toIndex( position ) {
 		toIndex( position ) {
-			return Math.round( ( this.sign * position - this.offset ) / Layout.slideWidth );
+			return Math.round( ( this.sign * position - this.offset ) / ( Layout.slideWidth + Layout.gap ) );
 		},
 		},
 
 
 		/**
 		/**
@@ -89,12 +89,12 @@ export default ( Splide, Components ) => {
 			let focusOffset;
 			let focusOffset;
 
 
 			if ( focus === 'center' ) {
 			if ( focus === 'center' ) {
-				focusOffset = ( width - slideWidth + gap ) / 2;
+				focusOffset = ( width - slideWidth ) / 2 + gap;
 			} else {
 			} else {
-				focusOffset = ( parseInt( focus ) || 0 ) * slideWidth;
+				focusOffset = ( parseInt( focus ) || 0 ) * ( slideWidth + gap );
 			}
 			}
 
 
-			return slideWidth * Components.Clones.length / 2 - focusOffset;
+			return ( slideWidth + gap ) * Components.Clones.length / 2 - focusOffset;
 		},
 		},
 	};
 	};
 }
 }

+ 6 - 6
src/js/components/track/resolvers/vertical.js

@@ -44,7 +44,7 @@ export default ( Splide, Components ) => {
 		 * @return {Object} - Calculated position.
 		 * @return {Object} - Calculated position.
 		 */
 		 */
 		toPosition( index ) {
 		toPosition( index ) {
-			return - ( index * Layout.slideHeight + this.offset )
+			return - ( index * ( Layout.slideHeight + Layout.gap ) + this.offset )
 		},
 		},
 
 
 		/**
 		/**
@@ -53,7 +53,7 @@ export default ( Splide, Components ) => {
 		 * @return {number} - The closest slide index.
 		 * @return {number} - The closest slide index.
 		 */
 		 */
 		toIndex( position ) {
 		toIndex( position ) {
-			return Math.round( - ( position + this.offset ) / Layout.slideHeight );
+			return Math.round( - ( position + this.offset ) / ( Layout.slideHeight + Layout.gap ) );
 		},
 		},
 
 
 		/**
 		/**
@@ -64,7 +64,7 @@ export default ( Splide, Components ) => {
 		 * @return {number} - Trimmed position.
 		 * @return {number} - Trimmed position.
 		 */
 		 */
 		trim( position ) {
 		trim( position ) {
-			const edge = -( Layout.slideHeight * ( Splide.length - Splide.options.perPage ) );
+			const edge = -( Layout.listHeight - ( Layout.height + Layout.gap ) );
 			return between( position, edge, 0 );
 			return between( position, edge, 0 );
 		},
 		},
 
 
@@ -80,12 +80,12 @@ export default ( Splide, Components ) => {
 			let focusOffset;
 			let focusOffset;
 
 
 			if ( focus === 'center' ) {
 			if ( focus === 'center' ) {
-				focusOffset = ( listHeight - slideHeight + gap ) / 2;
+				focusOffset = ( listHeight - slideHeight ) / 2 + gap;
 			} else {
 			} else {
-				focusOffset = ( parseInt( focus ) || 0 ) * slideHeight;
+				focusOffset = ( parseInt( focus ) || 0 ) * ( slideHeight + gap );
 			}
 			}
 
 
-			return slideHeight * Components.Clones.length / 2 - focusOffset;
+			return ( slideHeight + gap ) * Components.Clones.length / 2 - focusOffset;
 		},
 		},
 	};
 	};
 }  
 }  

+ 31 - 0
src/js/utils/utils.js

@@ -5,6 +5,8 @@
  * @copyright Naotoshi Fujita. All rights reserved.
  * @copyright Naotoshi Fujita. All rights reserved.
  */
  */
 
 
+import { create, applyStyle } from "./dom";
+
 
 
 /**
 /**
  * Check if the given value is between min and max.
  * Check if the given value is between min and max.
@@ -51,4 +53,33 @@ export function unit( value ) {
 	}
 	}
 
 
 	return '';
 	return '';
+}
+
+/**
+ * Convert the given value to pixel.
+ *
+ * @param {Element}       root  - Root element where a dummy div is appended.
+ * @param {string|number} value - CSS value to be converted, such as 10rem.
+ *
+ * @return {number} - Pixel.
+ */
+export function toPixel( root, value ) {
+	if ( typeof value === 'number' ) {
+		return value;
+	}
+
+	const div = create( 'div', {} );
+
+	applyStyle( div, {
+		position: 'absolute',
+		width: value,
+	} );
+
+	root.appendChild( div );
+
+	const px = div.clientWidth;
+
+	root.removeChild( div );
+
+	return px;
 }
 }

+ 0 - 5
tests/functionality/layout.test.js

@@ -20,11 +20,6 @@ describe( 'The Layout ', () => {
 
 
 		const slide = splide.Components.Elements.slides[ 0 ];
 		const slide = splide.Components.Elements.slides[ 0 ];
 		expect( slide.style.height ).toBe( '400px' );
 		expect( slide.style.height ).toBe( '400px' );
-
-		global.innerHeight = 100;
-
-		splide.options = { height: '10vh' };
-		expect( slide.style.height ).toBe( 100 / 10 + 'px' ); // window height / 10.
 	} );
 	} );
 
 
 	test( 'should apply height to a slide element when a "fixedHeight" option is provided.', () => {
 	test( 'should apply height to a slide element when a "fixedHeight" option is provided.', () => {

部分文件因文件數量過多而無法顯示