1/*� 2 _ _ _____ _ _� 3 | | | __ \ | | (_)� 4 ___ ___ _ __ ___ | | | |__) |_____ _____ __ _| | _ ___� 5 / __|/ __| '__/ _ \| | | _ // _ \ \ / / _ \/ _` | | | / __|� 6 \__ \ (__| | | (_) | | | | \ \ __/\ V / __/ (_| | |_| \__ \� 7 |___/\___|_| \___/|_|_|_| \_\___| \_/ \___|\__,_|_(_) |___/� 8 _/ |� 9 |__/� 10� 11 "Declarative on-scroll reveal animations."� 12� 13/*=============================================================================� 14� 15 scrollReveal.js is inspired by cbpScroller.js, © 2014, Codrops.� 16� 17 Licensed under the MIT license.� 18 http://www.opensource.org/licenses/mit-license.php� 19� 20 scrollReveal.js, © 2014 https://twitter.com/julianlloyd� 21� 22=============================================================================*/� 23� 24;(function (window) {� 25� 26 'use strict';� 27� 28 var docElem = window.document.documentElement;� 29� 30 function getViewportH () {� 31 var client = docElem['clientHeight'],� 32 inner = window['innerHeight'];� 33� 34 return (client < inner) ? inner : client;� 35 }� 36� 37 function getOffset (el) {� 38 var offsetTop = 0,� 39 offsetLeft = 0;� 40� 41 do {� 42 if (!isNaN(el.offsetTop)) {� 43 offsetTop += el.offsetTop;� 44 }� 45 if (!isNaN(el.offsetLeft)) {� 46 offsetLeft += el.offsetLeft;� 47 }� 48 } while (el = el.offsetParent)� 49� 50 return {� 51 top: offsetTop,� 52 left: offsetLeft� 53 }� 54 }� 55� 56 function isElementInViewport (el, h) {� 57 var scrolled = window.pageYOffset,� 58 viewed = scrolled + getViewportH(),� 59 elH = el.offsetHeight,� 60 elTop = getOffset(el).top,� 61 elBottom = elTop + elH,� 62 h = h || 0;� 63� 64 return (elTop + elH * h) <= viewed && (elBottom) >= 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� 77 function scrollReveal(options) {� 78 this.options = extend(this.defaults, options);� 79 this._init();� 80 }� 81� 82� 83� 84 scrollReveal.prototype = {� 85 defaults: {� 86 axis: 'y',� 87 distance: '60px',� 88 duration: '0.55s',� 89 delay: '0.15s',� 90� 91 // if 0, the element is considered in the viewport as soon as it enters� 92 // if 1, the element is considered in the viewport when it's fully visible� 93 viewportFactor: 0.33� 94 },� 95� 96 /*=============================================================================*/� 97� 98 _init: function () {� 99� 100 var self = this;� 101� 102 this.elems = Array.prototype.slice.call(docElem.querySelectorAll('[data-scrollReveal]'));� 103 this.scrolled = false;� 104� 105 // Initialize all scrollreveals, triggering all� 106 // reveals on visible elements.� 107 this.elems.forEach(function (el, i) {� 108 self.animate(el);� 109 });� 110� 111 var scrollHandler = function () {� 112 if (!self.scrolled) {� 113 self.scrolled = true;� 114 setTimeout(function () {� 115 self._scrollPage();� 116 }, 60);� 117 }� 118 };� 119� 120 var resizeHandler = function () {� 121 function delayed() {� 122 self._scrollPage();� 123 self.resizeTimeout = null;� 124 }� 125 if (self.resizeTimeout) {� 126 clearTimeout(self.resizeTimeout);� 127 }� 128 self.resizeTimeout = setTimeout(delayed, 200);� 129 };� 130� 131 window.addEventListener('scroll', scrollHandler, false);� 132 window.addEventListener('resize', resizeHandler, false);� 133 },� 134� 135 /*=============================================================================*/� 136� 137 _scrollPage: function () {� 138 var self = this;� 139� 140 this.elems.forEach(function (el, i) {� 141 if (isElementInViewport(el, self.options.viewportFactor)) {� 142 self.animate(el);� 143 }� 144 });� 145 this.scrolled = false;� 146 },� 147� 148 /*=============================================================================*/� 149� 150 parseLanguage: function (el) {� 151� 152 // Splits on a sequence of one or more commas or spaces.� 153 var words = el.getAttribute('data-scrollreveal').split(/[, ]+/),� 154 enterFrom,� 155 parsed = {};� 156� 157 function filter (words) {� 158 var ret = [],� 159� 160 blacklist = [� 161 "from",� 162 "the",� 163 "and",� 164 "then",� 165 "but"� 166 ];� 167� 168 words.forEach(function (word, i) {� 169 if (blacklist.indexOf(word) > -1) {� 170 return;� 171 }�
172 ret.push(word);� 173 });� 174� 175 return ret;� 176 }� 177� 178 words = filter(words);� 179� 180 words.forEach(function (word, i) {� 181� 182 switch (word) {� 183 case "enter":� 184 enterFrom = words[i + 1];� 185� 186 if (enterFrom == "top" || enterFrom == "bottom") {� 187 parsed.axis = "y";� 188 }� 189� 190 if (enterFrom == "left" || enterFrom == "right") {� 191 parsed.axis = "x";� 192 }� 193� 194 return;� 195� 196 case "after":� 197 parsed.delay = words[i + 1];� 198 return;� 199� 200 case "wait":� 201 parsed.delay = words[i + 1];� 202 return;� 203� 204 case "move":� 205 parsed.distance = words[i + 1];� 206 return;� 207� 208 case "over":� 209 parsed.duration = words[i + 1];� 210 return;� 211� 212 case "trigger":� 213 parsed.eventName = words[i + 1];� 214 return;� 215� 216 default:� 217 // Unrecognizable words; do nothing.� 218 return;� 219 }� 220 });� 221� 222 // After all values are parsed, letâs make sure our our� 223 // pixel distance is negative for top and left entrances.� 224 //� 225 // ie. "move 25px from top" starts at 'top: -25px' in CSS.� 226� 227 if (enterFrom == "top" || enterFrom == "left") {� 228� 229 if (!typeof parsed.distance == "undefined") {� 230 parsed.distance = "-" + parsed.distance;� 231 }� 232� 233 else {� 234 parsed.distance = "-" + this.options.distance;� 235 }� 236� 237 }� 238� 239 return parsed;� 240 },� 241� 242 /*=============================================================================*/� 243� 244 genCSS: function (el) {� 245 var parsed = this.parseLanguage(el);� 246� 247 var dist = parsed.distance || this.options.distance,� 248 dur = parsed.duration || this.options.duration,� 249 delay = parsed.delay || this.options.delay,� 250 axis = parsed.axis || this.options.axis;� 251� 252 var transition = "-webkit-transition: all " + dur + " ease " + delay + ";" +� 253 "-moz-transition: all " + dur + " ease " + delay + ";" +� 254 "-o-transition: all " + dur + " ease " + delay + ";" +� 255 "-ms-transition: all " + dur + " ease " + delay + ";" +� 256 "transition: all " + dur + " ease " + delay + ";";� 257� 258 var initial = "-webkit-transform: translate" + axis + "(" + dist + ");" +� 259 "-moz-transform: translate" + axis + "(" + dist + ");" +� 260 "-ms-transform: translate" + axis + "(" + dist + ");" +� 261 "transform: translate" + axis + "(" + dist + ");" +� 262 "opacity: 0;";� 263� 264 var target = "-webkit-transform: translate" + axis + "(0);" +� 265 "-moz-transform: translate" + axis + "(0);" +� 266 "-ms-transform: translate" + axis + "(0);" +� 267 "transform: translate" + axis + "(0);" +� 268 "opacity: 1;";� 269 return {� 270 transition: transition,� 271 initial: initial,� 272 target: target,� 273 totalDuration: ((parseFloat(dur) + parseFloat(delay)) * 1000)� 274 };� 275 },� 276� 277 /*=============================================================================*/� 278� 279 animate: function (el) {� 280 var css = this.genCSS(el);� 281� 282 if (!el.getAttribute('data-sr-init')) {� 283 el.setAttribute('style', css.initial);� 284 el.setAttribute('data-sr-init', true);� 285 }� 286� 287 if (el.getAttribute('data-sr-complete')) {� 288 return;� 289 }� 290� 291 if (isElementInViewport(el, this.options.viewportFactor)) {� 292 el.setAttribute('style', css.target + css.transition);� 293� 294 setTimeout(function () {� 295 el.removeAttribute('style');� 296 el.setAttribute('data-sr-complete', true);� 297 }, css.totalDuration);� 298 }� 299� 300 }� 301 }; // end scrollReveal.prototype� 302� 303 document.addEventListener("DOMContentLoaded", function (evt) {� 304 window.scrollReveal = new scrollReveal();� 305 });� 306� 307})(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.