/**
* boxesfx.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';
// based on http://responsejs.com/labs/dimensions/
function getviewport(axis) {
var client, inner;
if( axis === 'x' ) {
client = docelem['clientwidth'];
inner = window['innerwidth'];
}
else if( axis === 'y' ) {
client = docelem['clientheight'];
inner = window['innerheight'];
}
return client < inner ? inner : client;
}
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 },
win = { width : getviewport('x'), height : getviewport('y') };
function extend( a, b ) {
for( var key in b ) {
if( b.hasownproperty( key ) ) {
a[key] = b[key];
}
}
return a;
}
function boxesfx( el, options ) {
this.el = el;
this.options = extend( {}, this.options );
extend( this.options, options );
this._init();
}
boxesfx.prototype.options = {}
boxesfx.prototype._init = function() {
// set transforms configuration
this._settransforms();
// which effect
this.effect = this.el.getattribute( 'data-effect' ) || 'effect-1';
// check if animating
this.isanimating = false;
// the panels
this.panels = [].slice.call( this.el.queryselectorall( '.panel' ) );
// total number of panels (4 for this demo)
//this.panelscount = this.panels.length;
this.panelscount = 4;
// current panel´s index
this.current = 0;
classie.add( this.panels[0], 'current' );
// replace image with 4 divs, each including the image
var self = this;
this.panels.foreach( function( panel ) {
var img = panel.queryselector( 'img' ), imgreplacement = '';
for( var i = 0; i < self.panelscount; ++i ) {
imgreplacement += '
'
}
panel.removechild( img );
panel.innerhtml = imgreplacement + panel.innerhtml;
} );
// add navigation element
this.nav = document.createelement( 'nav' );
this.nav.innerhtml = '';
this.el.appendchild( this.nav );
// initialize events
this._initevents();
}
// set the transforms per effect
// we have defined both the next and previous action transforms for each panel
boxesfx.prototype._settransforms = function() {
this.transforms = {
'effect-1' : {
'next' : [
'translate3d(0, ' + (win.height/2+10) + 'px, 0)', // transforms for 1 panel
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)', // transforms for 2 panel
'translate3d(' + (win.width/2+10) + 'px, 0, 0)', // transforms for 3 panel
'translate3d(0, -' + (win.height/2+10) + 'px, 0)' // transforms for 4 panel
],
'prev' : [
'translate3d(' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(0, ' + (win.height/2+10) + 'px, 0)',
'translate3d(0, -' + (win.height/2+10) + 'px, 0)',
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)'
]
},
'effect-2' : {
'next' : [
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(' + (win.width/2+10) + 'px, 0, 0)'
],
'prev' : [
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)'
]
},
'effect-3' : {
'next' : [
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)'
],
'prev' : [
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)'
]
}
};
}
boxesfx.prototype._initevents = function() {
var self = this, navctrls = this.nav.children;
// previous action
navctrls[0].addeventlistener( 'click', function() { self._navigate('prev') } );
// next action
navctrls[1].addeventlistener( 'click', function() { self._navigate('next') } );
// window resize
window.addeventlistener( 'resize', function() { self._resizehandler(); } );
}
// goto next or previous slide
boxesfx.prototype._navigate = function( dir ) {
if( this.isanimating ) return false;
this.isanimating = true;
var self = this, currentpanel = this.panels[ this.current ];
if( dir === 'next' ) {
this.current = this.current < this.panelscount - 1 ? this.current + 1 : 0;
}
else {
this.current = this.current > 0 ? this.current - 1 : this.panelscount - 1;
}
// next panel to be shown
var nextpanel = this.panels[ this.current ];
// add class active to the next panel to trigger its animation
classie.add( nextpanel, 'active' );
// apply the transforms to the current panel
this._applytransforms( currentpanel, dir );
// let´s track the number of transitions ended per panel
var cnttranstotal = 0,
// transition end event function
onendtransitionfn = function( ev ) {
if( ev && !classie.has( ev.target, 'bg-img' ) ) return false;
// return if not all panel transitions ended
++cnttranstotal;
if( cnttranstotal < self.panelscount ) return false;
if( support.transitions ) {
this.removeeventlistener( transendeventname, onendtransitionfn );
}
// remove current class from current panel and add it to the next one
classie.remove( currentpanel, 'current' );
classie.add( nextpanel, 'current' );
// reset transforms for the currentpanel
self._resettransforms( currentpanel );
// remove class active
classie.remove( nextpanel, 'active' );
self.isanimating = false;
};
if( support.transitions ) {
currentpanel.addeventlistener( transendeventname, onendtransitionfn );
}
else {
onendtransitionfn();
}
}
boxesfx.prototype._applytransforms = function( panel, dir ) {
var self = this;
[].slice.call( panel.queryselectorall( 'div.bg-img' ) ).foreach( function( tile, pos ) {
tile.style.webkittransform = self.transforms[self.effect][dir][pos];
tile.style.transform = self.transforms[self.effect][dir][pos];
} );
}
boxesfx.prototype._resettransforms = function( panel ) {
[].slice.call( panel.queryselectorall( 'div.bg-img' ) ).foreach( function( tile ) {
tile.style.webkittransform = 'none';
tile.style.transform = 'none';
} );
}
boxesfx.prototype._resizehandler = function() {
var self = this;
function delayed() {
self._resize();
self._resizetimeout = null;
}
if ( this._resizetimeout ) {
cleartimeout( this._resizetimeout );
}
this._resizetimeout = settimeout( delayed, 50 );
}
boxesfx.prototype._resize = function() {
win.width = getviewport('x');
win.height = getviewport('y');
this._settransforms();
}
// add to global namespace
window.boxesfx = boxesfx;
} )( window );