1/* ====================================================================================================================================================== 2Avia Slideshow 3====================================================================================================================================================== */ 4 5(function($) 6{ 7 "use strict"; 8 9 $.AviaSlider = function(options, slider) 10 { 11 var self = this; 12 13 this.$win = $( window ); 14 15 this.$slider = $( slider ); 16 17 this.isMobile = $.avia_utilities.isMobile; 18 19 this._prepareSlides(options); 20 21 //default preload images then init slideshow 22 $.avia_utilities.preload({container: this.$slider, single_callback: function(){ self._init( options ); }}); 23 }; 24 25 $.AviaSlider.defaults = { 26 27 28 //interval between autorotation switches 29 interval:5, 30 31 //autorotation active or not 32 autoplay:false, 33 34 //set if the loop will stop at the last/first slide or if the slides will loop infinite 35 //set to false for infinite loop, "last" to stop at the last slide or "first" to stop at the first slide 36 stopinfiniteloop: false, 37 38 //fade or slide animation 39 animation:'slide', 40 41 //transition speed when switching slide 42 transitionSpeed:900, 43 44 //easing method for the transition 45 easing:'easeInOutQuart', 46 47 //slide wrapper 48 wrapElement: '>ul', 49 50 //slide element 51 slideElement: '>li', 52 53 //pause if mouse cursor is above item 54 hoverpause: false, 55 56 //attach images as background 57 bg_slider: false, 58 59 //delay of milliseconds to wait before showing the next slide 60 show_slide_delay: 0, 61 62 //if slider animation is set to "fade" the fullfade property sets the crossfade behaviour 63 fullfade: false, 64 65 //enable carousel mode with multiple visible slides 66 carousel: 'no', 67 68 // how many slides are displayed at once in the carousel 69 carouselSlidesToShow: 3, 70 71 // TODO: how many slides are scrolled in the carousel 72 carouselSlidesToScroll: 1, 73 74 // responsive carousel 75 carouselResponsive : new Array() 76 77 }; 78 79 $.AviaSlider.prototype = 80 { 81 _init: function( options ) 82 { 83 // set slider options 84 this.options = this._setOptions(options); 85 86 //slidewrap 87 this.$sliderUl = this.$slider.find(this.options.wrapElement); 88 89 // slide elements 90 this.$slides = this.$sliderUl.find(this.options.slideElement); 91 92 // goto dots 93 this.gotoButtons = this.$slider.find('.avia-slideshow-dots a'); 94 95 //perma caption 96 this.permaCaption = this.$slider.find('>.av-slideshow-caption'); 97 98 // slide count 99 this.itemsCount = this.$slides.length; 100 101 // current image index 102 this.current = 0; 103 104 // current carousel index 105 this.currentCarousel = 0; 106 107 // carousel slide width 108 this.slideWidthCarousel = '240'; 109 110 //loop count 111 this.loopCount = 0; 112 113 // control if the slicebox is animating 114 this.isAnimating = false; 115 116 // css browser prefix like -webkit-, -moz- 117 this.browserPrefix = $.avia_utilities.supports('transition'); 118 119 // css3 animation? 120 this.cssActive = this.browserPrefix !== false ? true : false; 121 122 // css3D animation? 123 this.css3DActive = document.documentElement.className.indexOf('avia_transform3d') !== -1 ? true : false; 124 125 //if we have a bg slider no images were preloaded yet. in that case start preloading and attaching images 126 if(this.options.bg_slider == true) 127 { 128 //create array that holds all image urls to preload 129 this.imageUrls = []; 130 131 //create a preloader icon to indicate loading 132 this.loader = $.avia_utilities.loading(this.$slider); 133 134 //preload the images ony by one 135 this._bgPreloadImages(); 136 137 } 138 else //if it was a default slider all images are already loaded and we can start showing the slider 139 { 140 //kickoff the slider: bind functions, show first slide, if active start the autorotation timer 141 this._kickOff(); 142 } 143 144 if(this.options.carousel === 'yes') 145 { 146 this.options.animation = 'carouselslide'; 147 } 148 }, 149 150 //set the slider options by first merging the default options and the passed options, then checking the slider element if any data attributes overwrite the option set 151 _setOptions: function(options) 152 { 153 var newOptions = $.extend( true, {}, $.AviaSlider.defaults, options ), 154 htmlData = this.$slider.data(); 155 156 //overwrite passed option set with any data properties on the html element 157 for( var i in htmlData ) 158 { 159 // data attribute is transformed to lower case, but js is case sensitive - transform key 160 var key = ( 'transition_speed' != i ) ? i :'transitionSpeed'; 161 162 if( typeof htmlData[ i ] === "string" || typeof htmlData[ i ] === "number" || typeof htmlData[ i ] === "boolean" ) 163 { 164 newOptions[ key ] = htmlData[ i ]; 165 } 166 167 } 168 169 return newOptions; 170 }, 171 172 _prepareSlides: function(options) 173 { 174 //if its a mobile device find all video slides that need to be altered 175 if(this.isMobile) 176 { 177 var alter = this.$slider.find('.av-mobile-fallback-image'); 178 alter.each(function() 179 { 180 var current = $(this).removeClass('av-video-slide').data({'avia_video_events': true, 'video-ratio':0}), 181 fallback = current.data('mobile-img'), 182 fallback_link = current.data('fallback-link'), 183 appendTo = current.find('.avia-slide-wrap'); 184 185 current.find('.av-click-overlay, .mejs-mediaelement, .mejs-container').remove(); 186 187 if(!fallback) 188 { 189 $('<p class="av-fallback-message"><span>Please set a mobile device fallback image for this video in your wordpress backend</span></p>').appendTo(appendTo); 190 } 191 192 if(options && options.bg_slider) 193 { 194 current.data('img-url', fallback); 195
196 //if we got a fallback link we need to either replace the default link on mobile devices, or if there is no default link change the wrapping <div> to an <a> 197 if(fallback_link != "") 198 { 199 if(appendTo.is('a')) 200 { 201 appendTo.attr('href', fallback_link); 202 } 203 else 204 { 205 appendTo.find('a').remove(); 206 appendTo.replaceWith(function(){ 207 var cur_slide = $(this); 208 return $("<a>").attr({'data-rel': cur_slide.data('rel'), 'class': cur_slide.attr('class'), 'href': fallback_link} ).append( $(this).contents() ); 209 }); 210 211 appendTo = current.find('.avia-slide-wrap'); 212 } 213 214 if($.fn.avia_activate_lightbox) 215 { 216 current.parents('#main').avia_activate_lightbox(); 217 } 218 } 219 } 220 else 221 { 222 var image = '<img src="'+fallback+'" alt="" title="" />'; 223 var lightbox = false; 224 225 if( 'string' == typeof fallback_link && fallback_link.trim() != '' ) 226 { 227 if( appendTo.is('a') ) 228 { 229 appendTo.attr('href', fallback_link); 230 } 231 else 232 { 233 var rel = fallback_link.match(/\.(jpg|jpeg|gif|png)$/i) != null ? ' rel="lightbox" ' : ''; 234 image = '<a href="' + fallback_link.trim() + '"' + rel + '>' + image + '</a>'; 235 } 236 lightbox = true; 237 } 238 239 current.find('.avia-slide-wrap').append(image); 240 241 if( lightbox && $.fn.avia_activate_lightbox) 242 { 243 current.parents('#main').avia_activate_lightbox(); 244 } 245 } 246 247 }); 248 } 249 250 }, 251 252 //start preloading the background images 253 _bgPreloadImages : function(callback) 254 { 255 this._getImageURLS(); 256 257 this._preloadSingle(0, function() 258 { 259 this._kickOff(); 260 this._preloadNext(1); 261 }); 262 }, 263 264 //if we are using a background image slider, fetch the images from a data attribute and preload them one by one 265 _getImageURLS: function() 266 { 267 var _self = this; 268 269 //collect url strings of the images to preload 270 this.$slides.each(function(i) 271 { 272 _self.imageUrls[i] = []; 273 _self.imageUrls[i]['url'] = $(this).data("img-url"); 274 275 //if no image is passed we can set the slide to loaded 276 if(typeof _self.imageUrls[i]['url'] == 'string') 277 { 278 _self.imageUrls[i]['status'] = false; 279 } 280 else 281 { 282 _self.imageUrls[i]['status'] = true; 283 } 284 }); 285 }, 286 287 288 _preloadSingle: function(key, callback) 289 { 290 var _self = this, 291 objImage = new Image(); 292 293 if(typeof _self.imageUrls[key]['url'] == 'string') 294 { 295 $(objImage).on('load error', function() 296 { 297 _self.imageUrls[key]['status'] = true; 298 _self.$slides.eq(key).css('background-image','url(' + _self.imageUrls[key]['url'] + ')'); 299 if(typeof callback == 'function') callback.apply( _self, [objImage, key] ); 300 }); 301 302 if(_self.imageUrls[key]['url'] != "") 303 { 304 objImage.src = _self.imageUrls[key]['url']; 305 } 306 else 307 { 308 $(objImage).trigger('error'); 309 } 310 } 311 else 312 { 313 if(typeof callback == 'function') callback.apply( _self, [objImage, key] ); 314 } 315 }, 316 317 _preloadNext: function(key) 318 { 319 if(typeof this.imageUrls[key] != "undefined") 320 { 321 this._preloadSingle(key, function() 322 { 323 this._preloadNext(key + 1); 324 }); 325 } 326 }, 327 328 329 //bind click events of slide controlls to the public functions 330 _bindEvents: function() 331 { 332 var self = this, 333 win = $( window ); 334 335 this.$slider.on('click','.next-slide', $.proxy( this.next, this) ); 336 this.$slider.on('click','.prev-slide', $.proxy( this.previous, this) ); 337 this.$slider.on('click','.goto-slide', $.proxy( this.go2, this) ); 338 339 if(this.options.hoverpause) 340 { 341 this.$slider.on('mouseenter', $.proxy( this.pause, this) ); 342 this.$slider.on('mouseleave', $.proxy( this.resume, this) ); 343 } 344 345 if(this.options.stopinfiniteloop && this.options.autoplay) 346 { 347 if(this.options.stopinfiniteloop == 'last') 348 { 349 this.$slider.on('avia_slider_last_slide', $.proxy(this._stopSlideshow, this) ); 350 } 351 else if(this.options.stopinfiniteloop == 'first') 352 { 353 this.$slider.on('avia_slider_first_slide', $.proxy(this._stopSlideshow, this) ); 354 } 355 } 356 357 if (this.options.carousel === 'yes'){ 358 // recalculate carousel dimensions on viewport size change 359 // use on desktop only, debouncedresize fires on scroll on mobile 360 if (!this.isMobile) 361 { 362 win.on( 'debouncedresize', $.proxy( this._buildCarousel, this) ); 363 } 364 } 365 else{ 366 win.on( 'debouncedresize.aviaSlider', $.proxy( this._setSize, this) ); 367 } 368 369 370 //if its a desktop browser add arrow navigation, otherwise add touch nav 371 if(!this.isMobile) 372 { 373 this.$slider.avia_keyboard_controls(); 374 } 375 else 376 { 377 this.$slider.avia_swipe_trigger(); 378 } 379 380 self._attach_video_events(); 381 }, 382 383 //kickoff the slider by binding all functions to slides and buttons, show the first slide and start autoplay 384 _kickOff: function() 385 { 386 var self = this, 387 first_slide = self.$slides.eq(0), 388 video = first_slide.data('video-ratio'); 389 390 // bind events to to the controll buttons 391 self._bindEvents(); 392 393 this.$slider.removeClass('av-default-height-applied'); 394 395 //show the first slide. if its a video set the correct size, otherwise make sure to remove the % padding 396 if(video) 397 { 398 self._setSize(true); 399 } 400 else 401 { 402 if(this.options.keep_pading != true) 403 { 404 self.$sliderUl.css('padding',0); 405 self.$win.trigger('av-height-change'); 406 } 407 } 408 409 self._setCenter(); 410 if ( this.options.carousel === 'no' ) { 411 first_slide.css({visibility:'visible', opacity:0}
411).avia_animate({opacity:1}, function() 412 { 413 var current = $(this).addClass('active-slide'); 414 415 if(self.permaCaption.length) 416 { 417 self.permaCaption.addClass('active-slide'); 418 } 419 }); 420 } 421 422 423 // start autoplay if active 424 if( self.options.autoplay ) 425 { 426 self._startSlideshow(); 427 } 428 429 // prepare carousel if active 430 if (self.options.carousel === 'yes') { 431 self._buildCarousel(); 432 } 433 434 self.$slider.trigger('_kickOff'); 435 436 }, 437 438 _buildCarousel : function(){ 439 440 var self = this, 441 stageWidth = this.$slider.outerWidth(), 442 slidesWidth = parseInt(stageWidth / this.options.carouselSlidesToShow), 443 windowWidth = window.innerWidth || $(window).width(); 444 445 446 // responsive carousel 447 if ( this.options.carouselResponsive && 448 this.options.carouselResponsive.length && 449 this.options.carouselResponsive !== null) { 450 451 for (var breakpoint in this.options.carouselResponsive){ 452 var breakpointValue = this.options.carouselResponsive[breakpoint]['breakpoint']; 453 var newSlidesToShow = this.options.carouselResponsive[breakpoint]['settings']['carouselSlidesToShow']; 454 455 if (breakpointValue >= windowWidth) { 456 slidesWidth = parseInt(stageWidth / newSlidesToShow); 457 this.options.carouselSlidesToShow = newSlidesToShow; 458 } 459 } 460 } 461 462 // set width and height for each slide 463 this.slideWidthCarousel = slidesWidth; 464 465 this.$slides.each(function(i){ 466 $(this).width(slidesWidth); 467 }); 468 469 // set width for the UL 470 var slideTrackWidth = slidesWidth * this.itemsCount; 471 this.$sliderUl.width(slideTrackWidth).css('transform', 'translateX(0px)'); 472 473 // hide nav if not needed 474 if (this.options.carouselSlidesToShow >= this.itemsCount){ 475 this.$slider.find('.av-timeline-nav').hide(); 476 } 477 478 }, 479 480 //calculate which slide should be displayed next and call the executing transition function 481 _navigate : function( dir, pos ) { 482 483 if( this.isAnimating || this.itemsCount < 2Â || !this.$slider.is(":visible") ) 484 { 485 return false; 486 } 487 488 this.isAnimating = true; 489 490 // current item's index 491 this.prev = this.current; 492 493 // if position is passed 494 if( pos !== undefined ) 495 { 496 this.current = pos; 497 dir = this.current > this.prev ? 'next' : 'prev'; 498 } 499 500 // if not check the boundaries 501 else if( dir === 'next' ) 502 { 503 this.current = this.current < this.itemsCount - 1 ? this.current + 1 : 0; 504 505 if( this.current === 0 && this.options.autoplay_stopper == 1 && this.options.autoplay ) 506 { 507 this.isAnimating = false; 508 this.current = this.prev; 509 this._stopSlideshow(); 510 return false; 511 } 512 } 513 else if( dir === 'prev' ) 514 { 515 this.current = this.current > 0 ? this.current - 1 : this.itemsCount - 1; 516 } 517 518 //set goto button 519 this.gotoButtons.removeClass('active').eq(this.current).addClass('active'); 520 521 //set slideshow size if carousel not in use 522 if( this.options.carousel === 'no') { 523 this._setSize(); 524 } 525 526 //if we are using a background slider make sure that the image is loaded. if not preload it, then show the slide 527 if(this.options.bg_slider == true) 528 { 529 if(this.imageUrls[this.current]['status'] == true ) 530 { 531 this['_' + this.options.animation].call(this, dir); 532 } 533 else 534 { 535 this.loader.show(); 536 this._preloadSingle(this.current, function() 537 { 538 this['_' + this.options.animation].call(this, dir); 539 this.loader.hide(); 540 }); 541 } 542 } 543 else //no background loader -> images are already loaded 544 { 545 //call the executing function. for example _slide, or _fade. since the function call is absed on a var we can easily extend the slider with new animations 546 this['_' + this.options.animation].call(this, dir); 547 } 548 549 if(this.current == 0) 550 { 551 this.loopCount++; 552 this.$slider.trigger('avia_slider_first_slide'); 553 } 554 else if(this.current == this.itemsCount - 1) 555 { 556 this.$slider.trigger('avia_slider_last_slide'); 557 } 558 else 559 {
560 this.$slider.trigger('avia_slider_navigate_slide'); 561 } 562 }, 563 564 //if the next slide has a different height than the current change the slideshow height 565 _setSize: function(instant) 566 { 567 //if images are attached as bg images the slider has a fixed height 568 if(this.options.bg_slider == true) return; 569 570 var self = this, 571 slide = this.$slides.eq(this.current), 572 img = slide.find('img'), 573 current = Math.floor(this.$sliderUl.height()), 574 ratio = slide.data('video-ratio'), 575 setTo = ratio ? this.$sliderUl.width() / ratio : Math.floor(slide.height()), 576 video_height = slide.data('video-height'), //forced video height %. needs to be set only once 577 video_toppos = slide.data('video-toppos'); //forced video top position 578 579 this.$sliderUl.height(current).css('padding',0); //make sure to set the slideheight to an actual value 580 581 if(setTo != current) 582 { 583 if(instant == true) 584 { 585 this.$sliderUl.css({height:setTo}); 586 this.$win.trigger('av-height-change'); 587 } 588 else 589 { 590 this.$sliderUl.avia_animate({height:setTo}, function() 591 { 592 self.$win.trigger('av-height-change'); 593 }); 594 } 595 } 596 597 this._setCenter(); 598 599 if(video_height && video_height!= "set") 600 { 601 slide.find('iframe, embed, video, object, .av_youtube_frame').css({height: video_height + '%', top: video_toppos + '%'}); 602 slide.data('video-height','set'); 603 } 604 }, 605 606 _setCenter: function() 607 { 608 //if the image has a min width and is larger than the slider center it 609 //positon img based on caption. right caption->left pos, left caption -> right pos 610 var slide = this.$slides.eq(this.current), 611 img = slide.find('img'), 612 min_width = parseInt(img.css('min-width'),10), 613 slide_width = slide.width(), 614 caption = slide.find('.av-slideshow-caption'), 615 css_left = ((slide_width - min_width) / 2); 616 617 if(caption.length) 618 { 619 if(caption.is('.caption_left')) 620 { 621 css_left = ((slide_width - min_width) / 1.5); 622 } 623 else if(caption.is('.caption_right')) 624 { 625 css_left = ((slide_width - min_width) / 2.5); 626 } 627 } 628 629 if(slide_width >= min_width) 630 { 631 css_left = 0; 632 } 633 634 img.css({left:css_left}); 635 }, 636 637 _carouselmove : function(){ 638 639 // var offset = (this.options.carouselSlidesToScroll*this.slideWidthCarousel)*this.currentCarousel; 640 var offset = this.slideWidthCarousel*this.currentCarousel; 641 this.$sliderUl.css('transform', 'translateX(-'+offset+'px)'); 642 643 }, 644 645 _carouselslide: function(dir){ 646 647 if (dir === 'next') { 648 649 if (this.options.carouselSlidesToShow + this.currentCarousel < this.itemsCount){ 650 this.currentCarousel++; 651 this._carouselmove(); 652 } 653 } 654 else if (dir === 'prev'){ 655 if (this.currentCarousel > 0) { 656 this.currentCarousel--; 657 this._carouselmove(); 658 } 659 } 660 661 this.isAnimating = false; 662 663 }, 664 665 _slide: function(dir) 666 { 667 var dynamic = false, //todo: pass by option if a slider is dynamic 668 modifier = dynamic == true ? 2 : 1, 669 sliderWidth = this.$slider.width(), 670 direction = dir === 'next' ? -1 : 1, 671 property = this.browserPrefix + 'transform', 672 reset = {}, transition = {}, transition2 = {}, 673 trans_val = ( sliderWidth * direction * -1), 674 trans_val2 = ( sliderWidth * direction) / modifier; 675 676 //do a css3 animation 677 if(this.cssActive) 678 { 679 property = this.browserPrefix + 'transform'; 680 681 //do a translate 3d transformation if available, since it uses hardware acceleration 682 if(this.css3DActive) 683 { 684 reset[property] = "translate3d(" + trans_val + "px, 0, 0)"; 685 transition[property] = "translate3d(" + trans_val2 + "px, 0, 0)"; 686 transition2[property] = "translate3d(0,0,0)"; 687 } 688 else //do a 2d transform. still faster than a position "left" change 689 { 690 reset[property] = "translate(" + trans_val + "px,0)"; 691 transition[property] = "translate(" + trans_val2 + "px,0)"; 692 transition2[property] = "translate(0,0)"; 693 } 694 } 695 else 696 {
697 reset.left = trans_val; 698 transition.left = trans_val2; 699 transition2.left = 0; 700 } 701 702 if(dynamic) 703 { 704 transition['z-index'] = "1"; 705 transition2['z-index'] = "2"; 706 } 707 708 this._slide_animate(reset, transition, transition2); 709 }, 710 711 _slide_up: function(dir) 712 { 713 var dynamic = true, //todo: pass by option if a slider is dynamic 714 modifier = dynamic == true ? 2 : 1, 715 sliderHeight = this.$slider.height(), 716 direction = dir === 'next' ? -1 : 1, 717 property = this.browserPrefix + 'transform', 718 reset = {}, transition = {}, transition2 = {}, 719 trans_val = ( sliderHeight * direction * -1), 720 trans_val2 = ( sliderHeight * direction) / modifier; 721 722 //do a css3 animation 723 if(this.cssActive) 724 { 725 property = this.browserPrefix + 'transform'; 726 727 //do a translate 3d transformation if available, since it uses hardware acceleration 728 if(this.css3DActive) 729 { 730 reset[property] = "translate3d( 0," + trans_val + "px, 0)"; 731 transition[property] = "translate3d( 0," + trans_val2 + "px, 0)"; 732 transition2[property] = "translate3d(0,0,0)"; 733 } 734 else //do a 2d transform. still faster than a position "left" change 735 { 736 reset[property] = "translate( 0," + trans_val + "px)"; 737 transition[property] = "translate( 0," + trans_val2 + "px)"; 738 transition2[property] = "translate(0,0)"; } 739 } 740 else 741 { 742 reset.top = trans_val; 743 transition.top = trans_val2; 744 transition2.top = 0; 745 } 746 747 if(dynamic) 748 { 749 transition['z-index'] = "1"; 750 transition2['z-index'] = "2"; 751 } 752 this._slide_animate(reset, transition, transition2); 753 }, 754 755 756 //slide animation: do a slide transition by css3 transform if possible. if not simply do a position left transition 757 _slide_animate: function( reset , transition , transition2 ) 758 { 759 760 var self = this, 761 displaySlide = this.$slides.eq(this.current), 762 hideSlide = this.$slides.eq(this.prev); 763 764 hideSlide.trigger('pause'); 765 if( !displaySlide.data('disableAutoplay') ) { 766 767 if(displaySlide.hasClass('av-video-lazyload') && !displaySlide.hasClass('av-video-lazyload-complete')) 768 { 769 displaySlide.find('.av-click-to-play-overlay').trigger('click'); 770 } 771 else 772 { 773 displaySlide.trigger('play'); 774 } 775 } 776 777 displaySlide.css({visibility:'visible', zIndex:4, opacity:1, left
777:0, top:0}); 778 displaySlide.css(reset); 779 780 hideSlide.avia_animate(transition, this.options.transitionSpeed, this.options.easing); 781 782 var after_slide = function() 783 { 784 self.isAnimating = false; 785 displaySlide.addClass('active-slide'); 786 hideSlide.css({visibility:'hidden'}).removeClass('active-slide'); 787 self.$slider.trigger('avia-transition-done'); 788 }; 789 790 if(self.options.show_slide_delay > 0) 791 { 792 setTimeout(function() { displaySlide.avia_animate(transition2, self.options.transitionSpeed, self.options.easing, after_slide); },self.options.show_slide_delay); 793 } 794 else 795 { 796 displaySlide.avia_animate(transition2, self.options.transitionSpeed, self.options.easing, after_slide); 797 } 798 799 }, 800 801 //simple fade transition of the slideshow 802 _fade: function() 803 { 804 var self = this, 805 displaySlide = this.$slides.eq(this.current), 806 hideSlide = this.$slides.eq(this.prev), 807 properties = {visibility:'visible', zIndex:3, opacity:0}, 808 fadeCallback = function() 809 { 810 self.isAnimating = false; 811 displaySlide.addClass('active-slide'); 812 hideSlide.css({visibility:'hidden', zIndex:2}).removeClass('active-slide'); 813 self.$slider.trigger('avia-transition-done'); 814 815 }; 816 817 hideSlide.trigger('pause'); 818 if( !displaySlide.data('disableAutoplay') ) { 819 820 if(displaySlide.hasClass('av-video-lazyload') && !displaySlide.hasClass('av-video-lazyload-complete')) 821 { 822 displaySlide.find('.av-click-to-play-overlay').trigger('click'); 823 } 824 else 825 { 826 displaySlide.trigger('play'); 827 } 828 } 829 830 if(self.options.fullfade == true) 831 { 832 hideSlide.avia_animate({opacity:0}
832, 200, 'linear', function() 833 { 834 displaySlide.css(properties).avia_animate({opacity:1}, self.options.transitionSpeed, 'linear',fadeCallback); 835 }); 836 } 837 else 838 { 839 if (self.current === 0) { 840 hideSlide.avia_animate({opacity:0}, self.options.transitionSpeed/2, 'linear'); 841 displaySlide.css(properties).avia_animate({opacity:1}, self.options.transitionSpeed/2, 'linear',fadeCallback); 842 } 843 else{ 844 displaySlide.css(properties).avia_animate({opacity:1}, self.options.transitionSpeed/2, 'linear', function() 845 { 846 hideSlide.avia_animate({opacity:0}, 200, 'linear', fadeCallback); 847 }); 848 } 849 850 } 851 852 }, 853 854 855 /************************************************************************ 856 Video functions 857 *************************************************************************/ 858 859 //bind events to the video that tell the slider to autorotate once a video has been played 860 _attach_video_events: function() 861 { 862 var self = this, $html = $('html'); 863 864 self.$slides.each(function(i) 865 { 866 var currentSlide = $(this), 867 caption = currentSlide.find('.caption_fullwidth, .av-click-overlay'), 868 mejs = currentSlide.find('.mejs-mediaelement'), 869 lazyload = currentSlide.hasClass('av-video-lazyload') ? true : false; 870 871 872 if(currentSlide.data('avia_video_events') != true) 873 { 874 currentSlide.data('avia_video_events', true); 875 876 currentSlide.on('av-video-events-bound', { slide: currentSlide, wrap: mejs , iteration: i , self: self, lazyload: lazyload }, onReady); 877 878 currentSlide.on('av-video-ended', { slide: currentSlide , self: self}, onFinish); 879 880 currentSlide.on('av-video-play-executed', function(){ setTimeout( function(){ self.pause(); }, 100 ); } ); 881 882 caption.on('click', { slide: currentSlide }, toggle); 883 884 // also if the player was loaded before the _bindEvents function was bound trigger it manually 885 if(currentSlide.is('.av-video-events-bound')) currentSlide.trigger('av-video-events-bound'); 886 887 //if we are on the first slide and autoplay is enabled and lazy loading is enabled we need to simulate a click event to the lazy load container 888 if(lazyload && i === 0 && !currentSlide.data('disableAutoplay')) 889 { 890 currentSlide.find('.av-click-to-play-overlay').trigger('click'); 891 } 892 } 893 }); 894 895 896 //function that takes care of events once the video is loaded for the first time. 897 //needs to take into account 2 different scenarios: normally embedded videos or lazyloaded videos that start on user interaction/autoplay 898 function onReady( event ) 899 { 900 //autostart for first slide 901 if(event.data.iteration === 0) 902 { 903 event.data.wrap.css('opacity',0); 904 if(!event.data.self.isMobile && !event.data.slide.data('disableAutoplay')) 905 { 906 event.data.slide.trigger('play'); 907 }Â 908 setTimeout(function(){ event.data.wrap.avia_animate({opacity:1}, 400); }, 50); 909 } 910 else if ($html.is('.avia-msie') && !event.data.slide.is('.av-video-service-html5')) 911 { 912 /* 913 * Internet Explorer fires the ready event for external videos once they become visible 914 * as oposed to other browsers which always fire immediately. 915 */ 916 if( !event.data.slide.data('disableAutoplay') ) event.data.slide.trigger('play'); 917 } 918 919 920 //make sure that the html5 element does not play if autoply is enabled but its not the first slide. 921 //the autoplay attribute on the video element might cause this 922 if(event.data.slide.is('.av-video-service-html5') && event.data.iteration !== 0 ) 923 { 924 event.data.slide.trigger('pause'); 925 } 926 927 //make sure that lazyloaded videos always get started once a user clicks them 928 if(event.data.lazyload) 929 { 930 event.data.slide.addClass('av-video-lazyload-complete'); 931 event.data.slide.trigger('play'); 932 } 933 } 934 935 936 937 938 function onFinish( event ) 939 { 940 //if the video is not looped resume the slideshow 941 if(!event.data.slide.is('.av-single-slide') && !event.data.slide.is('.av-loop-video')) 942 { 943 event.data.slide.trigger('reset'); 944 self._navigate( 'next' ); 945 self.resume(); 946 } 947
948 //safari 8 workaround for self hosted videos which wont loop by default 949 if(event.data.slide.is('.av-loop-video') && event.data.slide.is('.av-video-service-html5')) 950 { 951 if($html.is('.avia-safari-8')) 952 { 953 setTimeout(function(){ event.data.slide.trigger('play'); },1); 954 } 955 } 956 } 957 958 function toggle( event ) 959 { 960 if(event.target.tagName != "A") 961 { 962 event.data.slide.trigger('toggle'); 963 } 964 } 965 966 }, 967 968 969 970 /************************************************************************ 971 Slideshow control functions 972 *************************************************************************/ 973 974 _timer: function(callback, delay, first) 975 { 976 var self = this, start, remaining = delay; 977 978 self.timerId = 0; 979 980 this.pause = function() { 981 window.clearTimeout(self.timerId); 982 remaining -= new Date() - start; 983 }; 984 985 this.resume = function() { 986 start = new Date(); 987 self.timerId = window.setTimeout(callback, remaining); 988 }; 989 990 this.destroy = function() 991 { 992 window.clearTimeout(self.timerId); 993 }; 994 995 this.resume(true); 996 }, 997 998 //start autorotation 999 _startSlideshow: function() 1000 { 1001 var self = this; 1002 1003 this.isPlaying = true; 1004 1005 this.slideshow = new this._timer( function() 1006 { 1007 self._navigate( 'next' ); 1008 1009 if ( self.options.autoplay ) 1010 { 1011 self._startSlideshow(); 1012 } 1013 1014 }, (this.options.interval * 1000)); 1015 }, 1016 1017 //stop autorotation 1018 _stopSlideshow: function() 1019 { 1020 if ( this.options.autoplay ) { 1021 1022 this.slideshow.destroy(); 1023 this.isPlaying = false; 1024 this.options.autoplay = false; 1025 } 1026 }, 1027 1028 // public method: shows next image 1029 next : function(e) 1030 { 1031 e.preventDefault(); 1032 this._stopSlideshow(); 1033 this._navigate( 'next' ); 1034 }, 1035 1036 // public method: shows previous image 1037 previous : function(e) 1038 { 1039 e.preventDefault(); 1040 this._stopSlideshow(); 1041 this._navigate( 'prev' ); 1042 }, 1043 1044 // public method: goes to a specific image 1045 go2 : function( pos ) 1046 { 1047 //if we didnt pass a number directly lets asume someone clicked on a link that triggered the goto transition 1048 if(isNaN(pos)) 1049 { 1050 //in that case prevent the default link behavior and set the slide number to the links hash 1051 pos.preventDefault(); 1052 pos = pos.currentTarget.hash.replace('#',''); 1053 } 1054 1055 pos -= 1; 1056 1057 if( pos === this.current || pos >= this.itemsCount || pos < 0 ) 1058 { 1059 return false; 1060 } 1061 1062 this._stopSlideshow(); 1063 this._navigate( false, pos ); 1064 1065 }, 1066 1067 // public method: starts the slideshow 1068 // any call to next(), previous() or goto() will stop the slideshow autoplay 1069 play : function() 1070 { 1071 if( !this.isPlaying ) 1072 { 1073 this.isPlaying = true; 1074 1075 this._navigate( 'next' ); 1076 this.options.autoplay = true; 1077 this._startSlideshow(); 1078 } 1079 1080 }, 1081 1082 // public methos: pauses the slideshow 1083 pause : function() 1084 { 1085 if( this.isPlaying ) 1086 { 1087 this.slideshow.pause(); 1088 } 1089 }, 1090 1091 // publiccmethos: resumes the slideshow 1092 resume : function() 1093 { 1094 if( this.isPlaying ) 1095 { 1096 this.slideshow.resume(); 1097 } 1098 }, 1099 1100 // public methos: destroys the instance 1101 destroy : function( callback ) 1102 { 1103 this.slideshow.destroy( callback ); 1104 } 1105 1106 }; 1107 1108 //simple wrapper to call the slideshow. makes sure that the slide data is not applied twice 1109 $.fn.aviaSlider = function( options ) 1110 { 1111 return this.each(function() 1112 { 1113 var self = $.data( this, 'aviaSlider' ); 1114 1115 if( ! self ) 1116 { 1117 self = $.data( this, 'aviaSlider', new $.AviaSlider( options, this ) ); 1118 } 1119 }); 1120 }; 1121 1122 1123 1124})( jQuery ); 1125 1126 1127
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.