/** * animonscroll.js v1.0.0 */ ;( function( window ) { 'use strict'; var docelem = window.document.documentelement; function getviewporth() { var client = docelem['clientheight'], inner = window['innerheight']; if( client < inner ) return inner; else return client; } function scrolly() { return window.pageyoffset || docelem.scrolltop; } function getoffset( el ) { var offsettop = 0, offsetleft = 0; do { if ( !isnan( el.offsettop ) ) { offsettop += el.offsettop; } if ( !isnan( el.offsetleft ) ) { offsetleft += el.offsetleft; } } while( el = el.offsetparent ) return { top : offsettop, left : offsetleft } } function inviewport( el, h ) { var elh = el.offsetheight, scrolled = scrolly(), viewed = scrolled + getviewporth(), eltop = getoffset(el).top, elbottom = eltop + elh, // if 0, the element is considered in the viewport as soon as it enters. // if 1, the element is considered in the viewport only when it's fully inside // value in percentage (1 >= h >= 0) h = h || 0; return (eltop + elh * h) <= viewed && (elbottom - elh * h) >= scrolled; } function extend( a, b ) { for( var key in b ) { if( b.hasownproperty( key ) ) { a[key] = b[key]; } } return a; } function animonscroll( el, options ) { this.el = el; this.options = extend( this.defaults, options ); this._init(); } animonscroll.prototype = { defaults : { // minimum and a maximum duration of the animation (random value is chosen) minduration : 0, maxduration : 0, // the viewportfactor defines how much of the appearing item has to be visible in order to trigger the animation // if we'd use a value of 0, this would mean that it would add the animation class as soon as the item is in the viewport. // if we were to use the value of 1, the animation would only be triggered when we see all of the item in the viewport (100% of it) viewportfactor : 0 }, _init : function() { if( $('#psd-results').length > 0 ) this.items = array.prototype.slice.call( document.queryselectorall( '#psd-results .psd-result' ) ); else if( $('#sds-feed-wrap').length > 0 ) this.items = array.prototype.slice.call( document.queryselectorall( '#sds-feed-wrap .sds-post' ) ); else this.items = array.prototype.slice.call( document.queryselectorall( '#trends-feed-wrap .trends-post' ) ); this.itemscount = this.items.length; this.itemsrenderedcount = 0; this.didscroll = false; var self = this; imagesloaded( this.el, function() { // initialize masonry if( $('#psd-results').length > 0 ) new masonry( '#psd-results', { itemselector: '.psd-result', transitionduration : 0 } ) else if( $('#sds-feed-wrap').length > 0 ) new masonry( '#sds-feed-wrap', { itemselector: '.sds-post', transitionduration : 0 } ); else new masonry( '#trends-feed-wrap', { itemselector: '.trends-post', transitionduration : 0 } ); /*$('#trends-feed-wrap').masonry({ itemselector: '.trends-post', transitionduration : 0 });*/ if( modernizr.cssanimations ) { // the items already shown... self.items.foreach( function( el, i ) { if( inviewport( el ) ) { self._checktotalrendered(); classie.add( el, 'shown' ); } } ); // animate on scroll the items inside the viewport window.addeventlistener( 'scroll', function() { self._onscrollfn(); }, false ); window.addeventlistener( 'resize', function() { self._resizehandler(); }, false ); } }); }, _onscrollfn : function() { var self = this; if( !this.didscroll ) { this.didscroll = true; settimeout( function() { self._scrollpage(); }, 60 ); } }, _scrollpage : function() { var self = this; this.items.foreach( function( el, i ) { if( !classie.has( el, 'shown' ) && !classie.has( el, 'animate' ) && inviewport( el, self.options.viewportfactor ) ) { settimeout( function() { var perspy = scrolly() + getviewporth() / 2; self.el.style.webkitperspectiveorigin = '50% ' + perspy + 'px'; self.el.style.mozperspectiveorigin = '50% ' + perspy + 'px'; self.el.style.perspectiveorigin = '50% ' + perspy + 'px'; self._checktotalrendered(); if( self.options.minduration && self.options.maxduration ) { var randduration = ( math.random() * ( self.options.maxduration - self.options.minduration ) + self.options.minduration ) + 's'; el.style.webkitanimationduration = randduration; el.style.mozanimationduration = randduration; el.style.animationduration = randduration; } classie.add( el, 'animate' ); }, 25 ); } }); this.didscroll = false; }, _resizehandler : function() { var self = this; function delayed() { self._scrollpage(); self.resizetimeout = null; } if ( this.resizetimeout ) { cleartimeout( this.resizetimeout ); } this.resizetimeout = settimeout( delayed, 1000 ); }, _checktotalrendered : function() { ++this.itemsrenderedcount; if( this.itemsrenderedcount === this.itemscount ) { window.removeeventlistener( 'scroll', this._onscrollfn ); } } } // add to global namespace window.animonscroll = animonscroll; } )( window );