/** * 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 );