mirror of
				https://github.com/dawidolko/Website-Templates.git
				synced 2025-10-28 16:03:10 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			371 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			371 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * cbpGridGallery.js v1.0.0
 | |
|  * http://www.codrops.com
 | |
|  *
 | |
|  * Licensed under the MIT license.
 | |
|  * http://www.opensource.org/licenses/mit-license.php
 | |
|  * 
 | |
|  * Copyright 2014, Codrops
 | |
|  * http://www.codrops.com
 | |
|  */
 | |
| ;( function( window ) {
 | |
| 	
 | |
| 	'use strict';
 | |
| 
 | |
| 	var docElem = window.document.documentElement,
 | |
| 		transEndEventNames = {
 | |
| 			'WebkitTransition': 'webkitTransitionEnd',
 | |
| 			'MozTransition': 'transitionend',
 | |
| 			'OTransition': 'oTransitionEnd',
 | |
| 			'msTransition': 'MSTransitionEnd',
 | |
| 			'transition': 'transitionend'
 | |
| 		},
 | |
| 		transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
 | |
| 		support = {
 | |
| 			transitions : Modernizr.csstransitions,
 | |
| 			support3d : Modernizr.csstransforms3d
 | |
| 		};
 | |
| 
 | |
| 	function setTransform( el, transformStr ) {
 | |
| 		el.style.WebkitTransform = transformStr;
 | |
| 		el.style.msTransform = transformStr;
 | |
| 		el.style.transform = transformStr;
 | |
| 	}
 | |
| 
 | |
| 	// from http://responsejs.com/labs/dimensions/
 | |
| 	function getViewportW() {
 | |
| 		var client = docElem['clientWidth'],
 | |
| 			inner = window['innerWidth'];
 | |
| 		
 | |
| 		if( client < inner )
 | |
| 			return inner;
 | |
| 		else
 | |
| 			return client;
 | |
| 	}
 | |
| 
 | |
| 	function extend( a, b ) {
 | |
| 		for( var key in b ) { 
 | |
| 			if( b.hasOwnProperty( key ) ) {
 | |
| 				a[key] = b[key];
 | |
| 			}
 | |
| 		}
 | |
| 		return a;
 | |
| 	}
 | |
| 
 | |
| 	function CBPGridGallery( el, options ) {
 | |
| 		this.el = el;
 | |
| 		this.options = extend( {}, this.options );
 | |
|   		extend( this.options, options );
 | |
|   		this._init();
 | |
| 	}
 | |
| 
 | |
| 	CBPGridGallery.prototype.options = {
 | |
| 	};
 | |
| 
 | |
| 	CBPGridGallery.prototype._init = function() {
 | |
| 		// main grid
 | |
| 		this.grid = this.el.querySelector( 'section.grid-wrap > ul.grid' );
 | |
| 		// main grid items
 | |
| 		this.gridItems = [].slice.call( this.grid.querySelectorAll( 'li:not(.grid-sizer)' ) );
 | |
| 		// items total
 | |
| 		this.itemsCount = this.gridItems.length;
 | |
| 		// slideshow grid
 | |
| 		this.slideshow = this.el.querySelector( 'section.slideshow > ul' );
 | |
| 		// slideshow grid items
 | |
| 		this.slideshowItems = [].slice.call( this.slideshow.children );
 | |
| 		// index of current slideshow item
 | |
| 		this.current = -1;
 | |
| 		// slideshow control buttons
 | |
| 		this.ctrlPrev = this.el.querySelector( 'section.slideshow > nav > span.nav-prev' );
 | |
| 		this.ctrlNext = this.el.querySelector( 'section.slideshow > nav > span.nav-next' );
 | |
| 		this.ctrlClose = this.el.querySelector( 'section.slideshow > nav > span.nav-close' );
 | |
| 		// init masonry grid
 | |
| 		this._initMasonry();
 | |
| 		// init events
 | |
| 		this._initEvents();
 | |
| 	};
 | |
| 
 | |
| 	CBPGridGallery.prototype._initMasonry = function() {
 | |
| 		var grid = this.grid;
 | |
| 		imagesLoaded( grid, function() {
 | |
| 			new Masonry( grid, {
 | |
| 				itemSelector: 'li',
 | |
| 				columnWidth: grid.querySelector( '.grid-sizer' )
 | |
| 			});
 | |
| 		});
 | |
| 	};
 | |
| 
 | |
| 	CBPGridGallery.prototype._initEvents = function() {
 | |
| 		var self = this;
 | |
| 
 | |
| 		// open the slideshow when clicking on the main grid items
 | |
| 		this.gridItems.forEach( function( item, idx ) {
 | |
| 			item.addEventListener( 'click', function() {
 | |
| 				self._openSlideshow( idx );
 | |
| 			} );
 | |
| 		} );
 | |
| 
 | |
| 		// slideshow controls
 | |
| 		this.ctrlPrev.addEventListener( 'click', function() { self._navigate( 'prev' ); } );
 | |
| 		this.ctrlNext.addEventListener( 'click', function() { self._navigate( 'next' ); } );
 | |
| 		this.ctrlClose.addEventListener( 'click', function() { self._closeSlideshow(); } );
 | |
| 
 | |
| 		// window resize
 | |
| 		window.addEventListener( 'resize', function() { self._resizeHandler(); } );
 | |
| 
 | |
| 		// keyboard navigation events
 | |
| 		document.addEventListener( 'keydown', function( ev ) {
 | |
| 			if ( self.isSlideshowVisible ) {
 | |
| 				var keyCode = ev.keyCode || ev.which;
 | |
| 
 | |
| 				switch (keyCode) {
 | |
| 					case 37:
 | |
| 						self._navigate( 'prev' );
 | |
| 						break;
 | |
| 					case 39:
 | |
| 						self._navigate( 'next' );
 | |
| 						break;
 | |
| 					case 27:
 | |
| 						self._closeSlideshow();
 | |
| 						break;
 | |
| 				}
 | |
| 			}
 | |
| 		} );
 | |
| 
 | |
| 		// trick to prevent scrolling when slideshow is visible
 | |
| 		window.addEventListener( 'scroll', function() {
 | |
| 			if ( self.isSlideshowVisible ) {
 | |
| 				window.scrollTo( self.scrollPosition ? self.scrollPosition.x : 0, self.scrollPosition ? self.scrollPosition.y : 0 );
 | |
| 			}
 | |
| 			else {
 | |
| 				self.scrollPosition = { x : window.pageXOffset || docElem.scrollLeft, y : window.pageYOffset || docElem.scrollTop };
 | |
| 			}
 | |
| 		});
 | |
| 	};
 | |
| 
 | |
| 	CBPGridGallery.prototype._openSlideshow = function( pos ) {
 | |
| 		this.isSlideshowVisible = true;
 | |
| 		this.current = pos;
 | |
| 
 | |
| 		classie.addClass( this.el, 'slideshow-open' );
 | |
| 
 | |
| 		/* position slideshow items */
 | |
| 
 | |
| 		// set viewport items (current, next and previous)
 | |
| 		this._setViewportItems();
 | |
| 		
 | |
| 		// add class "current" and "show" to currentItem
 | |
| 		classie.addClass( this.currentItem, 'current' );
 | |
| 		classie.addClass( this.currentItem, 'show' );
 | |
| 
 | |
| 		// add class show to next and previous items
 | |
| 		// position previous item on the left side and the next item on the right side
 | |
| 		if( this.prevItem ) {
 | |
| 			classie.addClass( this.prevItem, 'show' );
 | |
| 			var translateVal = Number( -1 * ( getViewportW() / 2 + this.prevItem.offsetWidth / 2 ) );
 | |
| 			setTransform( this.prevItem, support.support3d ? 'translate3d(' + translateVal + 'px, 0, -150px)' : 'translate(' + translateVal + 'px)' );
 | |
| 		}
 | |
| 		if( this.nextItem ) {
 | |
| 			classie.addClass( this.nextItem, 'show' );
 | |
| 			var translateVal = Number( getViewportW() / 2 + this.nextItem.offsetWidth / 2 );
 | |
| 			setTransform( this.nextItem, support.support3d ? 'translate3d(' + translateVal + 'px, 0, -150px)' : 'translate(' + translateVal + 'px)' );
 | |
| 		}
 | |
| 	};
 | |
| 
 | |
| 	CBPGridGallery.prototype._navigate = function( dir ) {
 | |
| 		if( this.isAnimating ) return;
 | |
| 		if( dir === 'next' && this.current === this.itemsCount - 1 ||  dir === 'prev' && this.current === 0  ) {
 | |
| 			this._closeSlideshow();
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		this.isAnimating = true;
 | |
| 		
 | |
| 		// reset viewport items
 | |
| 		this._setViewportItems();
 | |
| 
 | |
| 		var self = this,
 | |
| 			itemWidth = this.currentItem.offsetWidth,
 | |
| 			// positions for the centered/current item, both the side items and the incoming ones
 | |
| 			transformLeftStr = support.support3d ? 'translate3d(-' + Number( getViewportW() / 2 + itemWidth / 2 ) + 'px, 0, -150px)' : 'translate(-' + Number( getViewportW() / 2 + itemWidth / 2 ) + 'px)',
 | |
| 			transformRightStr = support.support3d ? 'translate3d(' + Number( getViewportW() / 2 + itemWidth / 2 ) + 'px, 0, -150px)' : 'translate(' + Number( getViewportW() / 2 + itemWidth / 2 ) + 'px)',
 | |
| 			transformCenterStr = '', transformOutStr, transformIncomingStr,
 | |
| 			// incoming item
 | |
| 			incomingItem;
 | |
| 
 | |
| 		if( dir === 'next' ) {
 | |
| 			transformOutStr = support.support3d ? 'translate3d( -' + Number( (getViewportW() * 2) / 2 + itemWidth / 2 ) + 'px, 0, -150px )' : 'translate(-' + Number( (getViewportW() * 2) / 2 + itemWidth / 2 ) + 'px)';
 | |
| 			transformIncomingStr = support.support3d ? 'translate3d( ' + Number( (getViewportW() * 2) / 2 + itemWidth / 2 ) + 'px, 0, -150px )' : 'translate(' + Number( (getViewportW() * 2) / 2 + itemWidth / 2 ) + 'px)';
 | |
| 		}
 | |
| 		else {
 | |
| 			transformOutStr = support.support3d ? 'translate3d( ' + Number( (getViewportW() * 2) / 2 + itemWidth / 2 ) + 'px, 0, -150px )' : 'translate(' + Number( (getViewportW() * 2) / 2 + itemWidth / 2 ) + 'px)';
 | |
| 			transformIncomingStr = support.support3d ? 'translate3d( -' + Number( (getViewportW() * 2) / 2 + itemWidth / 2 ) + 'px, 0, -150px )' : 'translate(-' + Number( (getViewportW() * 2) / 2 + itemWidth / 2 ) + 'px)';
 | |
| 		}
 | |
| 
 | |
| 		// remove class animatable from the slideshow grid (if it has already)
 | |
| 		classie.removeClass( self.slideshow, 'animatable' );
 | |
| 
 | |
| 		if( dir === 'next' && this.current < this.itemsCount - 2 || dir === 'prev' && this.current > 1 ) {
 | |
| 			// we have an incoming item!
 | |
| 			incomingItem = this.slideshowItems[ dir === 'next' ? this.current + 2 : this.current - 2 ];
 | |
| 			setTransform( incomingItem, transformIncomingStr );
 | |
| 			classie.addClass( incomingItem, 'show' );
 | |
| 		}
 | |
| 
 | |
| 		var slide = function() {
 | |
| 			// add class animatable to the slideshow grid
 | |
| 			classie.addClass( self.slideshow, 'animatable' );
 | |
| 
 | |
| 			// overlays:
 | |
| 			classie.removeClass( self.currentItem, 'current' );
 | |
| 			var nextCurrent = dir === 'next' ? self.nextItem : self.prevItem;
 | |
| 			classie.addClass( nextCurrent, 'current' );
 | |
| 
 | |
| 			setTransform( self.currentItem, dir === 'next' ? transformLeftStr : transformRightStr );
 | |
| 
 | |
| 			if( self.nextItem ) {
 | |
| 				setTransform( self.nextItem, dir === 'next' ? transformCenterStr : transformOutStr );
 | |
| 			}
 | |
| 
 | |
| 			if( self.prevItem ) {
 | |
| 				setTransform( self.prevItem, dir === 'next' ? transformOutStr : transformCenterStr );
 | |
| 			}
 | |
| 
 | |
| 			if( incomingItem ) {
 | |
| 				setTransform( incomingItem, dir === 'next' ? transformRightStr : transformLeftStr );
 | |
| 			}
 | |
| 
 | |
| 			var onEndTransitionFn = function( ev ) {
 | |
| 				if( support.transitions ) {
 | |
| 					if( ev.propertyName.indexOf( 'transform' ) === -1 ) return false;
 | |
| 					this.removeEventListener( transEndEventName, onEndTransitionFn );
 | |
| 				}
 | |
| 
 | |
| 				if( self.prevItem && dir === 'next' ) {
 | |
| 					classie.removeClass( self.prevItem, 'show' );
 | |
| 				}
 | |
| 				else if( self.nextItem && dir === 'prev' ) {
 | |
| 					classie.removeClass( self.nextItem, 'show' );
 | |
| 				}
 | |
| 
 | |
| 				if( dir === 'next' ) {
 | |
| 					self.prevItem = self.currentItem;
 | |
| 					self.currentItem = self.nextItem;
 | |
| 					if( incomingItem ) {
 | |
| 						self.nextItem = incomingItem;
 | |
| 					}
 | |
| 				}
 | |
| 				else {
 | |
| 					self.nextItem = self.currentItem;
 | |
| 					self.currentItem = self.prevItem;
 | |
| 					if( incomingItem ) {
 | |
| 						self.prevItem = incomingItem;
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				self.current = dir === 'next' ? self.current + 1 : self.current - 1;
 | |
| 				self.isAnimating = false;
 | |
| 			};
 | |
| 
 | |
| 			if( support.transitions ) {
 | |
| 				self.currentItem.addEventListener( transEndEventName, onEndTransitionFn );
 | |
| 			}
 | |
| 			else {
 | |
| 				onEndTransitionFn();
 | |
| 			}
 | |
| 		};
 | |
| 
 | |
| 		setTimeout( slide, 25 );
 | |
| 	}
 | |
| 
 | |
| 	CBPGridGallery.prototype._closeSlideshow = function( pos ) {
 | |
| 		// remove class slideshow-open from the grid gallery elem
 | |
| 		classie.removeClass( this.el, 'slideshow-open' );
 | |
| 		// remove class animatable from the slideshow grid
 | |
| 		classie.removeClass( this.slideshow, 'animatable' );
 | |
| 
 | |
| 		var self = this,
 | |
| 			onEndTransitionFn = function( ev ) {
 | |
| 				if( support.transitions ) {
 | |
| 					if( ev.target.tagName.toLowerCase() !== 'ul' ) return;
 | |
| 					this.removeEventListener( transEndEventName, onEndTransitionFn );
 | |
| 				}
 | |
| 				// remove classes show and current from the slideshow items
 | |
| 				classie.removeClass( self.currentItem, 'current' );
 | |
| 				classie.removeClass( self.currentItem, 'show' );
 | |
| 				
 | |
| 				if( self.prevItem ) {
 | |
| 					classie.removeClass( self.prevItem, 'show' );
 | |
| 				}
 | |
| 				if( self.nextItem ) {
 | |
| 					classie.removeClass( self.nextItem, 'show' );
 | |
| 				}
 | |
| 
 | |
| 				// also reset any transforms for all the items
 | |
| 				self.slideshowItems.forEach( function( item ) { setTransform( item, '' ); } );
 | |
| 
 | |
| 				self.isSlideshowVisible = false;
 | |
| 			};
 | |
| 
 | |
| 		if( support.transitions ) {
 | |
| 			this.el.addEventListener( transEndEventName, onEndTransitionFn );
 | |
| 		}
 | |
| 		else {
 | |
| 			onEndTransitionFn();
 | |
| 		}
 | |
| 	};
 | |
| 
 | |
| 	CBPGridGallery.prototype._setViewportItems = function() {
 | |
| 		this.currentItem = null;
 | |
| 		this.prevItem = null;
 | |
| 		this.nextItem = null;
 | |
| 
 | |
| 		if( this.current > 0 ) {
 | |
| 			this.prevItem = this.slideshowItems[ this.current - 1 ];
 | |
| 		}
 | |
| 		if( this.current < this.itemsCount - 1 ) {
 | |
| 			this.nextItem = this.slideshowItems[ this.current + 1 ];
 | |
| 		}
 | |
| 		this.currentItem = this.slideshowItems[ this.current ];
 | |
| 	}
 | |
| 
 | |
| 	// taken from https://github.com/desandro/vanilla-masonry/blob/master/masonry.js by David DeSandro
 | |
| 	// original debounce by John Hann
 | |
| 	// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
 | |
| 	CBPGridGallery.prototype._resizeHandler = function() {
 | |
| 		var self = this;
 | |
| 		function delayed() {
 | |
| 			self._resize();
 | |
| 			self._resizeTimeout = null;
 | |
| 		}
 | |
| 		if ( this._resizeTimeout ) {
 | |
| 			clearTimeout( this._resizeTimeout );
 | |
| 		}
 | |
| 		this._resizeTimeout = setTimeout( delayed, 50 );
 | |
| 	}
 | |
| 
 | |
| 	CBPGridGallery.prototype._resize = function() {
 | |
| 		if ( this.isSlideshowVisible ) {
 | |
| 			// update width value
 | |
| 			if( this.prevItem ) {
 | |
| 				var translateVal = Number( -1 * ( getViewportW() / 2 + this.prevItem.offsetWidth / 2 ) );
 | |
| 				setTransform( this.prevItem, support.support3d ? 'translate3d(' + translateVal + 'px, 0, -150px)' : 'translate(' + translateVal + 'px)' );
 | |
| 			}
 | |
| 			if( this.nextItem ) {
 | |
| 				var translateVal = Number( getViewportW() / 2 + this.nextItem.offsetWidth / 2 );
 | |
| 				setTransform( this.nextItem, support.support3d ? 'translate3d(' + translateVal + 'px, 0, -150px)' : 'translate(' + translateVal + 'px)' );
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// add to global namespace
 | |
| 	window.CBPGridGallery = CBPGridGallery;
 | |
| 
 | |
| })( window );
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| new CBPGridGallery( document.getElementById( 'grid-gallery' ) ); |