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