1/** 2 * jquery.slitslider.js v1.1.0 3 * http://www.codrops.com 4 * 5 * Licensed under the MIT license. 6 * http://www.opensource.org/licenses/mit-license.php 7 * 8 * Copyright 2012, Codrops 9 * http://www.codrops.com 10 */ 11;( function( $, window, undefined ) { 12 'use strict'; 13 /* 14 * debouncedresize: special jQuery event that happens once after a window resize 15 * 16 * latest version and complete README available on Github: 17 * https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js 18 * 19 * Copyright 2011 @louis_remi 20 * Licensed under the MIT license. 21 */ 22 var $event = $.event, 23 $special, 24 resizeTimeout; 25 $special = $event.special.debouncedresize = { 26 setup: function() { 27 $( this ).on( "resize", $special.handler ); 28 }, 29 teardown: function() { 30 $( this ).off( "resize", $special.handler ); 31 }, 32 handler: function( event, execAsap ) { 33 // Save the context 34 var context = this, 35 args = arguments, 36 dispatch = function() { 37 // set correct event type 38 event.type = "debouncedresize"; 39 $event.dispatch.apply( context, args ); 40 }; 41 if ( resizeTimeout ) { 42 clearTimeout( resizeTimeout ); 43 } 44 execAsap ? 45 dispatch() : 46 resizeTimeout = setTimeout( dispatch, $special.threshold ); 47 }, 48 threshold: 20 49 }; 50 // global 51 var $window = $( window ), 52 $document = $( document ), 53 Modernizr = window.Modernizr; 54 $.Slitslider = function( options, element ) { 55 56 this.$elWrapper = $( element ); 57 this._init( options ); 58 59 }; 60 $.Slitslider.defaults = { 61 // transitions speed 62 speed : 800, 63 // if true the item's slices will also animate the opacity value 64 optOpacity : false, 65 // amount (%) to translate both slices - adjust as necessary 66 translateFactor : 230, 67 // maximum possible angle 68 maxAngle : 25, 69 // maximum possible scale 70 maxScale : 5, 71 // slideshow on / off 72 autoplay : true, 73 // keyboard navigation 74 keyboard : true, 75 // time between transitions 76 interval : $("#txt_slidespeed").val(), 77 // callbacks 78 onBeforeChange : function( slide, idx ) { return false; }, 79 onAfterChange : function( slide, idx ) { return false; } 80 }; 81 $.Slitslider.prototype = { 82 _init : function( options ) { 83 84 // options 85 this.options = $.extend( true, {}, $.Slitslider.defaults, options ); 86 // https://github.com/twitter/bootstrap/issues/2870 87 this.transEndEventNames = { 88 'WebkitTransition' : 'webkitTransitionEnd', 89 'MozTransition' : 'transitionend', 90 'OTransition' : 'oTransitionEnd', 91 'msTransition' : 'MSTransitionEnd', 92 'transition' : 'transitionend' 93 }; 94 this.transEndEventName = this.transEndEventNames[ Modernizr.prefixed( 'transition' ) ]; 95 // suport for css 3d transforms and css transitions 96 this.support = Modernizr.csstransitions && Modernizr.csstransforms3d; 97 // the slider 98 this.$el = this.$elWrapper.children( '.sl-slider' ); 99 // the slides 100 this.$slides = this.$el.children( '.sl-slide' ).hide(); 101 // total slides 102 this.slidesCount = this.$slides.length; 103 // current slide 104 this.current = 0; 105 // control if it's animating 106 this.isAnimating = false; 107 // get container size 108 this._getSize(); 109 // layout 110 this._layout(); 111 // load some events 112 this._loadEvents(); 113 // slideshow 114 if( this.options.autoplay ) { 115 this._startSlideshow(); 116 } 117 }, 118 // gets the current container width & height 119 _getSize : function() { 120 this.size = { 121 width : this.$elWrapper.outerWidth( true ), 122 height : this.$elWrapper.outerHeight( true ) 123 }; 124 }, 125 _layout : function() { 126 this.$slideWrapper = $( '<div class="sl-slides-wrapper" />' ); 127 // wrap the slides 128 this.$slides.wrapAll( this.$slideWrapper ).each( function( i ) { 129 var $slide = $( this ), 130 // vertical || horizontal 131 orientation = $slide.data( 'orientation' ); 132 $slide.addClass( 'sl-slide-' + orientation ) 133 .children() 134 .wrapAll( '<div class="sl-content-wrapper" />' ) 135 .wrapAll( '<div class="sl-content" />' ); 136 } ); 137 // set the right size of the slider/slides for the current window size 138 this._setSize(); 139 // show first slide 140 this.$slides.eq( this.current ).show(); 141 }, 142 _navigate : function( dir, pos ) { 143 if( this.isAnimating || this.slidesCount < 2 ) { 144 return false; 145 } 146 this.isAnimating = true; 147 var self = this, 148 $currentSlide = this.$slides.eq( this.current ); 149 // if position is passed 150 if( pos !== undefined ) { 151 this.current = pos; 152 } 153 // if not check the boundaries 154 else if( dir === 'next' ) { 155 this.current = this.current < this.slidesCount - 1 ? ++this.current : 0; 156 } 157 else if( dir === 'prev' ) { 158 this.current = this.current > 0 ? --this.current : this.slidesCount - 1; 159 } 160 this.options.onBeforeChange( $currentSlide, this.current ); 161 162 // next slide to be shown 163 var $nextSlide = this.$slides.eq( this.current ), 164 // the slide we want to cut and animate 165 $movingSlide = ( dir === 'next' ) ? $currentSlide : $nextSlide, 166 167 // the following are the data attrs set for each slide 168 configData = $movingSlide.data(), 169 config = {}; 170 config.orientation = configData.orientation || 'horizontal', 171 config.slice1angle = configData.slice1Rotation || 0, 172 config.slice1scale = configData.slice1Scale || 1, 173 config.slice2angle = configData.slice2Rotation || 0, 174 config.slice2scale = configData.slice2Scale || 1;
175 this._validateValues( config ); 176 var cssStyle = config.orientation === 'horizontal' ? { 177 marginTop : -this.size.height / 2 178 } : { 179 marginLeft : -this.size.width / 2 180 }, 181 // default slide's slices style 182 resetStyle = { 183 'transform' : 'translate(0%,0%) rotate(0deg) scale(1)', 184 opacity : 1 185 }, 186 // slice1 style 187 slice1Style = config.orientation === 'horizontal' ? { 188 'transform' : 'translateY(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')' 189 } : { 190 'transform' : 'translateX(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')' 191 }, 192 // slice2 style 193 slice2Style = config.orientation === 'horizontal' ? { 194 'transform' : 'translateY(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')' 195 } : { 196 'transform' : 'translateX(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg)
196scale(' + config.slice2scale + ')' 197 }; 198 if( this.options.optOpacity ) { 199 slice1Style.opacity = 0; 200 slice2Style.opacity = 0; 201 } 202 // we are adding the classes sl-trans-elems and sl-trans-back-elems to the slide that is either coming "next" 203 // or going "prev" according to the direction. 204 // the idea is to make it more interesting by giving some animations to the respective slide's elements 205 //( dir === 'next' ) ? $nextSlide.addClass( 'sl-trans-elems' ) : $currentSlide.addClass( 'sl-trans-back-elems' ); 206 $currentSlide.removeClass( 'sl-trans-elems' ); 207 var transitionProp = { 208 'transition' : 'all ' + this.options.speed + 'ms ease-in-out' 209 }; 210 // add the 2 slices and animate them 211 $movingSlide.css( 'z-index', this.slidesCount ) 212 .find( 'div.sl-content-wrapper' ) 213 .wrap( $( '<div class="sl-content-slice" />' ).css( transitionProp ) ) 214 .parent() 215 .cond( 216 dir === 'prev', 217 function() { 218 var slice = this; 219 this.css( slice1Style ); 220 setTimeout( function() { 221 slice.css( resetStyle ); 222 }, 50 ); 223 }, 224 function() { 225 var slice = this; 226 setTimeout( function() { 227 slice.css( slice1Style ); 228 }, 50 ); 229 } 230 ) 231 .clone() 232 .appendTo( $movingSlide ) 233 .cond( 234 dir === 'prev', 235 function() { 236 var slice = this; 237 this.css( slice2Style ); 238 setTimeout( function() { 239 $currentSlide.addClass( 'sl-trans-back-elems' ); 240 if( self.support ) { 241 slice.css( resetStyle ).on( self.transEndEventName, function() { 242 self._onEndNavigate( slice, $currentSlide, dir ); 243 } ); 244 } 245 else { 246 self._onEndNavigate( slice, $currentSlide, dir ); 247 } 248 }, 50 ); 249 }, 250 function() { 251 var slice = this; 252 setTimeout( function() { 253 $nextSlide.addClass( 'sl-trans-elems' ); 254 if( self.support ) { 255 slice.css( slice2Style ).on( self.transEndEventName, function() { 256 self._onEndNavigate( slice, $currentSlide, dir ); 257 } ); 258 } 259 else { 260 self._onEndNavigate( slice, $currentSlide, dir ); 261 } 262 }, 50 ); 263 } 264 ) 265 .find( 'div.sl-content-wrapper' ) 266 .css( cssStyle ); 267 $nextSlide.show(); 268 }, 269 _validateValues : function( config ) { 270 // OK, so we are restricting the angles and scale values here. 271 // This is to avoid the slices wrong sides to be shown. 272 // you can adjust these values as you wish but make sure you also ajust the 273 // paddings of the slides and also the options.translateFactor value and scale data attrs 274 if( config.slice1angle > this.options.maxAngle || config.slice1angle < -this.options.maxAngle ) { 275 config.slice1angle = this.options.maxAngle; 276 } 277 if( config.slice2angle > this.options.maxAngle || config.slice2angle < -this.options.maxAngle ) { 278 config.slice2angle = this.options.maxAngle; 279 } 280 if( config.slice1scale > this.options.maxScale || config.slice1scale <= 0 ) { 281 config.slice1scale = this.options.maxScale; 282 } 283 if( config.slice2scale > this.options.maxScale || config.slice2scale <= 0 ) { 284 config.slice2scale = this.options.maxScale; 285 } 286 if( config.orientation !== 'vertical' && config.orientation !== 'horizontal' ) { 287 config.orientation = 'horizontal' 288 } 289 }, 290 _onEndNavigate : function( $slice, $oldSlide, dir ) { 291 292 // reset previous slide's style after next slide is shown 293 var $slide = $slice.parent(), 294 removeClasses = 'sl-trans-elems sl-trans-back-elems'; 295 296 // remove second slide's slice 297 $slice.remove(); 298 // unwrap.. 299 $slide.css( 'z-index', 1 ) 300 .find( 'div.sl-content-wrapper' ) 301 .unwrap(); 302 303 // hide previous current slide 304 $oldSlide.hide().removeClass( removeClasses ); 305 $slide.removeClass( removeClasses ); 306 // now we can navigate again.. 307 this.isAnimating = false;
308 this.options.onAfterChange( $slide, this.current ); 309 310 }, 311 _setSize : function() { 312 313 // the slider and content wrappers will have the window's width and height 314 var cssStyle = { 315 width : this.size.width, 316 height : this.size.height 317 }; 318 319 this.$el.css( cssStyle ).find( 'div.sl-content-wrapper' ).css( cssStyle ); 320 }, 321 _loadEvents : function() { 322 var self = this; 323 $window.on( 'debouncedresize.slitslider', function( event ) { 324 // update size values 325 self._getSize(); 326 // set the sizes again 327 self._setSize(); 328 } ); 329 if ( this.options.keyboard ) { 330 $document.on( 'keydown.slitslider', function(e) { 331 var keyCode = e.keyCode || e.which, 332 arrow = { 333 left: 37, 334 up: 38, 335 right: 39, 336 down: 40 337 }; 338 switch (keyCode) { 339 case arrow.left : 340 self._stopSlideshow(); 341 self._navigate( 'prev' ); 342 break; 343 case arrow.right : 344 self._stopSlideshow(); 345 self._navigate( 'next' ); 346 break; 347 } 348 } ); 349 } 350 351 }, 352 _startSlideshow: function() { 353 var self = this; 354 this.slideshow = setTimeout( function() { 355 self._navigate( 'next' ); 356 if ( self.options.autoplay ) { 357 self._startSlideshow(); 358 } 359 }, this.options.interval ); 360 }, 361 _stopSlideshow: function() { 362 if ( this.options.autoplay ) { 363 clearTimeout( this.slideshow ); 364 this.isPlaying = false; 365 this.options.autoplay = false; 366 } 367 }, 368 _destroy : function( callback ) { 369 370 this.$el.off( '.slitslider' ).removeData( 'slitslider' ); 371 $window.off( '.slitslider' ); 372 $document.off( '.slitslider' ); 373 this.$slides.each( function( i ) { 374 var $slide = $( this ), 375 $content = $slide.find( 'div.sl-content' ).children(); 376 $content.appendTo( $slide ); 377 $slide.children( 'div.sl-content-wrapper' ).remove(); 378 } ); 379 this.$slides.unwrap( this.$slideWrapper ).hide(); 380 this.$slides.eq( 0 ).show(); 381 if( callback ) { 382 callback.call(); 383 } 384 }, 385 // public methos: adds more slides to the slider 386 add : function( $slides, callback ) { 387 this.$slides = this.$slides.add( $slides ); 388 var self = this; 389 390 391 $slides.each( function( i ) { 392 var $slide = $( this ), 393 // vertical || horizontal 394 orientation = $slide.data( 'orientation' ); 395 $slide.hide().addClass( 'sl-slide-' + orientation ) 396 .children() 397 .wrapAll( '<div class="sl-content-wrapper" />' ) 398 .wrapAll( '<div class="sl-content" />' ) 399 .end() 400 .appendTo( self.$el.find( 'div.sl-slides-wrapper' ) ); 401 } ); 402 this._setSize(); 403 this.slidesCount = this.$slides.length; 404 405 if ( callback ) { 406 callback.call( $items ); 407 } 408 }, 409 // public method: shows next slide 410 next : function() { 411 this._stopSlideshow(); 412 this._navigate( 'next' ); 413 }, 414 // public method: shows previous slide 415 previous : function() { 416 this._stopSlideshow(); 417 this._navigate( 'prev' ); 418 }, 419 // public method: goes to a specific slide 420 jump : function( pos ) { 421 pos -= 1; 422 if( pos === this.current || pos >= this.slidesCount || pos < 0 ) { 423 return false; 424 } 425 this._stopSlideshow(); 426 this._navigate( pos > this.current ? 'next' : 'prev', pos ); 427 }, 428 // public method: starts the slideshow 429 // any call to next(), previous() or jump() will stop the slideshow 430 play : function() { 431 if( !this.isPlaying ) { 432 this.isPlaying = true; 433 this._navigate( 'next' ); 434 this.options.autoplay = true; 435 this._startSlideshow(); 436 } 437 }, 438 // public method: pauses the slideshow 439 pause : function() { 440 if( this.isPlaying ) { 441 this._stopSlideshow(); 442 } 443 }, 444 // public method: check if isAnimating is true 445 isActive : function() { 446 return this.isAnimating; 447 }, 448 // publicc methos: destroys the slicebox instance 449 destroy : function( callback ) { 450 this._destroy( callback ); 451 } 452 }; 453 var logError = function( message ) { 454 if ( window.console ) { 455 window.console.error( message ); 456 } 457 }; 458 $.fn.slitslider = function( options ) { 459 var self = $.data( this, 'slitslider' ); 460 if ( typeof options === 'string' ) { 461 var args = Array.prototype.slice.call( arguments, 1 ); 462 this.each(function() { 463 if ( !self ) { 464 logError( "cannot call methods on slitslider prior to initialization; " + 465 "attempted to call method '" + options + "'" ); 466 return; 467 } 468 if ( !$.isFunction( self[options] ) || options.charAt(0) === "_" ) { 469 logError( "no such method '" + options + "' for slitslider self" ); 470 return; 471 } 472 self[ options ].apply( self, args ); 473 }); 474 } 475 else { 476 this.each(function() { 477 if ( self ) { 478 self._init(); 479 } 480 else { 481 self = $.data( this, 'slitslider', new $.Slitslider( options, this ) ); 482 } 483 }); 484 } 485 return self; 486 }; 487} )( jQuery, window );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.