PageSourceSearch

https://www.thecge.net/wp-content/themes/enfold/config-templatebuilder/avia-shortcodes/slideshow/slideshow.js

js thecge.net collected 2026-09-24 19:21:23 UTC 36,893 bytes, 1,322 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.