1;(function (window, document, $, undefined) { 2 'use strict'; 3 4 /** 5 * @returns {string} 6 */ 7 function detect_transitionend_event() { 8 var element = document.createElement('div'); 9 var transitions = { 10 'transition' : 'transitionend', 11 'OTransition' : 'oTransitionEnd', 12 'MozTransition' : 'transitionend', 13 'WebkitTransition': 'webkitTransitionEnd' 14 }; 15 16 for (var property in transitions) { 17 if (!Object.prototype.hasOwnProperty.call(transitions, property)) { 18 continue; 19 } 20 21 if (element.style[property] !== undefined) { 22 return transitions[property]; 23 } 24 } 25 26 return null; 27 } 28 29 var TRANSITIONEND_EVENT = detect_transitionend_event(); 30 31 /** 32 * @param {Function} callback 33 * @param {number} delay 34 * 35 * @returns {Function} 36 */ 37 function debounce(callback, delay) { 38 var timeoutId; 39 var result; 40 41 delay = delay || 500; 42 43 return function () { 44 var args = arguments; 45 var context = this; 46 47 if (timeoutId) { 48 clearTimeout(timeoutId); 49 } 50 51 timeoutId = setTimeout(function () { 52 timeoutId = null; 53 54 result = callback.apply(context, args); 55 }, delay); 56 57 return result; 58 }; 59 } 60 61 /** 62 * @param {jQuery} $element 63 * @param {Object.<string, *>} options 64 * 65 * @constructor 66 */ 67 function Animatable_Element($element, options) { 68 this._$element = $element; 69 this._options = options; 70 this._is_animating = false; 71 this._is_animated = false; 72 } 73 74 /** 75 * @param {number} [scroll_bottom] 76 * 77 * @return {boolean} 78 */ 79 Animatable_Element.prototype.is_visible = function (scroll_bottom) { 80 var trigger_top; 81 82 scroll_bottom = (typeof scroll_bottom !== 'undefined') ? scroll_bottom : $(window).scrollTop() + $(window).height(); 83 trigger_top = this._$element.offset().top - (this._options.offset * -1); 84 85 return (scroll_bottom >= trigger_top); 86 }; 87 88 /** 89 * @returns {boolean} 90 */ 91 Animatable_Element.prototype.is_animating = function () { 92 return this._is_animating; 93 }; 94 95 /** 96 * @returns {boolean} 97 */ 98 Animatable_Element.prototype.is_animated = function () { 99 return this._is_animated; 100 }; 101 102 /** 103 * @returns {jQuery.Promise} 104 */ 105 Animatable_Element.prototype.animate = function () { 106 var self = this; 107 var $deferred = $.Deferred(); 108 109 if (self._is_animating || self._is_animated) { 110 return $deferred.resolve().promise(); 111 } 112 113 if (TRANSITIONEND_EVENT !== null) { 114 self._$element.on(TRANSITIONEND_EVENT, function () { 115 self._$element.removeClass('is-animating'); 116 self._$element.addClass('is-animated'); 117 118 self._is_animating = false; 119 self._is_animated = true; 120 121 $deferred.resolve(); 122 }); 123 124 self._is_animating = true; 125 126 self._$element.addClass('is-animating'); 127 } else { 128 self._$element.removeClass('is-animating'); 129 self._$element.addClass('is-animated'); 130 131 self._is_animating = false; 132 self._is_animated = true; 133 134 $deferred.resolve(); 135 } 136 137 return $deferred.promise(); 138 }; 139 140 /** 141 * @param {Animatable_Element[]} animatable_elements 142 * 143 * @returns {Function} 144 */ 145 function create_updater(animatable_elements) { 146 var current_animatable_elements = animatable_elements; 147 148 return function () { 149 var scroll_bottom = $(window).scrollTop() + $(window).height(); 150 151 current_animatable_elements = current_animatable_elements.filter(function (animatable_element) { 152 return (!animatable_element.is_animating() && !animatable_element.is_animated()); 153 }); 154 155 current_animatable_elements 156 .filter(function (animatable_element) { 157 return animatable_element.is_visible(scroll_bottom); 158 }) 159 .map(function (animatable_element) { 160 return animatable_element.animate(); 161 }); 162 }; 163 } 164 165 function initialize() { 166 var animatable_elements = []; 167 var update; 168 169 $('[data-st-rich-animation]').each(function (index, element) { 170 var $element = $(this); 171 var options = $element.data('st-rich-animation-options'); 172 var animatable_element = new Animatable_Element($element, options); 173 174 animatable_elements.push(animatable_element); 175 }); 176 177 178 update = create_updater(animatable_elements); 179 180 update(); 181 182 $(window).scroll(update); 183 $(window).on('orientationchange resize', debounce(update)); 184 } 185 186 function on_ready() { 187 initialize(); 188 } 189 190 $(on_ready); 191}(window, window.document, jQuery));
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.