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