1/** 2 * animOnScroll.js v1.0.0 3 * http://www.codrops.com 4 * 5 * Licensed under the MIT license. 6 * http://www.opensource.org/licenses/mit-license.php 7 * 8 * Copyright 2013, Codrops 9 * http://www.codrops.com 10 */ 11;( function( window ) { 12 13 'use strict'; 14 15 var docElem = window.document.documentElement; 16 17 function getViewportH() { 18 var client = docElem['clientHeight'], 19 inner = window['innerHeight']; 20 21 if( client < inner ) 22 return inner; 23 else 24 return client; 25 } 26 27 function scrollY() { 28 return window.pageYOffset || docElem.scrollTop; 29 } 30 31 // http://stackoverflow.com/a/5598797/989439 32 function getOffset( el ) { 33 var offsetTop = 0, offsetLeft = 0; 34 do { 35 if ( !isNaN( el.offsetTop ) ) { 36 offsetTop += el.offsetTop; 37 } 38 if ( !isNaN( el.offsetLeft ) ) { 39 offsetLeft += el.offsetLeft; 40 } 41 } while( el = el.offsetParent ) 42 43 return { 44 top : offsetTop, 45 left : offsetLeft 46 } 47 } 48 49 function inViewport( el, h ) { 50 var elH = el.offsetHeight, 51 scrolled = scrollY(), 52 viewed = scrolled + getViewportH(), 53 elTop = getOffset(el).top, 54 elBottom = elTop + elH, 55 // if 0, the element is considered in the viewport as soon as it enters. 56 // if 1, the element is considered in the viewport only when it's fully inside 57 // value in percentage (1 >= h >= 0) 58 h = h || 0; 59 60 return (elTop + elH * h) <= viewed && (elBottom - elH * h) >= scrolled; 61 } 62 63 function extend( a, b ) { 64 for( var key in b ) { 65 if( b.hasOwnProperty( key ) ) { 66 a[key] = b[key]; 67 } 68 } 69 return a; 70 } 71 72 function AnimOnScroll( el, options ) { 73 this.el = el; 74 this.options = extend( this.defaults, options ); 75 this._init(); 76 } 77 78 AnimOnScroll.prototype = { 79 defaults : { 80 // Minimum and a maximum duration of the animation (random value is chosen) 81 minDuration : 0, 82 maxDuration : 0, 83 // The viewportFactor defines how much of the appearing item has to be visible in order to trigger the animation 84 // 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. 85 // 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) 86 viewportFactor : 0 87 }, 88 _init : function() { 89 this.items = Array.prototype.slice.call( document.querySelectorAll( '#' + this.el.id + ' > li' ) ); 90 this.itemsCount = this.items.length; 91 this.itemsRenderedCount = 0; 92 this.didScroll = false; 93 94 var self = this; 95 96 imagesLoaded( this.el, function() { 97 98 // initialize masonry 99 new Masonry( self.el, { 100 itemSelector: 'li', 101 transitionDuration : 0 102 } ); 103 104 if( Modernizr.cssanimations ) { 105 // the items already shown... 106 self.items.forEach( function( el, i ) { 107 if( inViewport( el ) ) { 108 self._checkTotalRendered(); 109 classie.add( el, 'shown' ); 110 } 111 } ); 112 113 // animate on scroll the items inside the viewport 114 window.addEventListener( 'scroll', function() { 115 self._onScrollFn(); 116 }, false ); 117 window.addEventListener( 'resize', function() { 118 self._resizeHandler(); 119 }, false ); 120 } 121 122 }); 123 }, 124 _onScrollFn : function() { 125 var self = this; 126 if( !this.didScroll ) { 127 this.didScroll = true; 128 setTimeout( function() { self._scrollPage(); }, 60 ); 129 } 130 }, 131 _scrollPage : function() { 132 var self = this; 133 this.items.forEach( function( el, i ) { 134 if( !classie.has( el, 'shown' ) && !classie.has( el, 'animate' ) && inViewport( el, self.options.viewportFactor ) ) { 135 setTimeout( function() { 136 var perspY = scrollY() + getViewportH() / 2; 137 self.el.style.WebkitPerspectiveOrigin = '50% ' + perspY + 'px'; 138 self.el.style.MozPerspectiveOrigin = '50% ' + perspY + 'px'; 139 self.el.style.perspectiveOrigin = '50% ' + perspY + 'px'; 140 141 self._checkTotalRendered(); 142 143 if( self.options.minDuration && self.options.maxDuration ) { 144 var randDuration = ( Math.random() * ( self.options.maxDuration - self.options.minDuration ) + self.options.minDuration ) + 's'; 145 el.style.WebkitAnimationDuration = randDuration; 146 el.style.MozAnimationDuration = randDuration; 147 el.style.animationDuration = randDuration; 148 } 149 150 classie.add( el, 'animate' ); 151 }, 25 ); 152 } 153 }); 154 this.didScroll = false;
155 }, 156 _resizeHandler : function() { 157 var self = this; 158 function delayed() { 159 self._scrollPage(); 160 self.resizeTimeout = null; 161 } 162 if ( this.resizeTimeout ) { 163 clearTimeout( this.resizeTimeout ); 164 } 165 this.resizeTimeout = setTimeout( delayed, 1000 ); 166 }, 167 _checkTotalRendered : function() { 168 ++this.itemsRenderedCount; 169 if( this.itemsRenderedCount === this.itemsCount ) { 170 window.removeEventListener( 'scroll', this._onScrollFn ); 171 } 172 } 173 } 174 175 // add to global namespace 176 window.AnimOnScroll = AnimOnScroll; 177 178} )( window );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.