/cody/learning-zone/website-templates/enlive-corporate-free-html5-bootstrap-web-template/js/jquery.slitslider.js
/** * jquery.slitslider.js v1.1.0 * http://www.codrops.com * * Licensed under the MIT license. * http://www.opensource.org/licenses/mit-license.php *  * Copyright 2012, Codrops * http://www.codrops.com */
;( function( $, window, undefined ) {		'use strict';
	/*	* debouncedresize: special jQuery event that happens once after a window resize	*	* latest version and complete README available on Github:	* https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js	*	* Copyright 2011 @louis_remi	* Licensed under the MIT license.	*/	var $event = $.event,	$special,	resizeTimeout;
	$special = $event.special.debouncedresize = {		setup: function() {			$( this ).on( "resize", $special.handler );		},		teardown: function() {			$( this ).off( "resize", $special.handler );		},		handler: function( event, execAsap ) {			// Save the context			var context = this,				args = arguments,				dispatch = function() {					// set correct event type					event.type = "debouncedresize";					$event.dispatch.apply( context, args );				};
			if ( resizeTimeout ) {				clearTimeout( resizeTimeout );			}
			execAsap ?				dispatch() :				resizeTimeout = setTimeout( dispatch, $special.threshold );		},		threshold: 20	};
	// global	var $window = $( window ),		$document = $( document ),		Modernizr = window.Modernizr;
	$.Slitslider = function( options, element ) {				this.$elWrapper = $( element );		this._init( options );			};
	$.Slitslider.defaults = {		// transitions speed		speed : 800,		// if true the item's slices will also animate the opacity value		optOpacity : false,		// amount (%) to translate both slices - adjust as necessary		translateFactor : 230,		// maximum possible angle		maxAngle : 25,		// maximum possible scale		maxScale : 2,		// slideshow on / off		autoplay : false,		// keyboard navigation		keyboard : true,		// time between transitions		interval : 4000,		// callbacks		onBeforeChange : function( slide, idx ) { return false; },		onAfterChange : function( slide, idx ) { return false; }	};
	$.Slitslider.prototype = {
		_init : function( options ) {						// options			this.options = $.extend( true, {}, $.Slitslider.defaults, options );
			// https://github.com/twitter/bootstrap/issues/2870			this.transEndEventNames = {				'WebkitTransition' : 'webkitTransitionEnd',				'MozTransition' : 'transitionend',				'OTransition' : 'oTransitionEnd',				'msTransition' : 'MSTransitionEnd',				'transition' : 'transitionend'			};			this.transEndEventName = this.transEndEventNames[ Modernizr.prefixed( 'transition' ) ];			// suport for css 3d transforms and css transitions			this.support = Modernizr.csstransitions && Modernizr.csstransforms3d;			// the slider			this.$el = this.$elWrapper.children( '.sl-slider' );			// the slides			this.$slides = this.$el.children( '.sl-slide' ).hide();			// total slides			this.slidesCount = this.$slides.length;			// current slide			this.current = 0;			// control if it's animating			this.isAnimating = false;			// get container size			this._getSize();			// layout			this._layout();			// load some events			this._loadEvents();			// slideshow			if( this.options.autoplay ) {							this._startSlideshow();						}
		},		// gets the current container width & height		_getSize : function() {
			this.size = {				width : this.$elWrapper.outerWidth( true ),				height : this.$elWrapper.outerHeight( true )			};
		},		_layout : function() {						this.$slideWrapper = $( '<div class="sl-slides-wrapper" />' );						// 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( '<div class="sl-content-wrapper" />' )					  .wrapAll( '<div class="sl-content" />' );						} );						// 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;
			var self = this,				$currentSlide = this.$slides.eq( this.current );
			// if position is passed			if( pos !== undefined ) {
				this.current = pos;
			}			// if not check the boundaries			else if( dir === 'next' ) {
				this.current = this.current < this.slidesCount - 1 ? ++this.current : 0;
			}			else if( dir === 'prev' ) {
				this.current = this.current > 0 ? --this.current : this.slidesCount - 1;
			}
			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				} : {					marginLeft : -this.size.width / 2				},				// default slide's slices style				resetStyle = {					'transform' : 'translate(0%,0%) rotate(0deg) scale(1)',					opacity : 1 				},				// slice1 style				slice1Style	= config.orientation === 'horizontal' ? {					'transform' : 'translateY(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')'				} : {					'transform' : 'translateX(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')'				},				// slice2 style				slice2Style	= config.orientation === 'horizontal' ? {					'transform' : 'translateY(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')'				} : {					'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 = {				'transition' : 'all ' + this.options.speed + 'ms ease-in-out'			};
			// add the 2 slices and animate them			$movingSlide.css( 'z-index', this.slidesCount )						.find( 'div.sl-content-wrapper' )						.wrap( $( '<div class="sl-content-slice" />' ).css( transitionProp ) )						.parent()						.cond(							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', 							function() {																var slice = this;								this.css( slice2Style );								setTimeout( function() {
									$currentSlide.addClass( 'sl-trans-back-elems' );
									if( self.support ) {
										slice.css( resetStyle ).on( self.transEndEventName, function() {
											self._onEndNavigate( slice, $currentSlide, dir );
										} );
									}									else {
										self._onEndNavigate( slice, $currentSlide, dir );
									}
								}, 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 );
										} );
									}									else {
										self._onEndNavigate( slice, $currentSlide, dir );
									}
								}, 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,						arrow = {							left: 37,							up: 38,							right: 39,							down: 40						};
					switch (keyCode) {												case arrow.left :
							self._stopSlideshow();							self._navigate( 'prev' );							break;												case arrow.right :														self._stopSlideshow();							self._navigate( 'next' );							break;
					}
				} );
			}				},		_startSlideshow: function() {
			var self = this;
			this.slideshow = setTimeout( function() {
				self._navigate( 'next' );
				if ( self.options.autoplay ) {
					self._startSlideshow();
				}
			}, this.options.interval );
		},		_stopSlideshow: function() {
			if ( this.options.autoplay ) {
				clearTimeout( this.slideshow );				this.isPlaying = false;				this.options.autoplay = false;
			}
		},		_destroy : function( callback ) {						this.$el.off( '.slitslider' ).removeData( 'slitslider' );			$window.off( '.slitslider' );			$document.off( '.slitslider' );			this.$slides.each( function( i ) {
				var $slide = $( this ),					$content = $slide.find( 'div.sl-content' ).children();
				$content.appendTo( $slide );				$slide.children( 'div.sl-content-wrapper' ).remove();
			} );			this.$slides.unwrap( this.$slideWrapper ).hide();			this.$slides.eq( 0 ).show();			if( callback ) {
				callback.call();
			}
		},		// public methos: adds more slides to the slider		add : function( $slides, callback ) {
			this.$slides = this.$slides.add( $slides );
			var self = this;									$slides.each( function( i ) {
				var $slide = $( this ),					// vertical || horizontal					orientation = $slide.data( 'orientation' );
				$slide.hide().addClass( 'sl-slide-' + orientation )					  .children()					  .wrapAll( '<div class="sl-content-wrapper" />' )					  .wrapAll( '<div class="sl-content" />' )					  .end()					  .appendTo( self.$el.find( 'div.sl-slides-wrapper' ) );
			} );
			this._setSize();
			this.slidesCount = this.$slides.length;						if ( callback ) {
				callback.call( $items );
			}
		},		// public method: shows next slide		next : function() {
			this._stopSlideshow();			this._navigate( 'next' );
		},		// public method: shows previous slide		previous : function() {
			this._stopSlideshow();			this._navigate( 'prev' );
		},		// public method: goes to a specific slide		jump : function( pos ) {
			pos -= 1;
			if( pos === this.current || pos >= this.slidesCount || pos < 0 ) {
				return false;
			}
			this._stopSlideshow();			this._navigate( pos > this.current ? 'next' : 'prev', pos );
		},		// public method: starts the slideshow		// any call to next(), previous() or jump() will stop the slideshow		play : function() {
			if( !this.isPlaying ) {
				this.isPlaying = true;
				this._navigate( 'next' );				this.options.autoplay = true;				this._startSlideshow();
			}
		},		// public method: pauses the slideshow		pause : function() {
			if( this.isPlaying ) {
				this._stopSlideshow();
			}
		},		// public method: check if isAnimating is true		isActive : function() {
			return this.isAnimating;
		},		// publicc methos: destroys the slicebox instance		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 );