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