/** * photostack.js v1.0.0 (modified version) * original from: 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(jQuery, $, window){ 'use strict'; function detectIE() { var ua = window.navigator.userAgent; var msie = ua.indexOf('MSIE '); var trident = ua.indexOf('Trident/'); if (msie > 0 || trident > 0) return true; // other browser return false; } function supportsTransitions() { var b = document.body || document.documentElement, s = b.style, p = 'transition'; if (typeof s[p] == 'string') { $("html").addClass("csstransformspreserve3d"); return true; } // Tests for vendor specific prop var v = ['Moz', 'webkit', 'Webkit', 'Khtml', 'O', 'ms']; p = p.charAt(0).toUpperCase() + p.substr(1); for (var i=0; i 0 ) { moveItems.call(); } else { // change transform-origin $(self.currentItem).addClass( 'photostack-flip' ); // all done.. self.isShuffling = false; if( typeof self.options.callback === 'function' ) { self.options.callback( self.currentItem ); } } } }; if(self.items.indexOf(item) === self.current && self.started && iter === 0) { self.currentItem.style.WebkitTransform = 'translate(' + self.centerItem.x + 'px,' + self.centerItem.y + 'px) rotate(0deg)'; self.currentItem.style.msTransform = 'translate(' + self.centerItem.x + 'px,' + self.centerItem.y + 'px) rotate(0deg)'; self.currentItem.style.transform = 'translate(' + self.centerItem.x + 'px,' + self.centerItem.y + 'px) rotate(0deg)'; // if there is something behind.. if( self.currentItem.querySelector( '.photostack-back' ) ) { self._addItemPerspective(); } $(self.currentItem).addClass( 'photostack-current' ); } else { item.style.WebkitTransform = 'translate(' + translation.x + 'px,' + translation.y + 'px) rotate(' + Math.floor( Math.random() * (maxrot - minrot + 1) + minrot ) + 'deg)'; item.style.msTransform = 'translate(' + translation.x + 'px,' + translation.y + 'px) rotate(' + Math.floor( Math.random() * (maxrot - minrot + 1) + minrot ) + 'deg)'; item.style.transform = 'translate(' + translation.x + 'px,' + translation.y + 'px) rotate(' + Math.floor( Math.random() * (maxrot - minrot + 1) + minrot ) + 'deg)'; } if( self.started ) { if( support.transitions ) { item.addEventListener( transEndEventName, onEndTransitionFn ); } else { onEndTransitionFn(); } } } ); }; moveItems.call(); } Photostack.prototype._getSizes = function() { this.sizes = { inner : { width : this.inner.offsetWidth, height : this.inner.offsetHeight }, item : { width : this.currentItem.offsetWidth, height : this.currentItem.offsetHeight } }; // translation values to center an item this.centerItem = { x : this.sizes.inner.width / 2 - this.sizes.item.width / 2, y : this.sizes.inner.height / 2 - this.sizes.item.height / 2 }; } Photostack.prototype._isOverlapping = function( itemVal ) { var dxArea = this.sizes.item.width + this.sizes.item.width / 3, // adding some extra avoids any rotated item to touch the central area dyArea = this.sizes.item.height + this.sizes.item.height / 3, areaVal = { x : this.sizes.inner.width / 2 - dxArea / 2, y : this.sizes.inner.height / 2 - dyArea / 2 }, dxItem = this.sizes.item.width, dyItem = this.sizes.item.height; if( !(( itemVal.x + dxItem ) < areaVal.x || itemVal.x > ( areaVal.x + dxArea ) || ( itemVal.y + dyItem ) < areaVal.y || itemVal.y > ( areaVal.y + dyArea )) ) { // how much to move so it does not overlap? // move left / or move right var left = Math.random() < 0.5, randExtraX = Math.floor( Math.random() * (dxItem/4 + 1) ), randExtraY = Math.floor( Math.random() * (dyItem/4 + 1) ), noOverlapX = left ? (itemVal.x - areaVal.x + dxItem) * -1 - randExtraX : (areaVal.x + dxArea) - (itemVal.x + dxItem) + dxItem + randExtraX, noOverlapY = left ? (itemVal.y - areaVal.y + dyItem) * -1 - randExtraY : (areaVal.y + dyArea) - (itemVal.y + dyItem) + dyItem + randExtraY; return { overlapping : true, noOverlap : { x : noOverlapX, y : noOverlapY } } } return { overlapping : false } } Photostack.prototype._addItemPerspective = function() { $(this.el).addClass( 'photostack-perspective' ); } Photostack.prototype._removeItemPerspective = function() { $(this.el).removeClass( 'photostack-perspective' ); $(this.currentItem).removeClass( 'photostack-flip' ); } Photostack.prototype._rotateItem = function( callback ) { if( $(this.el).hasClass( 'photostack-perspective' ) && !this.isRotating && !this.isShuffling ) { this.isRotating = true; var self = this, onEndTransitionFn = function() { if( support.transitions && support.preserve3d ) { this.removeEventListener( transEndEventName, onEndTransitionFn ); } self.isRotating = false; if( typeof callback === 'function' ) { callback(); } }; if( this.flipped ) { $(this.navDots[ this.current ]).removeClass( 'flip' ); if( support.preserve3d ) { this.currentItem.style.WebkitTransform = 'translate(' + this.centerItem.x + 'px,' + this.centerItem.y + 'px) rotateY(0deg)'; this.currentItem.style.transform = 'translate(' + this.centerItem.x + 'px,' + this.centerItem.y + 'px) rotateY(0deg)'; } else { $(this.currentItem).removeClass( 'photostack-showback' ); } } else { $(this.navDots[ this.current ]).addClass( 'flip' ); if( support.preserve3d ) { this.currentItem.style.WebkitTransform = 'translate(' + this.centerItem.x + 'px,' + this.centerItem.y + 'px) translate(' + this.sizes.item.width + 'px) rotateY(-179.9deg)'; this.currentItem.style.transform = 'translate(' + this.centerItem.x + 'px,' + this.centerItem.y + 'px) translate(' + this.sizes.item.width + 'px) rotateY(-179.9deg)'; } else { $(this.currentItem).addClass( 'photostack-showback' ); } } this.flipped = !this.flipped; if( support.transitions && support.preserve3d ) { this.currentItem.addEventListener( transEndEventName, onEndTransitionFn ); } else { onEndTransitionFn(); } } } // add to global namespace window.Photostack = Photostack; })(jQuery, jQuery, window);