From 1cbb7d06a2e3f361586a08a2356190edbef73e82 Mon Sep 17 00:00:00 2001 From: MAXakaWIZARD Date: Sun, 23 Nov 2014 23:21:53 +0200 Subject: [PATCH 1/4] add bower.json --- bower.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 bower.json diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..79dec01 --- /dev/null +++ b/bower.json @@ -0,0 +1,16 @@ +{ + "name": "SlitSlider", + "version": "1.1.0", + "main": "js/jquery.slitslider.js", + "license": "MIT", + "ignore": [ + + ], + "keywords": [ + "slider" + ], + "dependencies": { + "jquery": ">=1.5", + "modernizr": "2.*" + } +} \ No newline at end of file From 2f3b22fc78dcfb5674b4a0f9559714b3baae7e82 Mon Sep 17 00:00:00 2001 From: Franck Bossy Date: Wed, 26 Nov 2014 11:08:08 +0100 Subject: [PATCH 2/4] replace nth-child pseudo selector with nth-of-type as ios8 Safari fails on nth-child --- css/style.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/css/style.css b/css/style.css index 46fc764..7df6ddf 100755 --- a/css/style.css +++ b/css/style.css @@ -22,7 +22,7 @@ height: 100%; top: 0; left: 0; -} +} .sl-slide { z-index: 1; @@ -63,7 +63,7 @@ padding: 200px 200px 0px 200px; } -.sl-slide-horizontal .sl-content-slice:nth-child(2) { +.sl-slide-horizontal .sl-content-slice:nth-of-type(2) { top: 50%; padding: 0px 200px 200px 200px; } @@ -86,7 +86,7 @@ padding: 200px 0px 200px 200px; } -.sl-slide-vertical .sl-content-slice:nth-child(2) { +.sl-slide-vertical .sl-content-slice:nth-of-type(2) { left: 50%; padding: 200px 200px 200px 0px; } From 2a91f5145630c2543290cd66146e845b08bc50ca Mon Sep 17 00:00:00 2001 From: Jonathan Mifsud Date: Sun, 30 Nov 2014 17:20:41 +0100 Subject: [PATCH 3/4] Fix the Pause functionality Currently the pause only works if an animation is already going on. One would usually use the pause function to stop the slider from continuing to autoplay. --- js/jquery.slitslider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/jquery.slitslider.js b/js/jquery.slitslider.js index c1f0f3c..9aeb578 100755 --- a/js/jquery.slitslider.js +++ b/js/jquery.slitslider.js @@ -588,7 +588,7 @@ // public method: pauses the slideshow pause : function() { - if( this.isPlaying ) { + if( this.isPlaying || this.options.autoplay) { this._stopSlideshow(); From d9f563021290eb5765b60e99e3a5207699305120 Mon Sep 17 00:00:00 2001 From: Franck Bossy Date: Mon, 15 Dec 2014 15:44:09 +0100 Subject: [PATCH 4/4] add slitsliderEmulateTransitionEnd, ensure callback is called when transitionend event is not fired see http://blog.alexmaccaw.com/css-transitions --- js/jquery.slitslider.js | 219 ++++++++++++++++++++++------------------ 1 file changed, 118 insertions(+), 101 deletions(-) diff --git a/js/jquery.slitslider.js b/js/jquery.slitslider.js index 9aeb578..d5835cf 100755 --- a/js/jquery.slitslider.js +++ b/js/jquery.slitslider.js @@ -4,13 +4,30 @@ * * Licensed under the MIT license. * http://www.opensource.org/licenses/mit-license.php - * + * * Copyright 2012, Codrops * http://www.codrops.com */ +$.fn.slitsliderEmulateTransitionEnd = function (duration) { + var transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd', + 'MozTransition' : 'transitionend', + 'OTransition' : 'oTransitionEnd', + 'msTransition' : 'MSTransitionEnd', + 'transition' : 'transitionend' + }, + transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ]; + + var called = false, $el = this + $(this).one(transEndEventName, function () { called = true }) + + var callback = function () { if (!called) $($el).trigger(transEndEventName) } + setTimeout(callback, duration) + return this +} ;( function( $, window, undefined ) { - + 'use strict'; /* @@ -60,10 +77,10 @@ Modernizr = window.Modernizr; $.Slitslider = function( options, element ) { - + this.$elWrapper = $( element ); this._init( options ); - + }; $.Slitslider.defaults = { @@ -91,7 +108,7 @@ $.Slitslider.prototype = { _init : function( options ) { - + // options this.options = $.extend( true, {}, $.Slitslider.defaults, options ); @@ -124,9 +141,9 @@ this._loadEvents(); // slideshow if( this.options.autoplay ) { - + this._startSlideshow(); - + } }, @@ -140,35 +157,35 @@ }, _layout : function() { - + this.$slideWrapper = $( '
' ); - + // wrap the slides this.$slides.wrapAll( this.$slideWrapper ).each( function( i ) { - + var $slide = $( this ), // vertical || horizontal orientation = $slide.data( 'orientation' ); - + $slide.addClass( 'sl-slide-' + orientation ) .children() .wrapAll( '
' ) .wrapAll( '
' ); - + } ); - + // set the right size of the slider/slides for the current window size this._setSize(); // show first slide this.$slides.eq( this.current ).show(); - + }, _navigate : function( dir, pos ) { - + if( this.isAnimating || this.slidesCount < 2 ) { - + return false; - + } this.isAnimating = true; @@ -195,24 +212,24 @@ } this.options.onBeforeChange( $currentSlide, this.current ); - + // next slide to be shown var $nextSlide = this.$slides.eq( this.current ), // the slide we want to cut and animate $movingSlide = ( dir === 'next' ) ? $currentSlide : $nextSlide, - + // the following are the data attrs set for each slide configData = $movingSlide.data(), config = {}; - + config.orientation = configData.orientation || 'horizontal', config.slice1angle = configData.slice1Rotation || 0, config.slice1scale = configData.slice1Scale || 1, config.slice2angle = configData.slice2Rotation || 0, config.slice2scale = configData.slice2Scale || 1; - + this._validateValues( config ); - + var cssStyle = config.orientation === 'horizontal' ? { marginTop : -this.size.height / 2 } : { @@ -221,7 +238,7 @@ // default slide's slices style resetStyle = { 'transform' : 'translate(0%,0%) rotate(0deg) scale(1)', - opacity : 1 + opacity : 1 }, // slice1 style slice1Style = config.orientation === 'horizontal' ? { @@ -235,19 +252,19 @@ } : { 'transform' : 'translateX(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')' }; - + if( this.options.optOpacity ) { - + slice1Style.opacity = 0; slice2Style.opacity = 0; - + } - + // we are adding the classes sl-trans-elems and sl-trans-back-elems to the slide that is either coming "next" // or going "prev" according to the direction. // the idea is to make it more interesting by giving some animations to the respective slide's elements //( dir === 'next' ) ? $nextSlide.addClass( 'sl-trans-elems' ) : $currentSlide.addClass( 'sl-trans-back-elems' ); - + $currentSlide.removeClass( 'sl-trans-elems' ); var transitionProp = { @@ -260,35 +277,35 @@ .wrap( $( '
' ).css( transitionProp ) ) .parent() .cond( - dir === 'prev', + dir === 'prev', function() { - + var slice = this; this.css( slice1Style ); setTimeout( function() { - + slice.css( resetStyle ); }, 50 ); - - }, + + }, function() { - + var slice = this; setTimeout( function() { - + slice.css( slice1Style ); }, 50 ); - + } ) .clone() .appendTo( $movingSlide ) .cond( - dir === 'prev', + dir === 'prev', function() { - + var slice = this; this.css( slice2Style ); setTimeout( function() { @@ -301,7 +318,7 @@ self._onEndNavigate( slice, $currentSlide, dir ); - } ); + } ).slitsliderEmulateTransitionEnd( self.options.speed + 100); } else { @@ -311,22 +328,22 @@ } }, 50 ); - + }, function() { - + var slice = this; setTimeout( function() { $nextSlide.addClass( 'sl-trans-elems' ); - + if( self.support ) { slice.css( slice2Style ).on( self.transEndEventName, function() { self._onEndNavigate( slice, $currentSlide, dir ); - } ); + } ).slitsliderEmulateTransitionEnd( self.options.speed + 100); } else { @@ -336,95 +353,95 @@ } }, 50 ); - + } ) .find( 'div.sl-content-wrapper' ) .css( cssStyle ); - + $nextSlide.show(); - + }, _validateValues : function( config ) { - + // OK, so we are restricting the angles and scale values here. // This is to avoid the slices wrong sides to be shown. // you can adjust these values as you wish but make sure you also ajust the // paddings of the slides and also the options.translateFactor value and scale data attrs if( config.slice1angle > this.options.maxAngle || config.slice1angle < -this.options.maxAngle ) { - + config.slice1angle = this.options.maxAngle; - + } if( config.slice2angle > this.options.maxAngle || config.slice2angle < -this.options.maxAngle ) { - + config.slice2angle = this.options.maxAngle; - + } if( config.slice1scale > this.options.maxScale || config.slice1scale <= 0 ) { - + config.slice1scale = this.options.maxScale; - + } if( config.slice2scale > this.options.maxScale || config.slice2scale <= 0 ) { - + config.slice2scale = this.options.maxScale; - + } if( config.orientation !== 'vertical' && config.orientation !== 'horizontal' ) { - + config.orientation = 'horizontal' - + } - + }, _onEndNavigate : function( $slice, $oldSlide, dir ) { - + // reset previous slide's style after next slide is shown var $slide = $slice.parent(), removeClasses = 'sl-trans-elems sl-trans-back-elems'; - + // remove second slide's slice $slice.remove(); // unwrap.. $slide.css( 'z-index', 1 ) .find( 'div.sl-content-wrapper' ) .unwrap(); - + // hide previous current slide $oldSlide.hide().removeClass( removeClasses ); $slide.removeClass( removeClasses ); // now we can navigate again.. this.isAnimating = false; this.options.onAfterChange( $slide, this.current ); - + }, _setSize : function() { - + // the slider and content wrappers will have the window's width and height var cssStyle = { width : this.size.width, height : this.size.height }; - + this.$el.css( cssStyle ).find( 'div.sl-content-wrapper' ).css( cssStyle ); - + }, _loadEvents : function() { - + var self = this; - + $window.on( 'debouncedresize.slitslider', function( event ) { - + // update size values self._getSize(); // set the sizes again self._setSize(); - + } ); if ( this.options.keyboard ) { - + $document.on( 'keydown.slitslider', function(e) { var keyCode = e.keyCode || e.which, @@ -436,15 +453,15 @@ }; switch (keyCode) { - + case arrow.left : self._stopSlideshow(); self._navigate( 'prev' ); break; - + case arrow.right : - + self._stopSlideshow(); self._navigate( 'next' ); break; @@ -454,7 +471,7 @@ } ); } - + }, _startSlideshow: function() { @@ -485,7 +502,7 @@ }, _destroy : function( callback ) { - + this.$el.off( '.slitslider' ).removeData( 'slitslider' ); $window.off( '.slitslider' ); $document.off( '.slitslider' ); @@ -513,8 +530,8 @@ this.$slides = this.$slides.add( $slides ); var self = this; - - + + $slides.each( function( i ) { var $slide = $( this ), @@ -533,7 +550,7 @@ this._setSize(); this.slidesCount = this.$slides.length; - + if ( callback ) { callback.call( $items ); @@ -605,72 +622,72 @@ destroy : function( callback ) { this._destroy( callback ); - + } }; - + var logError = function( message ) { if ( window.console ) { window.console.error( message ); - + } }; - + $.fn.slitslider = function( options ) { var self = $.data( this, 'slitslider' ); - + if ( typeof options === 'string' ) { - + var args = Array.prototype.slice.call( arguments, 1 ); - + this.each(function() { - + if ( !self ) { logError( "cannot call methods on slitslider prior to initialization; " + "attempted to call method '" + options + "'" ); return; - + } - + if ( !$.isFunction( self[options] ) || options.charAt(0) === "_" ) { logError( "no such method '" + options + "' for slitslider self" ); return; - + } - + self[ options ].apply( self, args ); - + }); - - } + + } else { - + this.each(function() { - + if ( self ) { self._init(); - + } else { self = $.data( this, 'slitslider', new $.Slitslider( options, this ) ); - + } }); - + } - + return self; - + }; - + } )( jQuery, window );