PageSourceSearch

https://eventival.com/wp-content/themes/eventival/assets/plugins/g…/jquery.gridrotator.js?ver=1776331528

js eventival.com collected 2026-10-01 11:24:14 UTC 19,491 bytes, 758 lines download raw bytes

1/**
2 * jquery.gridrotator.js v1.1.0
3 * http://www.codrops.com
4 *
5 * Licensed under the MIT license.
6 * http://www.opensource.org/licenses/mit-license.php
7 * 
8 * Copyright 2012, Codrops
9 * http://www.codrops.com
10 */
11;( function( $, window, undefined ) {
12	
13	'use strict';
14
15	/*
16	* debouncedresize: special jQuery event that happens once after a window resize
17	*
18	* latest version and complete README available on Github:
19	* https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js
20	*
21	* Copyright 2011 @louis_remi
22	* Licensed under the MIT license.
23	*/
24	var $event = $.event,
25	$special,
26	resizeTimeout;
27
28	$special = $event.special.debouncedresize = {
29		setup: function() {
30			$( this ).on( "resize", $special.handler );
31		},
32		teardown: function() {
33			$( this ).off( "resize", $special.handler );
34		},
35		handler: function( event, execAsap ) {
36			// Save the context
37			var context = this,
38				args = arguments,
39				dispatch = function() {
40					// set correct event type
41					event.type = "debouncedresize";
42					$event.dispatch.apply( context, args );
43				};
44
45			if ( resizeTimeout ) {
46				clearTimeout( resizeTimeout );
47			}
48
49			execAsap ?
50				dispatch() :
51				resizeTimeout = setTimeout( dispatch, $special.threshold );
52		},
53		threshold: 100
54	};
55
56	// http://www.hardcode.nl/subcategory_1/article_317-array-shuffle-function
57	Array.prototype.shuffle = function() {
58		var i=this.length,p,t;
59		while (i--) {
60			p = Math.floor(Math.random()*i);
61			t = this[i];
62			this[i]=this[p];
63			this[p]=t;
64		}
65		return this;
66	};
67
68	// HTML5 PageVisibility API
69	// http://www.html5rocks.com/en/tutorials/pagevisibility/intro/
70	// by Joe Marini (@joemarini)
71	function getHiddenProp(){
72		var prefixes = ['webkit','moz','ms','o'];
73
74		// if 'hidden' is natively supported just return it
75		if ('hidden' in document) return 'hidden';
76
77		// otherwise loop over all the known prefixes until we find one
78		for (var i = 0; i < prefixes.length; i++){
79			if ((prefixes[i] + 'Hidden') in document) 
80				return prefixes[i] + 'Hidden';
81		}
82
83		// otherwise it's not supported
84		return null;
85	}
86	function isHidden() {
87		var prop = getHiddenProp();
88		if (!prop) return false;
89
90		return document[prop];
91	}
92
93	function isEmpty( obj ) {
94		return Object.keys(obj).length === 0;
95	}
96
97	// global
98	var $window = $( window ),
99		Modernizr = window.Modernizr;
100
101	$.GridRotator = function( options, element ) {
102		
103		this.$el = $( element );
104		if( Modernizr.backgroundsize ) {
105
106			var self = this;
107			this.$el.addClass( 'ri-grid-loading' );
108			this._init( options );
109
110		}
111		
112	};
113
114	// the options
115	$.GridRotator.defaults = {
116		// number of rows
117		rows : 4,
118		// number of columns 
119		columns : 10,
120		w1024 : { rows : 3, columns : 8 },
121		w768 : {rows : 3,columns : 7 },
122		w480 : {rows : 3,columns : 5 },
123		w320 : {rows : 2,columns : 4 },
124		w240 : {rows : 2,columns : 3 },
125		// step: number of items that are replaced at the same time
126		// random || [some number]
127		// note: for performance issues, the number "can't" be > options.maxStep
128		step : 'random',
129		// change it as you wish..
130		maxStep : 3,
131		// prevent user to click the items
132		preventClick : true,
133		// animation type
134		// showHide || fadeInOut || 
135		// slideLeft || slideRight || slideTop || slideBottom || 
136		// rotateBottom || rotateLeft || rotateRight || rotateTop || 
137		// scale ||
138		// rotate3d ||
139		// rotateLeftScale || rotateRightScale || rotateTopScale || rotateBottomScale || 
140		// random
141		animType : 'random',
142		// animation speed
143		animSpeed : 800,
144		// animation easings
145		animEasingOut : 'linear',
146		animEasingIn: 'linear',
147		// the item(s) will be replaced every 3 seconds
148		// note: for performance issues, the time "can't" be < 300 ms
149		interval : 3000,
150		// if false the animations will not start
151		// use false if onhover is true for example
152		slideshow : true,
153		// if true the items will switch when hovered
154		onhover : false,
155		// ids of elements that shouldn't change
156		nochange : []
157	};
158
159	$.GridRotator.prototype = {
160
161		_init : function( options ) {
162			
163			// options
164			this.options = $.extend( true, {}, $.GridRotator.defaults, options );
165			// cache some elements + variables
166			this._config();
167
168		},
169		_config : function() {
170
171			var self = this,
172				transEndEventNames = {
173					'WebkitTransition' : 'webkitTransitionEnd',
174					'MozTransition' : 'transitionend',
175					'OTransition' : 'oTransitionEnd',
176					'msTransition' : 'MSTransitionEnd',
177					'transition' : 'transitionend'
178				};
179
180			// support CSS transitions and 3d transforms
181			this.supportTransitions = Modernizr.csstransitions;
182			this.supportTransforms3D = Modernizr.csstransforms3d;
183
184			this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.gridrotator';
185
186			// all animation types for the random option
187			this.animTypes = this.supportTransforms3D ? [
188				'fadeInOut',
189				'slideLeft', 
190				'slideRight', 
191				'slideTop', 
192				'slideBottom', 
193				'rotateLeft', 
194				'rotateRight', 
195				'rotateTop', 
196				'rotateBottom', 
197				'scale', 
198				'rotate3d', 
199				'rotateLeftScale', 
200				'rotateRightScale', 
201				'rotateTopScale', 
202				'rotateBottomScale' ] :
203				[ 'fadeInOut', 'slideLeft', 'slideRight', 'slideTop', 'slideBottom' ];
204
205			this.animType = this.options.animType;
206
207			if( this.animType !== 'random' && !this.supportTransforms3D && $.inArray( this.animType, this.animTypes ) === -1 && this.animType !== 'showHide' ) {
208
209				// fallback to 'fadeInOut' if user sets a type which is not supported
210				this.animType = 'fadeInOut';
211
212			}
213
214			this.animTypesTotal	= this.animTypes.length;
215
216			// the <ul> where the items are placed
217			this.$list = this.$el.children( 'ul' );
218			// remove images and add background-image to anchors
219			// preload the images before
220			var loaded = 0,
221				$imgs = this.$list.find( 'img' ),
222				count = $imgs.length;
223
224			$imgs.each( function() {
225
226				var $img = $( this ), src = $img.attr( 'src' );
227
228				$( '<img/>' ).load( function() {
229
230					++loaded;
231					$img.parent().css( 'background-image', 'url(' + src + ')' );
232
233					if( loaded === count ) {
234
235						$imgs.remove();
236						self.$el.removeClass( 'ri-grid-loading' );
237						// the items
238						self.$items = self.$list.children( 'li' );
239						// make a copy of the items
240						self.$itemsCache = self.$items.clone();
241						// total number of items
242						self.itemsTotal = self.$items.length;
243						// the items that will be out of the grid
244						// actually the item's child (anchor element)
245						self.outItems= [];
246						self._layout( function() {
247							self._initEvents();
248						} );
249						// replace [options.step] items after [options.interval] time
250						// the items that go out are randomly chosen, while the ones that get in
251						// follow a "First In First Out" logic
252						self._start();
253
254					}
255
256				} ).attr( 'src', src )
257				 
258			} );
259
260		},
261		_layout : function( callback ) {
262
263			var self = this;
264
265			// sets the grid dimentions based on the container's width
266			this._setGridDim();
267
268			// reset
269			this.$list.empty();
270			this.$items = this.$itemsCache.clone().appendTo( this.$list );
271			
272			var $outItems = this.$items.filter( ':gt(' + ( this.showTotal - 1 ) + ')' ),
273				$outAItems = $outItems.children( 'a' );
274
275			this.outItems.length = 0;
276
277			$outAItems.each( function( i ) {
278				self.outItems.push( $( this ) );
279			} );
280
281			$outItems.remove();
282
283				// container's width
284			var containerWidth = ( document.defaultView ) ? parseInt( document.defaultView.getComputedStyle( this.$el.get( 0 ), null ).width ) : this.$el.width(),
285				// item's width
286				itemWidth = Math.floor( containerWidth / this.columns ),
287				// item's hieght
288				itemHeight = $(".ri-grid-envelope").height() / this.rows,
289				// calculate gap
290				gapWidth = containerWidth - ( this.columns * Math.floor( itemWidth ) );
291
292			for( var i = 0; i < this.rows; ++i ) {
293
294				for( var j = 0; j < this.columns; ++j ) {
295
296					var idx = this.columns * i + j,
297						$item = this.$items.eq( idx );
298
299					$item.css( {
300						width : j < Math.floor( gapWidth ) ? itemWidth + 1 : itemWidth,
301						height : itemHeight
302					} );
303
304					if( $.inArray( idx, this.options.nochange ) !== -1 ) {
305						$item.addClass( 'ri-nochange' ).data( 'nochange', true );
306					}
307
308				}
309
310			}
311
312			if( this.options.preventClick ) {
313
314				this.$items.children().css( 'cursor', 'default' ).on( 'click.gridrotator', false );
315
316			}
317
318			if( callback ) {
319				callback.call();
320			}
321
322		},
323		// set the grid rows and columns
324		_setGridDim	 : function() {
325
326			// container's width
327			var c_w = this.$el.width();
328
329			// we will choose the number of rows/columns according to the container's width and the values set in the plugin options 
330			switch( true ) {
331				case ( c_w < 240 ) : this.rows = this.options.w240.rows; this.columns = this.options.w240.columns; break;
332				case ( c_w < 320 ) : this.rows = this.options.w320.rows; this.columns = this.options.w320.columns; break;
333				case ( c_w < 480 ) : this.rows = this.options.w480.rows; this.columns = this.options.w480.columns; break;
334				case ( c_w < 768 ) : this.rows = this.options.w768.rows; this.columns = this.options.w768.columns; break;
335				case ( c_w < 1024 ) : this.rows = this.options.w1024.rows; this.columns = this.options.w1024.columns; break;
336				default : this.rows = this.options.rows; this.columns = this.options.columns; break;
337			}
338
339			this.showTotal = this.rows * this.columns;
340
341		},
342		// init window resize event
343		_initEvents : function() {
344
345			var self = this;
346
347			$window.on( 'debouncedresize.gridrotator', function() {
348				self._layout();
349			} );
350
351			// use the property name to generate the prefixed event name
352			var visProp = getHiddenProp();
353			
354			// HTML5 PageVisibility API
355			// http://www.html5rocks.com/en/tutorials/pagevisibility/intro/
356			// by Joe Marini (@joemarini)
357			if (visProp) {
358
359				var evtname = visProp.replace(/[H|h]idden/,'') + 'visibilitychange';
360				document.addEventListener(evtname, function() { self._visChange(); } );
361
362			}
363
364			if( !Modernizr.touch && this.options.onhover ) {
365				
366				self.$items.on( 'mouseenter.gridrotator', function() {
367
368					var $item = $( this );
369					if( !$item.data( 'active' ) && !$item.data( 'hovered' ) && !$item.data( 'nochange' ) ) {
370						$item.data( 'hovered', true );
371						self._replace( $item );
372					}
373
374				} ).on( 'mouseleave.gridrotator', function() {
375
376					$( this ).data( 'hovered', false );
377
378				} );
379
380			}
381
382		},
383		_visChange : function() {
384
385			isHidden() ? clearTimeout( this.playtimeout ) : this._start();
386
387		},
388		// start rotating elements
389		_start : function() {
390
391			if( this.showTotal < this.itemsTotal && this.options.slideshow ) {
392				this._showNext();
393			}
394
395		},
396		// get which type of animation
397		_getAnimType : function() {
398
399			return this.animType === 'random' ? this.animTypes[ Math.floor( Math.random() * this.animTypesTotal ) ] : this.animType;
400
401		},
402		// get css properties for the transition effect
403		_getAnimProperties : function( $out ) {
404
405			var startInProp = {}, startOutProp = {}, endInProp = {}, endOutProp = {},
406				animType = this._getAnimType(), speed, delay = 0;
407
408			switch( animType ) {
409
410				case 'showHide' :
411					
412					speed = 0;
413					endOutProp.opacity = 0;
414					break;
415
416				case 'fadeInOut' :
417
418					endOutProp.opacity = 0;
419					break;
420
421				case 'slideLeft' :
422					
423					startInProp.left = $out.width();
424					endInProp.left = 0;
425					endOutProp.left = -$out.width();
426					break;
427
428				case 'slideRight' :
429					
430					startInProp.left = -$out.width();
431					endInProp.left = 0;
432					endOutProp.left = $out.width();
433					break;
434
435				case 'slideTop' :
436					
437					startInProp.top = $out.height();
438					endInProp.top = 0;
439					endOutProp.top = -$out.height();
440					break;
441
442				case 'slideBottom' :
443					
444					startInProp.top = -$out.height();
445					endInProp.top = 0;
446					endOutProp.top = $out.height();
447					break;
448
449				case 'rotateLeft' :
450					
451					speed = this.options.animSpeed / 2;
452					startInProp.transform = 'rotateY(90deg)';
453					endInProp.transform = 'rotateY(0deg)';
454					delay = speed;
455					endOutProp.transform = 'rotateY(-90deg)';
456					break;
457
458				case 'rotateRight' :
459					
460					speed = this.options.animSpeed / 2;
461					startInProp.transform = 'rotateY(-90deg)';
462					endInProp.transform = 'rotateY(0deg)';
463					delay = speed;
464					endOutProp.transform = 'rotateY(90deg)';
465					break;
466
467				case 'rotateTop' :
468					
469					speed = this.options.animSpeed / 2;
470					startInProp.transform= 'rotateX(90deg)';
471					endInProp.transform = 'rotateX(0deg)';
472					delay = speed;
473					endOutProp.transform = 'rotateX(-90deg)';
474					break;
475
476				case 'rotateBottom' :
477					
478					speed = this.options.animSpeed / 2;
479					startInProp.transform = 'rotateX(-90deg)';
480					endInProp.transform = 'rotateX(0deg)';
481					delay = speed;
482					endOutProp.transform = 'rotateX(90deg)';
483					break;
484
485				case 'scale' :
486					
487					speed = this.options.animSpeed / 2;
488					startInProp.transform = 'scale(0)';
489					startOutProp.transform = 'scale(1)';
490					endInProp.transform = 'scale(1)';
491					delay = speed;
492					endOutProp.transform = 'scale(0)';
493					break;
494
495				case 'rotateLeftScale' :
496					
497					startOutProp.transform = 'scale(1)';
498					speed = this.options.animSpeed / 2;	
499					startInProp.transform = 'scale(0.3) rotateY(90deg)';
500					endInProp.transform = 'scale(1) rotateY(0deg)';
501					delay = speed;
502					endOutProp.transform = 'scale(0.3) rotateY(-90deg)';
503					break;
504
505				case 'rotateRightScale' :
506					
507					startOutProp.transform = 'scale(1)';
508					speed = this.options.animSpeed / 2;
509					startInProp.transform = 'scale(0.3) rotateY(-90deg)';
510					endInProp.transform = 'scale(1) rotateY(0deg)';
511					delay = speed;
512					endOutProp.transform = 'scale(0.3) rotateY(90deg)';
513					break;
514
515				case 'rotateTopScale' :
516					
517					startOutProp.transform = 'scale(1)';
518					speed = this.options.animSpeed / 2;
519					startInProp.transform = 'scale(0.3) rotateX(90deg)';
520					endInProp.transform = 'scale(1) rotateX(0deg)';
521					delay = speed;
522					endOutProp.transform = 'scale(0.3) rotateX(-90deg)';
523					break;
524
525				case 'rotateBottomScale' :
526					
527					startOutProp.transform = 'scale(1)';
528					speed = this.options.animSpeed / 2;
529					startInProp.transform = 'scale(0.3) rotateX(-90deg)';
530					endInProp.transform = 'scale(1) rotateX(0deg)';
531					delay = speed;
532					endOutProp.transform = 'scale(0.3) rotateX(90deg)';
533					break;
534
535				case 'rotate3d' :
536					
537					speed = this.options.animSpeed / 2;
538					startInProp.transform = 'rotate3d( 1, 1, 0, 90deg )';
539					endInProp.transform = 'rotate3d( 1, 1, 0, 0deg )';
540					delay = speed;
541					endOutProp.transform = 'rotate3d( 1, 1, 0, -90deg )';
542					break;
543
544			}
545
546			return {
547				startInProp : startInProp,
548				startOutProp : startOutProp,
549				endInProp : endInProp,
550				endOutProp : endOutProp,				
551				delay : delay,
552				animSpeed : speed != undefined ? speed : this.options.animSpeed
553			};
554
555		},
556		// show next [option.step] elements
557		_showNext : function( time ) {
558
559			var self = this;
560
561			clearTimeout( this.playtimeout );
562
563			this.playtimeout = setTimeout( function() {
564
565				var step = self.options.step, max= self.options.maxStep, min = 1;
566				
567				if( max > self.showTotal ) {
568					max = self.showTotal;
569				}
570
571					// number of items to swith at this point of time
572				var nmbOut	= step === 'random' ? Math.floor( Math.random() * max + min ) : Math.min( Math.abs( step ) , max ) ,
573					// array with random indexes. These will be the indexes of the items we will replace
574					randArr	= self._getRandom( nmbOut, self.showTotal );
575
576				for( var i = 0; i < nmbOut; ++i ) {
577
578					// element to go out
579					var $out = self.$items.eq( randArr[ i ] );
580
581					// if element is active, which means it is currently animating,
582					// then we need to get different positions.. 
583					if( $out.data( 'active' ) || $out.data( 'nochange' ) ) {
584
585						// one of the items is active, call again..
586						self._showNext( 1 );
587						return false;
588
589					}
590
591					self._replace( $out );
592
593				}
594
595				// again and again..
596				self._showNext();
597
598			}, time || Math.max( Math.abs( this.options.interval ) , 300 ) );
599
600		},
601		_replace : function( $out ) {
602
603			$out.data( 'active', true );
604
605			var self = this,
606				$outA = $out.children( 'a:last' ),
607				newElProp = {
608					width : $outA.width(),
609					height : $outA.height()
610				};
611
612			// element stays active
613			$out.data( 'active', true );
614
615			// get the element (anchor) that will go in (first one inserted in this.outItems)
616			var $inA = this.outItems.shift();
617
618			// save element that went out
619			this.outItems.push( $outA.clone().css( 'transition', 'none' ) );
620			
621			// prepend in element
622			$inA.css( newElProp ).prependTo( $out );
623
624			var animProp = this._getAnimProperties( $outA );
625
626			$inA.css( animProp.startInProp );
627			$outA.css( animProp.startOutProp );
628			
629			this._setTransition( $inA, 'all', animProp.animSpeed, animProp.delay, this.options.animEasingIn );
630			this._setTransition( $outA, 'all', animProp.animSpeed, 0, this.options.animEasingOut );
631
632			this._applyTransition( $inA, animProp.endInProp, animProp.animSpeed, function() {
633
634				var $el = $( this ),
635					t = animProp.animSpeed === self.options.animSpeed && isEmpty( animProp.endInProp ) ? animProp.animSpeed : 0;
636					
637				setTimeout( function() {
638					
639					if( self.supportTransitions ) {
640						$el.off( self.transEndEventName );
641					}
642					
643					$el.next().remove();
644					$el.parent().data( 'active', false );
645
646				}, t );
647
648			}, animProp.animSpeed === 0 || isEmpty( animProp.endInProp ) );
649			this._applyTransition( $outA, animProp.endOutProp, animProp.animSpeed );
650
651		},
652		_getRandom : function( cnt, limit ) {
653
654			var randArray = [];
655
656			for( var i = 0; i < limit; ++i ) {
657				randArray.push( i )
658			}
659			
660			return randArray.shuffle().slice( 0, cnt );
661
662		},
663		_setTransition : function( el, prop, speed, delay, easing ) {
664
665			setTimeout( function() {
666				el.css( 'transition', prop + ' ' + speed + 'ms ' + delay + 'ms ' + easing );
667			}, 25 );
668
669		},
670		_applyTransition : function( el, styleCSS, speed, fncomplete, force ) {
671
672			var self = this;
673			setTimeout( function() {
674				$.fn.applyStyle = self.supportTransitions ? $.fn.css : $.fn.animate;
675
676				if( fncomplete && self.supportTransitions ) {
677
678					el.on( self.transEndEventName, fncomplete );
679
680					if( force ) {
681						fncomplete.call( el );					
682					}
683
684				}
685
686				fncomplete = fncomplete || function() { return false; };
687
688				el.stop().applyStyle( styleCSS, $.extend( true, [], { duration : speed + 'ms', complete : fncomplete } ) );
689			}, 25 );
690
691		}
692
693	};
694	
695	var logError = function( message ) {
696
697		if ( window.console ) {
698
699			window.console.error( message );
700		
701		}
702
703	};
704	
705	$.fn.gridrotator = function( options ) {
706
707		var instance = $.data( this, 'gridrotator' );
708		
709		if ( typeof options === 'string' ) {
710			
711			var args = Array.prototype.slice.call( arguments, 1 );
712			
713			this.each(function() {
714			
715				if ( !instance ) {
716
717					logError( "cannot call methods on gridrotator prior to initialization; " +
718					"attempted to call method '" + options + "'" );
719					return;
720				
721				}
722				
723				if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
724
725					logError( "no such method '" + options + "' for gridrotator instance" );
726					return;
727				
728				}
729				
730				instance[ options ].apply( instance, args );
731			
732			});
733		
734		} 
735		else {
736		
737			this.each(function() {
738				
739				if ( instance ) {
740
741					instance._init();
742				
743				}
744				else {
745
746					instance = $.data( this, 'gridrotator', new $.GridRotator( options, this ) );
747				
748				}
749
750			});
751		
752		}
753		
754		return instance;
755		
756	};
757	
758} )( jQuery, window );

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.