1/** 2 * Avia Fade Slider - A simple jQuery image slider that supports embedded videos 3 * (c) Copyright Christian "Kriesi" Budschedl 4 * http://www.kriesi.at 5 * http://www.twitter.com/kriesi/ 6 * Version 1: Fade Slider release 7 * Version 2: defaults are now called within the plugin 8 * version 3: introduces comboslide detection and fade in/out of preview images 9 * version 4: fades out caption for video slides, fixed preloading, requires new aviaImagePreloader now, fades out controlls if requested 10 * version 5: added the option for slideshow resizing 11 * version 6: slideshow resizing detects change of slideshow width and ,odifies image ratio accordingly. good for flexible layouts 12 */ 13 14 15 16(function($) 17{ 18 var pluginNameSpace = 'avia_fade_slider', 19 20 //methods used to create the slideshow 21 methods = { 22 23 /************************************************************************ 24 methods.init: 25 26 initialize the slider by activating the image preloader if available and 27 then wait until images are loaded 28 *************************************************************************/ 29 init: function() 30 { 31 //start preloading images if the preloader is available 32 if(jQuery.fn.aviaImagePreloader) 33 { 34 this.aviaImagePreloader({thisData: this}, methods.preloadingDone); 35 } 36 else 37 { 38 methods.preloadingDone.apply( this ); 39 } 40 }, 41 42 /************************************************************************ 43 methods.preloadingDone: 44 45 once images are pre loaded execute all necessary functions for the slider 46 like applying controlls and starting autorotation 47 *************************************************************************/ 48 preloadingDone: function() 49 { 50 //fetch slider data 51 var data = this.data( pluginNameSpace ); 52 53 this.addClass('preloadingDone'); 54 55 //allow animation of slides: 56 data.animatingNow = false; 57 58 //prepare slides 59 methods.prepareSlides.apply( this ); 60 methods.modifyHeight.apply( this , [data.currentSlide]); 61 62 //append controlls and start autsolider if we got more than one slide and these options are set 63 if(data.slideCount > 1) 64 { 65 if(data.options.appendControlls) methods.appendControlls.apply( this ); 66 if(data.options.autorotation) methods.autorotation.apply( this ); 67 68 } 69 methods.bindEvents.apply( this ); 70 71 //show caption if available 72 if(data.options.appendCaption) methods.appendCaption.apply( this ); 73 data.allcaptions = this.find('.'+data.options.captionClass).css({display:'none'}); 74 methods.showCaption.apply( this ); 75 }, 76 77 /************************************************************************ 78 methods.prepareSlides: 79 80 addds classnames slides so we know if they are image slides, image slides 81 with video beneath or embeded videos 82 *************************************************************************/ 83 prepareSlides :function() 84 { 85 var data = this.data( pluginNameSpace ), currentslide, imageslide, videoslide, classname; 86 87 data.slides.each(function(i) 88 { 89 currentslide = $(this); 90 imageslide = currentslide.find('img'); 91 videoslide = currentslide.find('video, embed, object, iframe, .avia_video'); 92 93 if(imageslide.length && videoslide.length) 94 {
95 classname = 'comboslide'; 96 } 97 else if(videoslide.length) 98 { 99 classname = 'videoslide'; 100 } 101 else if(imageslide.length) 102 { 103 classname = 'imageslide'; 104 } 105 106 currentslide.addClass(classname).append('<span class="slideshow_overlay"></span>'); 107 108 //google chrome youtube fix: youtube videos need to be hidden and then shown before they respond to zIndex properties 109 if(classname == 'videoslide' && i == 0) 110 { 111 currentslide.css({display:"none"}); 112 setTimeout(function() 113 { 114 currentslide.css({display:"block"}); 115 },10) 116 } 117 118 }); 119 }, 120 121 /************************************************************************ 122 methods.autorotation: 123 124 start the slider autorotation 125 *************************************************************************/ 126 autorotation: function() 127 { 128 var current = this, 129 data = this.data( pluginNameSpace ), 130 time = (parseInt(data.options.autorotationSpeed) * 1000); 131 132 data.interval = setTimeout(function() 133 { 134 //switch slides 135 methods.transition.apply( current, ['next'] ); 136 137 //call this function again 138 methods.autorotation.apply( current ); 139 }, 140 time); 141 142 if(data.options.appendControlls) data.arrowControlls.play.addClass('ctrl_active').text('Pause'); 143 }, 144 145 146 /************************************************************************ 147 methods.autorotationStop: 148 149 stop the slider autorotation 150 *************************************************************************/ 151 autorotationStop: function() 152 { 153 var data = this.data( pluginNameSpace ); 154 clearTimeout(data.interval); 155 data.interval = false; 156 157 if(data.options.appendControlls && data.arrowControlls && data.arrowControlls.play && data.arrowControlls.play.length) data.arrowControlls.play.removeClass('ctrl_active').text('Play'); 158 }, 159 160 /************************************************************************ 161 methods.switchAutorotation: 162 163 switch between active and inactive autorotation state 164 *************************************************************************/ 165 switchAutorotation: function() 166 { 167 var data = this.data( pluginNameSpace ); 168 169 if(data.interval) 170 { 171 methods.autorotationStop.apply( this ); 172 } 173 else 174 { 175 methods.transition.apply( this, ['next'] ); 176 methods.autorotation.apply( this ); 177 } 178 }, 179 180 /************************************************************************ 181 methods.appendControlls: 182 183 append direct controlls as well as arrow controlls to the slider 184 *************************************************************************/ 185 appendControlls: function() 186 { 187 var data = this.data( pluginNameSpace ), 188 first = 'class="active_item" ', 189 singlecontroll = '', 190 arrowcontroll = '<a href="#" class="ctrl_back ctrl_arrow">Previous</a>'; 191 arrowcontroll += '<a href="#" class="ctrl_play ctrl_arrow">Play</a>'; 192 arrowcontroll += '<a href="#" class="ctrl_fwd ctrl_arrow">Next</a>'; 193 194 for(var i = 0; i < data.slideCount; i++) 195 { 196 singlecontroll += '<a '+first+'href="#'+i+'">'+(i+1)+'</a>'; 197 first = ''; 198 } 199
200 data.controllContainer = $('<div class="slidecontrolls">'+singlecontroll+'</div>').insertAfter(this); 201 data.arrowControllContainer = $('<div class="arrowslidecontrolls">'+arrowcontroll+'</div>').insertAfter(this); 202 data.controlls = data.controllContainer.find('a'); 203 data.arrowControlls = { 204 prev: data.arrowControllContainer.find('.ctrl_back'), 205 next: data.arrowControllContainer.find('.ctrl_fwd'), 206 play: data.arrowControllContainer.find('.ctrl_play'), 207 all: data.arrowControllContainer.find('a') 208 }; 209 }, 210 211 /************************************************************************ 212 methods.setSlides: 213 214 checks which slide should be displayed next and stores that information to 215 the this.data.nextSlide var 216 *************************************************************************/ 217 setSlides: function(selector) 218 { 219 //get slider data and set the current slide by selecting the one that is visible 220 var data = this.data( pluginNameSpace ), newIndex; 221 222 if(!data.animatingNow) 223 { 224 data.currentSlide = this.find(data.options.slides + ':visible'); 225 data.currentSlideIndex = data.slides.index(data.currentSlide); 226 227 //based on the passed selector value (next/prev/integer value) get the number of the next slide 228 switch (selector) 229 { 230 case 'next': newIndex = data.currentSlideIndex + 1 < data.slideCount ? data.currentSlideIndex + 1 : 0; break; 231 case 'prev': newIndex = data.currentSlideIndex - 1 >= 0 ? data.currentSlideIndex - 1 : data.slideCount - 1; break; 232 default: newIndex = selector; 233 } 234 235 //select the next slide and store it to data.nextSlide 236 data.nextSlide = this.find( data.options.slides + ':eq('+newIndex+')'); 237 data.currentSlideIndex = newIndex; 238 239 //check if the current slide is the same as the next one. if so skip the transition 240 if(data.nextSlide[0] == data.currentSlide[0]) data.skipTransition = true; 241 } 242 }, 243 244 /************************************************************************ 245 methods.appendCaption: 246 247 append a caption based on the image alt attribute 248 *************************************************************************/ 249 appendCaption: function() 250 { 251 var data = this.data( pluginNameSpace ), description = false, splitdesc = []; 252 253 data.slides.each(function() 254 { 255 var currentSlide = $(this); 256 description = currentSlide.find('img').attr('alt'); 257 258 if(description) splitdesc = description.split('::'); 259 260 if(splitdesc[0] != "" ) 261 { 262 if(splitdesc[1] != undefined ) 263 { 264 description = "<strong>"+splitdesc[0] +"</strong>"+splitdesc[1]; 265 } 266 else 267 { 268 description = splitdesc[0]; 269 } 270 } 271 272 if(description) 273 { 274 $('<span></span>').addClass(data.options.captionClass) 275 .html(description) 276 .css({display:'none', 'opacity':data.options.captionOpacity}) 277 .appendTo(currentSlide); 278 } 279 }); 280 281 }, 282 283 /************************************************************************ 284 methods.showCaption: 285 286 show the caption for the current slide once the slide has been revealed 287 *************************************************************************/ 288 showCaption: function() 289 { 290 var data = this.data( pluginNameSpace ); 291 292 //hide all other captions 293 data.allcaptions = this.find('.'+data.options.captionClass).css({display:'none'}).removeClass('active_caption'); 294 295 //select current caption 296 297 var caption = data.currentSlide.find('.'+data.options.captionClass).css({display:'block', opacity:0}).addClass('active_caption'); 298 299 var opacityVal = data.options.captionOpacity; 300 if(data.currentSlide.is('.caption_left_framed') || data.currentSlide.is('.caption_right_framed')) opacityVal = 0.8; 301 302 caption.animate({opacity: opacityVal}); 303 }, 304 305 /************************************************************************ 306 methods.fadeSlides: 307 308 visual fade slide transition via jQuerys animate function 309 *************************************************************************/ 310 fadeSlides: function() 311 { 312 var current = $(this), data = this.data( pluginNameSpace ); 313 314 if(!data.animatingNow && !data.skipTransition) 315 { 316 methods.beforeSwitch.apply( current ); 317 data.currentSlide.animate({opacity:0}
317, data.options.animationSpeed, function(){ methods.switchComplete.apply( current ); }); 318 319 //check the controlls and apply the active class to the correct controll 320 if(data.options.appendControlls) data.controlls.removeClass('active_item').filter(':eq('+data.currentSlideIndex+')').addClass('active_item'); 321 } 322 323 if(data.skipTransition) data.skipTransition = false; 324 }, 325 326 327 /************************************************************************ 328 methods.moveSlides: 329 330 visual sliding transition via jQuerys animate function 331 *************************************************************************/ 332 moveSlides: function() 333 { 334 var current = $(this), data = this.data( pluginNameSpace ); 335 336 if(!data.animatingNow && !data.skipTransition) 337 { 338 methods.beforeSwitch.apply( current ); 339 340 var indexCurrent = data.slides.index(data.currentSlide), 341 indexNext = data.slides.index(data.nextSlide), 342 direction = 1, 343 positioning = -1; 344 movement = parseInt(current.width()); 345 346 if(indexCurrent < indexNext) direction = -1; 347 348 data.nextSlide.css({left: ((movement * direction) * positioning)}
348).animate({opacity:1, left: 0}, data.options.animationSpeed); 349 data.currentSlide.animate({opacity:0, left: (movement * direction)}, data.options.animationSpeed, function(){ methods.switchComplete.apply( current ); }); 350 351 //check the controlls and apply the active class to the correct controll 352 if(data.options.appendControlls) data.controlls.removeClass('active_item').filter(':eq('+data.currentSlideIndex+')').addClass('active_item'); 353 } 354 355 if(data.skipTransition) data.skipTransition = false; 356 }, 357 358 359 /************************************************************************ 360 methods.beforeSwitch: 361 362 execute this before the slide switching starts 363 *************************************************************************/ 364 beforeSwitch: function() 365 { 366 var data = this.data( pluginNameSpace ); 367 368 data.animatingNow = true; 369 data.currentSlide.css({zIndex:3}); 370 data.nextSlide.css({zIndex:2, display:'block'}); 371 372 methods.modifyHeight.apply( this ); 373 }, 374 375 /************************************************************************ 376 methods.switchComplete: 377 378 execute this once the slides have been switched 379 *************************************************************************/ 380 switchComplete: function() 381 { 382 var data = this.data( pluginNameSpace ); 383 384 data.animatingNow = false; 385 data.currentSlide.css({zIndex:2, display:'none', opacity:1}); 386 data.nextSlide.css({zIndex:3}); 387 388 //set the current slide 389 data.currentSlide = data.nextSlide; 390 391 //show image caption 392 methods.showCaption.apply( this ); 393 }, 394 395 /************************************************************************ 396 methods.transition: 397 398 switch the slides 399 *************************************************************************/ 400 transition: function(selector, autorotation) 401 { 402 var data = this.data( pluginNameSpace ); 403 404 if(!this.filter(':visible').length) return; 405 406 methods.setSlides.apply( this, [selector] ); 407 408 409 //fade or slide transition 410 if(data.options.transition == 'slide') 411 { 412 methods.moveSlides.apply( this ); 413 } 414 else 415 { 416 methods.fadeSlides.apply( this ); 417 } 418 419 420 421 if('stop_autorotation' == autorotation) 422 { 423 methods.autorotationStop.apply(this); 424 } 425 }, 426 427 /************************************************************************ 428 methods.bindEvents: 429 430 bind all events for the slider 431 *************************************************************************/ 432 bindEvents: function() 433 { 434 var current = this, data = this.data( pluginNameSpace ); 435 436 //when any link within the slideshow is clicked stop the autorotation 437 this.find('a').bind('click.'+pluginNameSpace, function(){ methods.autorotationStop.apply(current); }); 438 439 //show videos 440 data.slides.bind('click.'+pluginNameSpace, function() 441 { 442 var clicked_item = $(this); 443 444 if(clicked_item.is('.comboslide')) 445 { 446 methods.showvideo.apply(current, [clicked_item]); 447 methods.autorotationStop.apply(current); 448 return false; 449 } 450 }); 451 //hide captions when showing videos 452 data.slides.filter('.comboslide, .videoslide').hover( 453 454 function() 455 { 456 $(this).find('.slideshow_caption').stop().animate({opacity:0}
456); 457 }, 458 function() 459 { 460 $(this).find('.slideshow_caption').stop().animate({opacity:1}); 461 } 462 463 ); 464 465 //bind nextslide buttons 466 current.find('.nextSlide').bind('click.'+pluginNameSpace, function() 467 { 468 methods.transition.apply(current, ['next','stop_autorotation']); 469 return false; 470 }); 471 472 473 474 //bind controll clicks 475 if(data.controlls && data.controlls.length) 476 { 477 //bind controll clicks 478 data.controlls.bind('click.'+pluginNameSpace, function() 479 { 480 var selector = this.hash.substr(1); 481 methods.transition.apply(current, [selector, 'stop_autorotation']); 482 return false; 483 }); 484 } 485 486 //bind arrowControll clicks 487 if(data.arrowControlls && data.arrowControlls.next.length) 488 { 489 //bind arrowControll clicks 490 data.arrowControlls.next.bind('click.'+pluginNameSpace, function(){ methods.transition.apply(current, ['next','stop_autorotation']); return false; }); 491 data.arrowControlls.prev.bind('click.'+pluginNameSpace, function(){ methods.transition.apply(current, ['prev','stop_autorotation']); return false; }); 492 data.arrowControlls.play.bind('click.'+pluginNameSpace, function(){ methods.switchAutorotation.apply(current); return false; }); 493 494 495 //hide arrows if mouse cursor is not hovering slider area 496 if(data.options.hideArrows) 497 { 498 data.arrowControlls.all.css({opacity:0}); 499 current.parent('.slideshow_container').hover( 500 501 function() 502 { 503 data.arrowControlls.all.stop().animate({'opacity':1}); 504 }, 505 function(event) 506 { 507 if(!$(event.relatedTarget).is('.ctrl_arrow')) 508 { 509 data.arrowControlls.all.stop().animate({'opacity':0}); 510 } 511 } 512 ); 513 } 514 } 515 516 517 518 519 520 }, 521 522 /************************************************************************ 523 methods.showvideo: 524 525 hide image and show video instead 526 *************************************************************************/ 527 showvideo: function(clicked_item) 528 { 529 var data = this.data( pluginNameSpace ); 530 531 clicked_item.find('img, canvas, .slideshow_overlay, .'+data.options.captionClass).stop().fadeOut(); 532 clicked_item.find('.slideshow_video').stop().fadeIn(); 533 534 }, 535 536 537 /************************************************************************ 538 methods.modifyHeight: 539 540 changes the height of the slideshow in case an image is smaller or bigger 541 than the slideshow container 542 *************************************************************************/ 543 modifyHeight: function(whichSlidePassed) 544 { 545 var data = this.data( pluginNameSpace ), 546 current = this, 547 slide = whichSlidePassed || data.nextSlide; 548 549 if(data.options.resizeSlider) 550 { 551 var item = slide.find('img'), 552 video = slide.find('iframe, object, embed'), 553 sliderWidth = this.width(); 554 555 if(video.length && !item.length) 556 { 557 var videoHeight = (sliderWidth / 16) * 9; 558 video.css({height: videoHeight}); 559 item = video; 560 } 561 562 if(item.length) 563 { 564 var itemHeight = item.height(); 565 current.animate({height: itemHeight}, 600, data.options.defaultEasing, function() 566 { 567 var ratio = current.width() / current.height(); 568 $(window).unbind('resize.'+pluginNameSpace).bind('resize.'+pluginNameSpace, function() 569 { 570 var newheight = current.width() / ratio; 571 if(current.width() > 0) 572 { 573 current.height(newheight); 574 } 575 }) 576 }); 577 } 578 } 579 }, 580 581 582 /************************************************************************ 583 methods.overwrite_defaults: 584 585 lets you overwrite options for multiple sliders on one page with different 586 settings, without the need to call the slider function multiple times 587 *************************************************************************/ 588 overwrite_options: function() 589 { 590 var data = this.data( pluginNameSpace ), 591 optionsWrapper = this.parents('.slideshow_container:eq(0)'); 592 593 if(optionsWrapper.length) 594 { 595 var autoInterval = /autoslidedelay__(\d+)/; 596 var matchInterval = autoInterval.exec(optionsWrapper[0].className); 597 598 if(matchInterval != null) { data.options.autorotationSpeed = matchInterval[1]; }
599 if(optionsWrapper.is('.autoslide_false')) data.options.autorotation = false; 600 if(optionsWrapper.is('.autoslide_true')) data.options.autorotation = true; 601 if(optionsWrapper.is('.auto_height')) data.options.resizeSlider = true; 602 if(optionsWrapper.is('.caption_full_opa')) data.options.captionOpacity = 1; 603 if(optionsWrapper.is('.transition_slide')) data.options.transition = 'slide'; 604 605 } 606 } 607 608 }; 609 610 611 612 $.fn.avia_fade_slider = function(options) 613 { 614 return this.each(function() 615 { 616 var slider = $(this), data = {}, 617 618 //default slideshow settings. can be overwritten by passing different values when calling the function 619 defaults = 620 { 621 slides: 'li', // wich element inside the container should serve as slide 622 animationSpeed: 600, // animation duration 623 autorotation: true, // autorotation true or false? 624 autorotationSpeed: 3, // duration between autorotation switch in Seconds 625 appendControlls: true, // should slidecontrolls be appended or should we use none/predefined, 626 appendCaption: false, // should a caption be created by using the slideshow images alt tag?, 627 captionOpacity: 0.8, 628 hideArrows: true, //hide slidecontroll arrows if mouse is not located over slider 629 resizeSlider: true, //resizes the slider height, in case we got different sized preview images 630 defaultEasing: 'easeOutQuint', // default easing for animations 631 captionClass: 'slideshow_caption',// caption class 632 transition: 'fade' // transition type 633 }; 634 635 //merge default options and options passed by the user, then collect some slider data 636 data.options = $.extend(defaults, options); 637 data.slides = slider.find(data.options.slides).css({display:'none'}); 638 data.slideCount = data.slides.length; 639 data.currentSlide = slider.find(data.options.slides + ':eq(0)').css({display:'block'}); 640 data.nextSlide = slider.find(data.options.slides + ':eq(1)'); 641 data.interval = false; 642 data.animatingNow = true; 643 644 645 //apply data to the slider to keep track of variables and states 646 slider.data( pluginNameSpace, data ); 647 648 //overwrite options with slider specific options if necessary 649 methods.overwrite_options.apply( slider ); 650 651 //initialize the slideshow 652 methods.init.apply( slider ); 653 }); 654 }; 655})(jQuery);
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.