1/** 2 * simpleParallax 3 * ------------ 4 * Version : 2.4.0 5 * Website : https://anakao-theme.com/simpleparallax/ 6 * Repo : https://github.com/geosenna/simpleParallax 7 * Author : Geoffrey Signorato (@geosenna) 8 */ 9 10(function(factory) { 11 if (typeof module === 'object' && typeof module.exports === 'object') { 12 factory(require('jquery'), window, document); 13 } else { 14 factory(jQuery, window, document); 15 } 16})(function($, window, document, undefined) { 17 'use strict'; 18 19 // Detect css transform 20 var cssTransform = (function() { 21 var prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' '), 22 cssTransform, 23 i = 0; 24 while (cssTransform === undefined) { 25 cssTransform = document.createElement('div').style[prefixes[i]] != undefined ? prefixes[i] : undefined; 26 i++; 27 } 28 return cssTransform; 29 })(); 30 31 //requestAnimationFrame polyfill by Erik Mï¾ï½¶ller. fixes from Paul Irish and Tino Zijdel 32 //via: https://gist.github.com/paulirish/1579671 33 (function() { 34 var lastTime = 0; 35 var vendors = ['ms', 'moz', 'webkit', 'o']; 36 for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 37 window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; 38 window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; 39 } 40 41 if (!window.requestAnimationFrame) 42 window.requestAnimationFrame = function(callback, element) { 43 var currTime = new Date().getTime(); 44 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 45 var id = window.setTimeout(function() { 46 callback(currTime + timeToCall); 47 }, timeToCall); 48 lastTime = currTime + timeToCall; 49 return id; 50 }; 51 52 if (!window.cancelAnimationFrame) 53 window.cancelAnimationFrame = function(id) { 54 clearTimeout(id); 55 }; 56 })(); 57 58 var pluginName = 'simpleParallax', 59 edge = 20, 60 lastPosition = -1, 61 isInitialized = false; 62 63 function SimpleParallax(element, options) { 64 this.element = element; 65 this.$element = $(this.element); 66 this._name = pluginName; 67 this._defaults = $.fn.simpleParallax.defaults; 68 this.options = $.extend({}, this._defaults, options); 69 70 this.init(); 71 } 72 73 $.extend(SimpleParallax, { 74 getViewportOffsetTop: function() { 75 this.viewportTop = window.pageYOffset; 76 }, 77 78 getViewportOffset: function() { 79 var win = $(window); 80 81 (this.viewportHeight = win.outerHeight()), (this.viewportBottom = SimpleParallax.viewportTop + SimpleParallax.viewportHeight); 82 } 83 }); 84 85 $.extend(SimpleParallax.prototype, { 86 occurence: [], 87 88 //initialization of elements 89 init: function() { 90 var plugin = this; 91 92 plugin.wrapElement(); 93 94 this.occurence.push(plugin); 95 96 if (isInitialized) plugin.proceedLoop(); 97 }, 98 99 //wrap the element with the .simpleParallax div and apply overflow hidden to hide the image excedant (cause of the scale) 100 wrapElement: function() { 101 var plugin = this; 102 103 //wrap into a div only if overflow is set to true 104 if (plugin.options.overflow == true) { 105 plugin.$elementToWrap = plugin.$element; 106 107 if (plugin.$element.closest('picture').length) plugin.$elementToWrap = plugin.$element.parent('picture'); 108 109 plugin.$elementToWrap.wrap('<div class="simpleParallax" style="overflow:hidden"></div>'); 110 111 plugin.$elementContainer = plugin.$element.closest('.simpleParallax'); 112 113 //add scale option to ensure correct calculation of the rangeMax value 114 plugin.$element[0].style[cssTransform] = 'scale(' + plugin.options.scale + ')'; 115 } else { 116 plugin.$elementContainer = plugin.$element; 117 } 118 119 //add will-change CSs property to improve persomance 120 plugin.$element[0].style.willChange = 'transform'; 121 122 //if animation is set, add a transition CSS 123 if (plugin.options.delay > 0) { 124 plugin.$element[0].style.transition = 'transform ' + plugin.options.delay + 's cubic-bezier(0,0,0,1)'; 125 } 126 }, 127 128 //unwrap the element from the .simpleParallax div 129 unWrapElement: function() { 130 var plugin = this; 131 132 if (plugin.options.overflow == true) { 133 plugin.$elementToWrap.unwrap('.simpleParallax'); 134 } 135 }, 136 137 //calculate the current element offset 138 getElementOffset: function() { 139 var plugin = this; 140 141 plugin.elementHeight = plugin.$elementContainer[0].offsetHeight; 142 plugin.elementTopX = plugin.$elementContainer.offset().top; 143 plugin.elementBottomX = plugin.elementTopX + plugin.elementHeight; 144 }, 145 146 //check if the current element is visible in the Viewport 147 isVisible: function() { 148 var plugin = this; 149 150 return plugin.elementBottomX > SimpleParallax.viewportTop - edge && plugin.elementTopX < SimpleParallax.viewportBottom + edge; 151 }, 152 153 calculateRange: function() { 154 var plugin = this; 155 156 //get the real height of the image with the scaling apply to it
157 plugin.elementImageHeight = plugin.$element[0].getBoundingClientRect().height; 158 159 if (plugin.options.overflow == true) { 160 //range is calculate with the extra space of the scaled image comparing to its container 161 plugin.rangeMax = Math.abs(plugin.elementHeight - plugin.elementImageHeight); 162 } else { 163 //range is calculate with the image height by the scale 164 plugin.rangeMax = plugin.elementImageHeight * plugin.options.scale - plugin.elementImageHeight; 165 } 166 167 if (plugin.options.orientation === 'down' || plugin.options.orientation === 'right') { 168 plugin.rangeMax *= -1; 169 } 170 }, 171 172 //calculate the percentage and the translate value to apply on the element 173 calculate: function() { 174 var plugin = this, 175 //calculate the % position of the element comparing to the viewport 176 percentage = (SimpleParallax.viewportBottom - plugin.elementTopX) / ((SimpleParallax.viewportHeight + plugin.elementHeight) / 100); 177 178 //Rounded to percentage to the nearest 0.1 to increase perfomance 179 percentage = Number(percentage.toFixed(1)); 180 181 //sometime the same percentage if returned, to avoid this if the old percentage is equal to the new one, we don't do aything 182 if (plugin.oldPercentage === percentage) return false; 183 184 //sometime the percentage exceeds 100 or goes below 0 185 if (percentage > 100) percentage = 100; 186 else if (percentage < 0) percentage = 0; 187 188 plugin.calculateRange(); 189 190 //transform this % into the max range of the element 191 plugin.translateValue = (percentage / 100) * plugin.rangeMax - plugin.rangeMax / 2; 192 193 plugin.oldPercentage = percentage; 194 195 return true; 196 }, 197 198 animate: function() { 199 var plugin = this, 200 inlineCss, 201 translateValueY = plugin.translateValue, 202 translateValueX = 0; 203 204 //check the orientation to know which of X or Y axe should we use 205 if (plugin.options.orientation == 'left' || plugin.options.orientation == 'right') { 206 translateValueY = 0; 207 translateValueX = plugin.translateValue; 208 } 209 210 //prepare style to apply to the element 211 if (plugin.options.overflow == true) { 212 inlineCss = 'scale(' + plugin.options.scale + ') translate3d(' + translateValueX + 'px, ' + translateValueY + 'px, 0)'; 213 } else { 214 inlineCss = 'translate3d(' + translateValueX + 'px, ' + translateValueY + 'px, 0)'; 215 } 216 217 //add style depending the current vendor CSS of the browser 218 plugin.$element[0].style[cssTransform] = inlineCss; 219 }, 220 221 proceedElement: function(elem) { 222 elem.getElementOffset(); 223 224 if (!elem.isVisible()) return; 225 226 if (!elem.calculate()) return; 227 228 elem.animate(); 229 }, 230 231 proceedLoop: function() { 232 var plugin = this; 233 234 SimpleParallax.getViewportOffsetTop(); 235 236 if (lastPosition === SimpleParallax.viewportTop) { 237 plugin.frameID = window.requestAnimationFrame(plugin.proceedLoop.bind(plugin)); 238 return; 239 } else { 240 lastPosition = SimpleParallax.viewportTop; 241 242 for (var i = 0; i < this.occurence.length; i++) { 243 if (i === 0) SimpleParallax.getViewportOffset(); 244 plugin.proceedElement(this.occurence[i]); 245 } 246 247 plugin.frameID = window.requestAnimationFrame(plugin.proceedLoop.bind(plugin)); 248 } 249 }, 250 251 destroy: function() { 252 for (var i = 0; i < this.occurence.length; i++) { 253 this.occurence[i].$element.removeData(); 254 255 this.occurence[i].$element[0].style[cssTransform] = ''; 256 257 this.occurence[i].unWrapElement(); 258 259 window.cancelAnimationFrame(this.occurence[i].frameID); 260 } 261 } 262 }); 263 264 $.fn.simpleParallax = function(options) { 265 var length = this.length; 266 this.each(function(index) { 267 if (!$.data(this, pluginName)) { 268 if (length - 1 == index) isInitialized = true; 269 $.data(this, pluginName, new SimpleParallax(this, options)); 270 } 271 }); 272 273 return this; 274 }; 275 276 $.fn.simpleParallax.defaults = { 277 delay: 0.3, 278 orientation: 'up', 279 scale: 1.2, 280 overflow: true 281 }; 282});
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.