1/* 2 _ _ _____ _ _ 3 | | | __ \ | | (_) 4 ___ ___ _ __ ___ | | | |__) |_____ _____ __ _| | _ ___ 5 / __|/ __| '__/ _ \| | | _ // _ \ \ / / _ \/ _` | | | / __| 6 \__ \ (__| | | (_) | | | | \ \ __/\ V / __/ (_| | |_| \__ \ 7 |___/\___|_| \___/|_|_|_| \_\___| \_/ \___|\__,_|_(_) |___/ v.0.1.3 8 _/ | 9 |__/ 10 11 "Declarative on-scroll reveal animations." 12 13/*============================================================================= 14 15 scrollReveal.js was inspired by cbpScroller.js (c) 2014 Codrops. 16 17 Licensed under the MIT license. 18 http://www.opensource.org/licenses/mit-license.php 19 20=============================================================================*/ 21 22/*! scrollReveal.js v0.1.3 (c) 2014 Julian Lloyd | MIT license */ 23 24/*===========================================================================*/ 25 26 27window.scrollReveal = (function (window) { 28 29 'use strict'; 30 31 // generator (increments) for the next scroll-reveal-id 32 var nextId = 1; 33 34 /** 35 * RequestAnimationFrame polyfill 36 * @function 37 * @private 38 */ 39 var requestAnimFrame = (function () { 40 return window.requestAnimationFrame || 41 window.webkitRequestAnimationFrame || 42 window.mozRequestAnimationFrame || 43 function (callback) { 44 window.setTimeout(callback, 1000 / 60); 45 }; 46 }()); 47 48 function scrollReveal(options) { 49 50 this.options = this.extend(this.defaults, options); 51 this.docElem = this.options.elem; 52 this.styleBank = {}; 53 54 if (this.options.init == true) this.init(); 55 } 56 57 scrollReveal.prototype = { 58 59 defaults: { 60 after: '0s', 61 enter: 'bottom', 62 move: '24px', 63 over: '0.66s', 64 easing: 'ease-in-out', 65 opacity: 0, 66 complete: function() {}, 67 68 // if 0, the element is considered in the viewport as soon as it enters 69 // if 1, the element is considered in the viewport when it's fully visible 70 viewportFactor: 0.33, 71 72 // if false, animations occur only once 73 // if true, animations occur each time an element enters the viewport 74 reset: false, 75 76 // if true, scrollReveal.init() is automaticaly called upon instantiation 77 init: true, 78 elem: window.document.documentElement 79 }, 80 81 /*=============================================================================*/ 82 83 init: function () { 84 85 this.scrolled = false; 86 87 var self = this; 88 89 // Check DOM for the data-scrollReveal attribute 90 // and initialize all found elements. 91 this.elems = Array.prototype.slice.call(this.docElem.querySelectorAll('[data-scroll-reveal]')); 92 this.elems.forEach(function (el, i) { 93 94 // Capture original style attribute 95 var id = el.getAttribute("data-scroll-reveal-id"); 96 if (!id) { 97 id = nextId++; 98 el.setAttribute("data-scroll-reveal-id", id); 99 } 100 if (!self.styleBank[id]) { 101 self.styleBank[id] = el.getAttribute('style'); 102 } 103 104 self.update(el); 105 }); 106 107 var scrollHandler = function (e) { 108 // No changing, exit 109 if (!self.scrolled) { 110 self.scrolled = true; 111 requestAnimFrame(function () { 112 self._scrollPage(); 113 }); 114 } 115 }; 116 117 var resizeHandler = function () { 118 119 // If weâre still waiting for settimeout, reset the timer. 120 if (self.resizeTimeout) { 121 clearTimeout(self.resizeTimeout); 122 } 123 function delayed() { 124 self._scrollPage(); 125 self.resizeTimeout = null; 126 } 127 self.resizeTimeout = setTimeout(delayed, 200); 128 }; 129 130 // captureScroll 131 if (this.docElem == window.document.documentElement) { 132 window.addEventListener('scroll', scrollHandler, false); 133 window.addEventListener('resize', resizeHandler, false); 134 } 135 else { 136 this.docElem.addEventListener('scroll', scrollHandler, false); 137 } 138 }, 139 140 /*=============================================================================*/ 141 142 _scrollPage: function () { 143 var self = this; 144
145 this.elems.forEach(function (el, i) { 146 self.update(el); 147 }); 148 this.scrolled = false; 149 }, 150 151 /*=============================================================================*/ 152 153 parseLanguage: function (el) { 154 155 // Splits on a sequence of one or more commas or spaces. 156 var words = el.getAttribute('data-scroll-reveal').split(/[, ]+/), 157 parsed = {}; 158 159 function filter (words) { 160 var ret = [], 161 162 blacklist = [ 163 "from", 164 "the", 165 "and", 166 "then", 167 "but", 168 "with" 169 ]; 170 171 words.forEach(function (word, i) { 172 if (blacklist.indexOf(word) > -1) { 173 return; 174 } 175 ret.push(word); 176 }); 177 178 return ret; 179 } 180 181 words = filter(words); 182 183 words.forEach(function (word, i) { 184 185 switch (word) { 186 case "enter": 187 parsed.enter = words[i + 1]; 188 return; 189 190 case "after": 191 parsed.after = words[i + 1]; 192 return; 193 194 case "wait": 195 parsed.after = words[i + 1]; 196 return; 197 198 case "move": 199 parsed.move = words[i + 1]; 200 return; 201 202 case "ease": 203 parsed.move = words[i + 1]; 204 parsed.ease = "ease"; 205 return; 206 207 case "ease-in": 208 parsed.move = words[i + 1]; 209 parsed.easing = "ease-in"; 210 return; 211 212 case "ease-in-out": 213 parsed.move = words[i + 1]; 214 parsed.easing = "ease-in-out"; 215 return; 216 217 case "ease-out": 218 parsed.move = words[i + 1]; 219 parsed.easing = "ease-out"; 220 return; 221 222 case "over": 223 parsed.over = words[i + 1]; 224 return; 225 226 default: 227 return; 228 } 229 }); 230 231 return parsed; 232 }, 233 234 235 /*=============================================================================*/ 236 237 update: function (el) { 238 239 var that = this; 240 var css = this.genCSS(el); 241 var style = this.styleBank[el.getAttribute("data-scroll-reveal-id")]; 242 243 if (style != null) style += ";"; else style = ""; 244 245 if (!el.getAttribute('data-scroll-reveal-initialized')) { 246 el.setAttribute('style', style + css.initial); 247 el.setAttribute('data-scroll-reveal-initialized', true); 248 } 249 250 if (!this.isElementInViewport(el, this.options.viewportFactor)) { 251 if (this.options.reset) { 252 el.setAttribute('style', style + css.initial + css.reset); 253 } 254 return; 255 } 256 257 if (el.getAttribute('data-scroll-reveal-complete')) return; 258 259 if (this.isElementInViewport(el, this.options.viewportFactor)) { 260 el.setAttribute('style', style + css.target + css.transition); 261 // Without reset enabled, we can safely remove the style tag 262 // to prevent CSS specificy wars with authored CSS. 263 if (!this.options.reset) { 264 setTimeout(function () { 265 if (style != "") { 266 el.setAttribute('style', style); 267 } else { 268 el.removeAttribute('style'); 269 } 270 el.setAttribute('data-scroll-reveal-complete',true); 271 that.options.complete(el); 272 }, css.totalDuration); 273 } 274 return; 275 } 276 }, 277 278 /*=============================================================================*/ 279 280 genCSS: function (el) { 281 var parsed = this.parseLanguage(el), 282 enter, 283 axis; 284 285 if (parsed.enter) { 286 287 if (parsed.enter == "top" || parsed.enter == "bottom") { 288 enter = parsed.enter; 289 axis = "y"; 290 } 291 292 if (parsed.enter == "left" || parsed.enter == "right") { 293 enter = parsed.enter; 294 axis = "x"; 295 } 296 297 } else { 298 299 if (this.options.enter == "top" || this.options.enter == "bottom") { 300 enter = this.options.enter 301 axis = "y"; 302 } 303 304 if (this.options.enter == "left" || this.options.enter == "right") { 305 enter = this.options.enter 306 axis = "x"; 307 } 308 } 309 310 // After all values are parsed, letâs make sure our our 311 // pixel distance is negative for top and left entrances. 312 // 313 // ie. "move 25px from top" starts at 'top: -25px' in CSS. 314 315 if (enter == "top" || enter == "left") { 316 if (parsed.move) { 317 parsed.move = "-" + parsed.move; 318 } 319 else { 320 parsed.move = "-" + this.options.move; 321 } 322 } 323 324 var dist = parsed.move || this.options.move, 325 dur = parsed.over || this.options.over, 326 delay = parsed.after || this.options.after, 327 easing = parsed.easing || this.options.easing, 328 opacity = parsed.opacity || this.options.opacity; 329 330 var transition = "-webkit-transition: -webkit-transform " + dur + " " + easing + " " + delay + ", opacity " + dur + " " + easing + " " + delay + ";" + 331 "transition: transform " + dur + " " + easing + " " + delay + ", opacity " + dur + " " + easing + " " + delay + ";" + 332 "-webkit-perspective: 1000;" + 333 "-webkit-backface-visibility: hidden;"; 334 335 // The same as transition, but removing the delay for elements fading out. 336 var reset = "-webkit-transition: -webkit-transform " + dur + " " + easing + " 0s, opacity " + dur + " " + easing + " " + delay + ";" + 337 "transition: transform " + dur + " " + easing + " 0s, opacity " + dur + " " + easing + " " + delay + ";" + 338 "-webkit-perspective: 1000;" + 339 "-webkit-backface-visibility: hidden;"; 340 341 var initial = "-webkit-transform: translate" + axis + "(" + dist + ");" + 342 "transform: translate" + axis + "(" + dist + ");" + 343 "opacity: " + opacity + ";"; 344 345 var target = "-webkit-transform: translate" + axis + "(0);" + 346 "transform: translate" + axis + "(0);" + 347 "opacity: 1;"; 348 return { 349 transition: transition, 350 initial: initial, 351 target: target, 352 reset: reset, 353 totalDuration: ((parseFloat(dur) + parseFloat(delay)) * 1000) 354 }; 355 }, 356 357 getViewportH : function () { 358 var client = this.docElem['clientHeight'],
359 inner = window['innerHeight']; 360 361 if (this.docElem == window.document.documentElement) 362 return (client < inner) ? inner : client; 363 else 364 return client; 365 }, 366 367 getOffset : function(el) { 368 var offsetTop = 0, 369 offsetLeft = 0; 370 371 do { 372 if (!isNaN(el.offsetTop)) { 373 offsetTop += el.offsetTop; 374 } 375 if (!isNaN(el.offsetLeft)) { 376 offsetLeft += el.offsetLeft; 377 } 378 } while (el = el.offsetParent) 379 380 return { 381 top: offsetTop, 382 left: offsetLeft 383 } 384 }, 385 386 isElementInViewport : function(el, h) { 387 var scrolled = this.docElem.scrollTop + this.docElem.offsetTop; 388 if (this.docElem == window.document.documentElement)scrolled = window.pageYOffset; 389 var 390 viewed = scrolled + this.getViewportH(), 391 elH = el.offsetHeight, 392 elTop = this.getOffset(el).top, 393 elBottom = elTop + elH, 394 h = h || 0; 395 396 return (elTop + elH * h) <= viewed 397 && (elBottom) >= scrolled 398 || (el.currentStyle? el.currentStyle : window.getComputedStyle(el, null)).position == 'fixed'; 399 }, 400 401 extend: function (a, b){ 402 for (var key in b) { 403 if (b.hasOwnProperty(key)) { 404 a[key] = b[key]; 405 } 406 } 407 return a; 408 } 409 }; // end scrollReveal.prototype 410 411 return scrollReveal; 412})(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.