PageSourceSearch

https://knihovna-vratimov.cz/domains/knihovna-vratimov.cz/templates/explore//src/scrollReveal.js

js knihovna-vratimov.cz collected 2026-10-08 17:48:20 UTC 11,539 bytes, 398 lines download raw bytes

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