1/** 2 * jquery.slicebox.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 12;( function( $, window, undefined ) { 13 14 'use strict'; 15 16 /* 17 * debouncedresize: special jQuery event that happens once after a window resize 18 * 19 * latest version and complete README available on Github: 20 * https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js 21 * 22 * Copyright 2011 @louis_remi 23 * Licensed under the MIT license. 24 */ 25 var $event = $.event, 26 $special, 27 resizeTimeout; 28 29 $special = $event.special.debouncedresize = { 30 setup: function() { 31 $( this ).on( "resize", $special.handler ); 32 }, 33 teardown: function() { 34 $( this ).off( "resize", $special.handler ); 35 }, 36 handler: function( event, execAsap ) { 37 // Save the context 38 var context = this, 39 args = arguments, 40 dispatch = function() { 41 // set correct event type 42 event.type = "debouncedresize"; 43 $event.dispatch.apply( context, args ); 44 }; 45 46 if ( resizeTimeout ) { 47 clearTimeout( resizeTimeout ); 48 } 49 50 execAsap ? 51 dispatch() : 52 resizeTimeout = setTimeout( dispatch, $special.threshold ); 53 }, 54 threshold: 50 55 }; 56 57 // ======================= imagesLoaded Plugin =============================== 58 // https://github.com/desandro/imagesloaded 59 60 // $('#my-container').imagesLoaded(myFunction) 61 // execute a callback when all images have loaded. 62 // needed because .load() doesn't work on cached images 63 64 // callback function gets image collection as argument 65 // this is the container 66 67 // original: mit license. paul irish. 2010. 68 // contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou 69 70 // blank image data-uri bypasses webkit log warning (thx doug jones) 71 var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='; 72 73 $.fn.imagesLoaded = function( callback ) { 74 var $this = this, 75 deferred = $.isFunction($.Deferred) ? $.Deferred() : 0, 76 hasNotify = $.isFunction(deferred.notify), 77 $images = $this.find('img').add( $this.filter('img') ), 78 loaded = [], 79 proper = [], 80 broken = []; 81 82 // Register deferred callbacks 83 if ($.isPlainObject(callback)) { 84 $.each(callback, function (key, value) { 85 if (key === 'callback') { 86 callback = value; 87 } else if (deferred) { 88 deferred[key](value); 89 } 90 }); 91 } 92 93 function doneLoading() { 94 var $proper = $(proper), 95 $broken = $(broken); 96 97 if ( deferred ) { 98 if ( broken.length ) { 99 deferred.reject( $images, $proper, $broken ); 100 } else { 101 deferred.resolve( $images ); 102 } 103 } 104 105 if ( $.isFunction( callback ) ) { 106 callback.call( $this, $images, $proper, $broken ); 107 } 108 } 109 110 function imgLoaded( img, isBroken ) { 111 // don't proceed if BLANK image, or image is already loaded 112 if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) { 113 return; 114 } 115 116 // store element in loaded images array 117 loaded.push( img ); 118 119 // keep track of broken and properly loaded images 120 if ( isBroken ) { 121 broken.push( img ); 122 } else { 123 proper.push( img ); 124 } 125 126 // cache image and its state for future calls 127 $.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } ); 128 129 // trigger deferred progress method if present 130 if ( hasNotify ) { 131 deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] ); 132 } 133 134 // call doneLoading and clean listeners if all images are loaded 135 if ( $images.length === loaded.length ){ 136 setTimeout( doneLoading ); 137 $images.unbind( '.imagesLoaded' ); 138 } 139 } 140 141 // if no images, trigger immediately 142 if ( !$images.length ) { 143 doneLoading(); 144 } else { 145 $images.bind( 'load.imagesLoaded error.imagesLoaded', function( event ){ 146 // trigger imgLoaded 147 imgLoaded( event.target, event.type === 'error' ); 148 }).each( function( i, el ) { 149 var src = el.src; 150 151 // find out if this image has been already checked for status 152 // if it was, and src has not changed, call imgLoaded on it 153 var cached = $.data( el, 'imagesLoaded' ); 154 if ( cached && cached.src === src ) { 155 imgLoaded( el, cached.isBroken ); 156 return; 157 } 158 159 // if complete is true and browser supports natural sizes, try 160 // to check for image status manually
161 if ( el.complete && el.naturalWidth !== undefined ) { 162 imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 ); 163 return; 164 } 165 166 // cached images don't fire load sometimes, so we reset src, but only when 167 // dealing with IE, or image is complete (loaded) and failed manual check 168 // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f 169 if ( el.readyState || el.complete ) { 170 el.src = BLANK; 171 el.src = src; 172 } 173 }); 174 } 175 176 return deferred ? deferred.promise( $this ) : $this; 177 }; 178 179 // global 180 var $window = $( window ), 181 Modernizr = window.Modernizr; 182 183 $.Slicebox = function( options, element ) { 184 185 this.$el = $( element ); 186 this._init( options ); 187 188 }; 189 190 $.Slicebox.defaults = { 191 // (v)ertical, (h)orizontal or (r)andom 192 orientation : 'v', 193 // perspective value 194 perspective : 1200, 195 // number of slices / cuboids 196 // needs to be an odd number 15 => number > 0 (if you want the limit higher, change the _validate function). 197 cuboidsCount : 5, 198 // if true then the number of slices / cuboids is going to be random (cuboidsCount is overwitten) 199 cuboidsRandom : false, 200 // the range of possible number of cuboids if cuboidsRandom is true 201 // it is strongly recommended that you do not set a very large number :) 202 maxCuboidsCount : 5, 203 // each cuboid will move x pixels left / top (depending on orientation). The middle cuboid doesn't move. the middle cuboid's neighbors will move disperseFactor pixels 204 disperseFactor : 0, 205 // color of the hidden sides 206 colorHiddenSides : '#222', 207 // the animation will start from left to right. The left most cuboid will be the first one to rotate 208 // this is the interval between each rotation in ms 209 sequentialFactor : 150, 210 // animation speed 211 // this is the speed that takes "1" cuboid to rotate 212 speed : 600, 213 // transition easing 214 easing : 'ease', 215 // if true the slicebox will start the animation automatically 216 autoplay : false, 217 // time (ms) between each rotation, if autoplay is true 218 interval: 3000, 219 // the fallback will just fade out / fade in the items 220 // this is the time fr the fade effect
221 fallbackFadeSpeed : 300, 222 // callbacks 223 onBeforeChange : function( position ) { return false; }, 224 onAfterChange : function( position ) { return false; }, 225 onReady : function() { return false; } 226 }; 227 228 $.Slicebox.prototype = { 229 230 _init : function( options ) { 231 232 // options 233 this.options = $.extend( true, {}, $.Slicebox.defaults, options ); 234 235 this._validate(); 236 237 // all the items 238 this.$items = this.$el.children( 'li' ); 239 240 // total number of items 241 this.itemsCount = this.$items.length; 242 // if there's no items return 243 if(this.itemsCount === 0 ) { 244 245 return false; 246 247 }; 248 249 // suport for css 3d transforms and css transitions 250 this.support = Modernizr.csstransitions && Modernizr.csstransforms3d; 251 252 // current image index 253 this.current = 0; 254 255 // control if the slicebox is animating 256 this.isAnimating = false; 257 258 // control if slicebox is ready (all images loaded) 259 this.isReady = false; 260 261 // preload the images 262 var self = this; 263 this.$el.imagesLoaded( function() { 264 265 // we need to hide the items except first one (current default value) 266 var $current = self.$items.eq( self.current ).css( 'display', 'block' ).addClass( 'sb-current' ); 267 268 // get real size of image 269 var i = new Image(); 270 i.src = $current.find( 'img' ).attr( 'src' ); 271 self.realWidth = i.width; 272 273 // assuming all images with same size 274 self._setSize(); 275 self._setStyle(); 276 self._initEvents(); 277 278 self.options.onReady(); 279 self.isReady = true; 280 281 if( self.options.autoplay ) { 282 283 self._startSlideshow(); 284 285 } 286 287 }); 288 289 }, 290 _validate : function( options ) { 291 292 if( this.options.cuboidsCount < 0 ){ 293 294 this.options.cuboidsCount = 1; 295 296 } 297 else if( this.options.cuboidsCount > 15 ) { 298 299 this.options.cuboidsCount = 15; 300 301 } 302 else if( this.options.cuboidsCount %2 === 0 ) { 303 304 ++this.options.cuboidsCount; 305 306 } 307 308 if( this.options.maxCuboidsCount < 0 ){ 309 310 this.options.maxCuboidsCount = 1; 311 312 } 313 else if( this.options.maxCuboidsCount > 15 ) { 314 315 this.options.maxCuboidsCount = 15; 316 317 } 318 else if( this.options.maxCuboidsCount %2 === 0 ) { 319 320 ++this.options.maxCuboidsCount; 321 322 } 323 324 if( this.options.disperseFactor < 0 ) { 325 326 this.options.disperseFactor = 0; 327 328 } 329 330 if( this.options.orientation !== 'v' && this.options.orientation !== 'h' && this.options.orientation !== 'r' ) { 331 332 this.options.orientation = 'v'; 333 334 } 335 336 }, 337 _setSize : function() { 338 339 var $visible = this.$items.eq( this.current ).find( 'img' ); 340 341 this.size = { 342 width : $visible.width(), 343 height : $visible.height() 344 }; 345 346 }, 347 _setStyle : function() { 348 349 // max-width is the real size of the images 350 this.$el.css( { 351 'max-width' : this.realWidth 352 } ); 353 354 }, 355 _initEvents : function() { 356 357 var self = this; 358 359 $window.on( 'debouncedresize.slicebox', function( event ) { 360 361 // assuming all images with same size 362 self._setSize(); 363 364 } ); 365 366 }, 367 _startSlideshow: function() { 368 369 var self = this; 370 371 this.slideshow = setTimeout( function() { 372 373 self._navigate( 'next' ); 374 375 if ( self.options.autoplay ) { 376 377 self._startSlideshow(); 378 379 } 380 381 }, this.options.interval ); 382 383 }, 384 _stopSlideshow: function() { 385 386 if ( this.options.autoplay ) { 387 388 clearTimeout( this.slideshow ); 389 this.isPlaying = false; 390 this.options.autoplay = false; 391 392 } 393 394 }, 395 _navigate : function( dir, pos ) { 396 397 if( this.isAnimating || !this.isReady || this.itemsCount < 2 ) { 398 399 return false; 400 401 } 402 403 this.isAnimating = true; 404 405 // current item's index 406 this.prev = this.current; 407 408 // if position is passed 409 if( pos !== undefined ) { 410 411 this.current = pos; 412 413 } 414 // if not check the boundaries 415 else if( dir === 'next' ) { 416 417 this.current = this.current < this.itemsCount - 1 ? this.current + 1 : 0; 418 419 } 420 else if( dir === 'prev' ) { 421 422 this.current = this.current > 0 ? this.current - 1 : this.itemsCount - 1; 423 424 } 425 426 // callback trigger 427 this.options.onBeforeChange( this.current ); 428 429 if( !this.support ) { 430 431 this._fade( dir ); 432 433 } 434 else { 435 436 this._layout( dir ); 437 this._rotate(); 438 439 } 440 441 }, 442 _fade : function( dir ) { 443 444 var self = this, 445 $visible = this.$items.eq( this.prev ),
446 h = $visible.find( 'img' ).height(); 447 448 this.$el.css( 'height', h ); 449 this.$items.css( 'position', 'absolute' ); 450 451 this.$items.eq( this.current ).fadeIn( this.options.fallbackFadeSpeed, function() { 452 453 $( this ).css( 'display', 'block' ).addClass( 'sb-current' ); 454 self.$el.css( 'height', 'auto' ); 455 self.$items.css( 'position', 'relative' ); 456 self.isAnimating = false; 457 458 } ); 459 self.$items.eq( self.prev ).removeClass( 'sb-current' ).fadeOut( this.options.fallbackFadeSpeed ); 460 461 }, 462 _layout : function( dir ) { 463 464 // create a structure like this and append it to the main container (this.$el): 465 // <div> wrapper with perspective 466 // <div> 467 // <div></div> front side 468 // <div></div> back side 469 // <div></div> right side 470 // <div></div> left side 471 // <div></div> top side 472 // <div></div> bottom side 473 // </div> 474 // <div>..</div> 475 // <div>..</div> 476 // <div>..</div> 477 // ... number of slices defined in options 478 // </div> 479 480 var orientation = this.options.orientation; 481 482 if( orientation === 'r' ) { 483 484 orientation = Math.floor( Math.random() * 2 ) === 0 ? 'v' : 'h'; 485 486 } 487 488 if( this.options.cuboidsRandom ) { 489 490 this.options.cuboidsCount = Math.floor( Math.random() * this.options.maxCuboidsCount + 1 ); 491 492 } 493 494 this._validate(); 495 496 var boxStyle = { 497 'width' : this.size.width, 498 'height' : this.size.height, 499 'perspective' : this.options.perspective + 'px' 500 }, 501 config = $.extend( this.options, { 502 size : this.size, 503 items : this.$items, 504 direction : dir, 505 prev : this.prev, 506 current : this.current, 507 o : orientation 508 } ), 509 self = this; 510 511 this.$box = $('<div>').addClass( 'sb-perspective' ).css( boxStyle ).appendTo( this.$el ); 512 513 this.cuboids = []; 514 515 this.$el.css( 'overflow', 'visible' ); 516 517 for( var i = 0; i < this.options.cuboidsCount; ++i ) { 518 519 var cuboid = new $.Cuboid( config, i ); 520 521 this.$box.append( cuboid.getEl() ); 522 523 this.cuboids.push( cuboid ); 524 525 } 526 527 }, 528 _rotate : function() { 529 530 // hide current item 531 this.$items.eq( this.prev ).removeClass( 'sb-current' ).hide(); 532 533 for( var i = 0; i < this.options.cuboidsCount; ++i ) { 534 535 var cuboid = this.cuboids[ i ], 536 self = this; 537 538 cuboid.rotate( function( pos ) { 539 540 if( pos === self.options.cuboidsCount - 1 ) { 541 542 self.$el.css( 'overflow', 'hidden' ); 543 self.isAnimating = false; 544 self.$box.remove(); 545 var $current = self.$items.eq( self.current ); 546 $current.css( 'display', 'block' ); // show() makes it inline style 547 setTimeout(function() { 548 $current.addClass( 'sb-current' ); 549 } , 0 ); 550 self.options.onAfterChange( self.current ); 551 552 } 553 554 }); 555 556 } 557 558 }, 559 _destroy : function( callback ) { 560 561 this.$el.off( '.slicebox' ).removeData( 'slicebox' ); 562 $window.off( '.slicebox' ); 563 callback.call(); 564 565 }, 566 // public methos: adds more items to the slicebox 567 add : function( $items, callback ) { 568 569 this.$items = this.$items.add( $items ); 570 this.itemsCount = this.$items.length; 571 572 if ( callback ) { 573 574 callback.call( $items ); 575 576 } 577 578 }, 579 // public method: shows next image 580 next : function() { 581 582 this._stopSlideshow(); 583 this._navigate( 'next' ); 584 585 }, 586 // public method: shows previous image 587 previous : function() { 588 589 this._stopSlideshow(); 590 this._navigate( 'prev' ); 591 592 }, 593 // public method: goes to a specific image 594 jump : function( pos ) { 595 596 pos -= 1; 597 598 if( pos === this.current || pos >= this.itemsCount || pos < 0 ) { 599 600 return false; 601 602 } 603 604 this._stopSlideshow(); 605 this._navigate( pos > this.current ? 'next' : 'prev', pos ); 606 607 }, 608 // public method: starts the slideshow 609 // any call to next(), previous() or jump() will stop the slideshow 610 play : function() { 611 612 if( !this.isPlaying ) { 613 614 this.isPlaying = true; 615 616 this._navigate( 'next' ); 617 this.options.autoplay = true; 618 this._startSlideshow(); 619 620 } 621 622 }, 623 // publicc methos: pauses the slideshow 624 pause : function() { 625 626 if( this.isPlaying ) { 627 628 this._stopSlideshow(); 629 630 } 631 632 }, 633 // public method: check if isAnimating is true 634 isActive : function() { 635 636 return this.isAnimating; 637 638 },
639 // publicc methos: destroys the slicebox instance 640 destroy : function( callback ) { 641 642 this._destroy( callback ); 643 644 } 645 646 }; 647 648 $.Cuboid = function( config, pos ) { 649 650 this.config = config; 651 this.pos = pos; 652 this.side = 1; 653 this._setSize(); 654 this._configureStyles(); 655 656 }; 657 658 $.Cuboid.prototype = { 659 660 _setSize : function() { 661 662 this.size = { 663 width : this.config.o === 'v' ? Math.floor( this.config.size.width / this.config.cuboidsCount ) : this.config.size.width, 664 height : this.config.o === 'v' ? this.config.size.height : Math.floor( this.config.size.height / this.config.cuboidsCount ) 665 }; 666 // extra space to fix gaps 667 this.extra = this.config.o === 'v' ? this.config.size.width - ( this.size.width * this.config.cuboidsCount ) : this.config.size.height - ( this.size.height * this.config.cuboidsCount ); 668 669 }, 670 _configureStyles : function() { 671 672 // style for the cuboid element 673 // set z-indexes based on the cuboid's position 674 var middlepos = Math.ceil( this.config.cuboidsCount / 2 ), 675 positionStyle = this.pos < middlepos ? { 676 zIndex : ( this.pos + 1 ) * 100, 677 left : ( this.config.o === 'v' ) ? this.size.width * this.pos : 0, 678 top : ( this.config.o === 'v' ) ? 0 : this.size.height * this.pos 679 } : { 680 zIndex : (this.config.cuboidsCount - this.pos) * 100, 681 left : ( this.config.o === 'v' ) ? this.size.width * this.pos : 0, 682 top : ( this.config.o === 'v' ) ? 0 : this.size.height * this.pos 683 }; 684 685 // how much this cuboid is going to move (left or top values) 686 this.disperseFactor = this.config.disperseFactor * ( ( this.pos + 1 ) - middlepos ); 687 688 this.style = $.extend( { 689 '-webkit-transition' : '-webkit-transform ' + this.config.speed + 'ms ' + this.config.easing, 690 '-moz-transition' : '-moz-transform ' + this.config.speed + 'ms ' + this.config.easing, 691 '-o-transition' : '-o-transform ' + this.config.speed + 'ms ' + this.config.easing, 692 '-ms-transition' : '-ms-transform ' + this.config.speed + 'ms ' + this.config.easing, 693 'transition' : 'transform ' + this.config.speed + 'ms ' + this.config.easing 694 }, positionStyle, this.size ); 695 696 this.animationStyles = { 697 side1 : ( this.config.o === 'v' ) ? { 'transform' : 'translate3d( 0, 0, -' + ( this.size.height / 2 ) + 'px )' } : { 'transform' : 'translate3d( 0, 0, -' + ( this.size.width / 2 ) + 'px )' }, 698 side2 : ( this.config.o === 'v' ) ? { 'transform' : 'translate3d( 0, 0, -' + ( this.size.height / 2 ) + 'px ) rotate3d( 1, 0, 0, -90deg )' } : { 'transform' : 'translate3d( 0, 0, -' + ( this.size.width / 2 ) + 'px ) rotate3d( 0, 1, 0, -90deg )' }, 699 side3 : ( this.config.o === 'v' ) ? { 'transform' : 'translate3d( 0, 0, -' + ( this.size.height / 2 ) + 'px ) rotate3d( 1, 0, 0, -180deg )' } : { 'transform' : 'translate3d( 0, 0, -' + ( this.size.width / 2 ) + 'px ) rotate3d( 0, 1, 0, -180deg )' }, 700 side4 : ( this.config.o === 'v' ) ? { 'transform' : 'translate3d( 0, 0, -' + ( this.size.height / 2 ) + 'px ) rotate3d( 1, 0, 0, -270deg )' } : { 'transform' : 'translate3d( 0, 0, -' + ( this.size.width / 2 ) + 'px ) rotate3d( 0, 1, 0, -270deg )' } 701 }; 702 703 var measure = ( this.config.o === 'v' ) ? this.size.height : this.size.width; 704 705 this.sidesStyles = { 706 frontSideStyle : { 707 width : ( this.config.o === 'v' ) ? this.size.width + this.extra : this.size.width, 708 height : ( this.config.o === 'v' ) ? this.size.height : this.size.height + this.extra, 709 backgroundColor : this.config.colorHiddenSides, 710 transform : 'rotate3d( 0, 1, 0, 0deg ) translate3d( 0, 0, ' + ( measure / 2 ) + 'px )' 711 }, 712 backSideStyle : { 713 width : this.size.width, 714 height : this.size.height, 715 backgroundColor : this.config.colorHiddenSides, 716 transform : 'rotate3d( 0, 1, 0, 180deg ) translate3d( 0, 0, ' + ( measure / 2 ) + 'px ) rotateZ( 180deg )' 717 }, 718 rightSideStyle : { 719 width : measure, 720 height : ( this.config.o === 'v' ) ? this.size.height : this.size.height + this.extra, 721 left : ( this.config.o === 'v' ) ? this.size.width / 2 - this.size.height / 2 : 0, 722 backgroundColor : this.config.colorHiddenSides, 723 transform : 'rotate3d( 0, 1, 0, 90deg ) translate3d( 0, 0, ' + ( this.size.width / 2 ) + 'px )' 724 }, 725 leftSideStyle : { 726 width : measure, 727 height : ( this.config.o === 'v' ) ? this.size.height : this.size.height + this.extra, 728 left : ( this.config.o === 'v' ) ? this.size.width / 2 - this.size.height / 2 : 0, 729 backgroundColor : this.config.colorHiddenSides, 730 transform : 'rotate3d( 0, 1, 0, -90deg ) translate3d( 0, 0, ' + ( this.size.width / 2 ) + 'px )' 731 }, 732 topSideStyle : { 733 width : ( this.config.o === 'v' ) ? this.size.width + this.extra
733: this.size.width, 734 height : measure, 735 top : ( this.config.o === 'v' ) ? 0 : this.size.height / 2 - this.size.width / 2, 736 backgroundColor : this.config.colorHiddenSides, 737 transform : 'rotate3d( 1, 0, 0, 90deg ) translate3d( 0, 0, ' + ( this.size.height / 2 ) + 'px )' 738 }, 739 bottomSideStyle : { 740 width : ( this.config.o === 'v' ) ? this.size.width + this.extra : this.size.width, 741 height : measure, 742 top : ( this.config.o === 'v' ) ? 0 : this.size.height / 2 - this.size.width / 2, 743 backgroundColor : this.config.colorHiddenSides, 744 transform : 'rotate3d( 1, 0, 0, -90deg ) translate3d( 0, 0, ' + ( this.size.height / 2 ) + 'px )' 745 } 746 }; 747 748 }, 749 getEl : function() { 750 751 this.$el = $('<div/>').css( this.style ) 752 .css( this.animationStyles.side1 ) 753 .append( $('<div/>').addClass('sb-side').css( this.sidesStyles.frontSideStyle ) ) 754 .append( $('<div/>').addClass('sb-side').css( this.sidesStyles.backSideStyle ) ) 755 .append( $('<div/>').addClass('sb-side').css( this.sidesStyles.rightSideStyle ) ) 756 .append( $('<div/>').addClass('sb-side').css( this.sidesStyles.leftSideStyle ) ) 757 .append( $('<div/>').addClass('sb-side').css( this.sidesStyles.topSideStyle ) ) 758 .append( $('<div/>').addClass('sb-side').css( this.sidesStyles.bottomSideStyle ) ); 759 760 this._showImage( this.config.prev ); 761 762 return this.$el; 763 764 }, 765 _showImage : function( imgPos ) { 766 767 var sideIdx, 768 $item = this.config.items.eq( imgPos ), 769 imgParam = { 770 'background-size' : this.config.size.width + 'px ' + this.config.size.height + 'px' 771 }; 772 773 imgParam.backgroundImage = 'url(' + $item.find( 'img' ).attr('src') + ')'; 774 775 switch( this.side ) { 776 777 case 1 : sideIdx = 0; break; 778 case 2 : sideIdx = ( this.config.o === 'v' ) ? 4 : 2; break; 779 case 3 : sideIdx = 1; break; 780 case 4 : sideIdx = ( this.config.o === 'v' ) ? 5 : 3; break; 781 782 }; 783 784 imgParam.backgroundPosition = ( this.config.o === 'v' ) ? - ( this.pos * this.size.width ) + 'px 0px' : '0px -' + ( this.pos * this.size.height ) + 'px'; 785 this.$el.children().eq( sideIdx ).css( imgParam ); 786 787 }, 788 rotate : function( callback ) { 789 790 var self = this, animationStyle; 791 792 setTimeout(function() { 793 794 if( self.config.direction === 'next' ) { 795 796 switch( self.side ) { 797 case 1 : animationStyle = self.animationStyles.side2; self.side = 2; break; 798 case 2 : animationStyle = self.animationStyles.side3; self.side = 3; break; 799 case 3 : animationStyle = self.animationStyles.side4; self.side = 4; break; 800 case 4 : animationStyle = self.animationStyles.side1; self.side = 1; break; 801 }; 802 803 } 804 else { 805 806 switch( self.side ) { 807 case 1 : animationStyle = self.animationStyles.side4; self.side = 4; break; 808 case 2 : animationStyle = self.animationStyles.side1; self.side = 1; break; 809 case 3 : animationStyle = self.animationStyles.side2; self.side = 2; break; 810 case 4 : animationStyle = self.animationStyles.side3; self.side = 3; break; 811 }; 812 813 } 814 815 self._showImage( self.config.current ); 816 817 var animateOut = {}, animateIn = {}; 818 819 if( self.config.o === 'v' ) { 820 821 animateOut.left = '+=' + self.disperseFactor + 'px'; 822 animateIn.left = '-=' + self.disperseFactor + 'px'; 823 824 } 825 else if( self.config.o === 'h' ) { 826 827 animateOut.top = '+=' + self.disperseFactor + 'px'; 828 animateIn.top = '-=' + self.disperseFactor + 'px'; 829 830 } 831 832 self.$el.css( animationStyle ).animate( animateOut, self.config.speed / 2 ).animate( animateIn, self.config.speed / 2 , function() { 833 834 if( callback ) { 835 836 callback.call( self, self.pos ); 837 838 } 839 840 }); 841 842 }, this.config.sequentialFactor * this.pos + 30 ); 843 844 } 845 846 }; 847 848 var logError = function( message ) { 849 850 if ( window.console ) { 851 852 window.console.error( message ); 853 854 } 855 856 }; 857 858 $.fn.slicebox = function( options ) { 859 860 var self = $.data( this, 'slicebox' ); 861 862 if ( typeof options === 'string' ) { 863 864 var args = Array.prototype.slice.call( arguments, 1 ); 865 866 this.each(function() { 867 868 if ( !self ) { 869 870 logError( "cannot call methods on slicebox prior to initialization; " + 871 "attempted to call method '" + options + "'" ); 872 return; 873 874 } 875 876 if ( !$.isFunction( self[options] ) || options.charAt(0) === "_" ) { 877 878 logError( "no such method '" + options + "' for slicebox self" ); 879 return; 880 881 } 882 883 self[ options ].apply( self, args ); 884 885 }); 886 887 } 888 else { 889 890 this.each(function() { 891 892 if ( self ) { 893 894 self._init(); 895 896 } 897 else { 898 899 self = $.data( this, 'slicebox', new $.Slicebox( options, this ) ); 900 901 } 902 903 }); 904 905 } 906 907 return self; 908 909 }; 910 911} )( 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.