init commit
This commit is contained in:
@@ -0,0 +1,364 @@
|
||||
/**
|
||||
* 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 );
|
||||
@@ -0,0 +1,80 @@
|
||||
/*!
|
||||
* classie - class helper functions
|
||||
* from bonzo https://github.com/ded/bonzo
|
||||
*
|
||||
* classie.has( elem, 'my-class' ) -> true/false
|
||||
* classie.add( elem, 'my-new-class' )
|
||||
* classie.remove( elem, 'my-unwanted-class' )
|
||||
* classie.toggle( elem, 'my-class' )
|
||||
*/
|
||||
|
||||
/*jshint browser: true, strict: true, undef: true */
|
||||
/*global define: false */
|
||||
|
||||
( function( window ) {
|
||||
|
||||
'use strict';
|
||||
|
||||
// class helper functions from bonzo https://github.com/ded/bonzo
|
||||
|
||||
function classReg( className ) {
|
||||
return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
|
||||
}
|
||||
|
||||
// classList support for class management
|
||||
// altho to be fair, the api sucks because it won't accept multiple classes at once
|
||||
var hasClass, addClass, removeClass;
|
||||
|
||||
if ( 'classList' in document.documentElement ) {
|
||||
hasClass = function( elem, c ) {
|
||||
return elem.classList.contains( c );
|
||||
};
|
||||
addClass = function( elem, c ) {
|
||||
elem.classList.add( c );
|
||||
};
|
||||
removeClass = function( elem, c ) {
|
||||
elem.classList.remove( c );
|
||||
};
|
||||
}
|
||||
else {
|
||||
hasClass = function( elem, c ) {
|
||||
return classReg( c ).test( elem.className );
|
||||
};
|
||||
addClass = function( elem, c ) {
|
||||
if ( !hasClass( elem, c ) ) {
|
||||
elem.className = elem.className + ' ' + c;
|
||||
}
|
||||
};
|
||||
removeClass = function( elem, c ) {
|
||||
elem.className = elem.className.replace( classReg( c ), ' ' );
|
||||
};
|
||||
}
|
||||
|
||||
function toggleClass( elem, c ) {
|
||||
var fn = hasClass( elem, c ) ? removeClass : addClass;
|
||||
fn( elem, c );
|
||||
}
|
||||
|
||||
var classie = {
|
||||
// full names
|
||||
hasClass: hasClass,
|
||||
addClass: addClass,
|
||||
removeClass: removeClass,
|
||||
toggleClass: toggleClass,
|
||||
// short names
|
||||
has: hasClass,
|
||||
add: addClass,
|
||||
remove: removeClass,
|
||||
toggle: toggleClass
|
||||
};
|
||||
|
||||
// transport
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( classie );
|
||||
} else {
|
||||
// browser global
|
||||
window.classie = classie;
|
||||
}
|
||||
|
||||
})( window );
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user