1/*! 2 * parallax.js v1.5.0 (http://pixelcog.github.io/parallax.js/) 3 * @copyright 2016 PixelCog, Inc. 4 * @license MIT (https://github.com/pixelcog/parallax.js/blob/master/LICENSE) 5 */ 6 7;(function ( $, window, document, undefined ) { 8 9 // Polyfill for requestAnimationFrame 10 // via: https://gist.github.com/paulirish/1579671 11 12 (function() { 13 var lastTime = 0; 14 var vendors = ['ms', 'moz', 'webkit', 'o']; 15 for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 16 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 17 window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; 18 } 19 20 if (!window.requestAnimationFrame) 21 window.requestAnimationFrame = function(callback) { 22 var currTime = new Date().getTime(); 23 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 24 var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 25 timeToCall); 26 lastTime = currTime + timeToCall; 27 return id; 28 }; 29 30 if (!window.cancelAnimationFrame) 31 window.cancelAnimationFrame = function(id) { 32 clearTimeout(id); 33 }; 34 }()); 35 36 37 // Parallax Constructor 38 39 function Parallax(element, options) { 40 var self = this; 41 42 if (typeof options == 'object') { 43 delete options.refresh; 44 delete options.render; 45 $.extend(this, options); 46 } 47 48 this.$element = $(element); 49 50 if (!this.imageSrc && this.$element.is('img')) { 51 this.imageSrc = this.$element.attr('src'); 52 } 53 54 var positions = (this.position + '').toLowerCase().match(/\S+/g) || []; 55 56 if (positions.length < 1) { 57 positions.push('center'); 58 } 59 if (positions.length == 1) { 60 positions.push(positions[0]); 61 } 62 63 if (positions[0] == 'top' || positions[0] == 'bottom' || positions[1] == 'left' || positions[1] == 'right') { 64 positions = [positions[1], positions[0]]; 65 } 66 67 if (this.positionX !== undefined) positions[0] = this.positionX.toLowerCase(); 68 if (this.positionY !== undefined) positions[1] = this.positionY.toLowerCase(); 69 70 self.positionX = positions[0]; 71 self.positionY = positions[1]; 72 73 if (this.positionX != 'left' && this.positionX != 'right') { 74 if (isNaN(parseInt(this.positionX))) { 75 this.positionX = 'center'; 76 } else { 77 this.positionX = parseInt(this.positionX); 78 } 79 } 80 81 if (this.positionY != 'top' && this.positionY != 'bottom') { 82 if (isNaN(parseInt(this.positionY))) { 83 this.positionY = 'center'; 84 } else { 85 this.positionY = parseInt(this.positionY); 86 } 87 } 88 89 this.position = 90 this.positionX + (isNaN(this.positionX)? '' : 'px') + ' ' + 91 this.positionY + (isNaN(this.positionY)? '' : 'px'); 92 93 if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) { 94 if (this.imageSrc && this.iosFix && !this.$element.is('img')) { 95 this.$element.css({ 96 backgroundImage: 'url(' + this.imageSrc + ')', 97 backgroundSize: 'cover', 98 backgroundPosition: this.position 99 }); 100 } 101 return this; 102 } 103 104 if (navigator.userAgent.match(/(Android)/)) { 105 if (this.imageSrc && this.androidFix && !this.$element.is('img')) { 106 this.$element.css({ 107 backgroundImage: 'url(' + this.imageSrc + ')', 108 backgroundSize: 'cover', 109 backgroundPosition: this.position 110 }); 111 } 112 return this; 113 } 114 115 this.$mirror = $('<div />').prependTo(this.mirrorContainer); 116 117 var slider = this.$element.find('>.parallax-slider'); 118 var sliderExisted = false; 119 120 if (slider.length == 0) 121 this.$slider = $('<img />').prependTo(this.$mirror); 122 else { 123 this.$slider = slider.prependTo(this.$mirror) 124 sliderExisted = true; 125 } 126 127 this.$mirror.addClass('parallax-mirror').css({ 128 visibility: 'hidden', 129 zIndex: this.zIndex, 130 position: 'fixed', 131 top: 0, 132 left: 0, 133 overflow: 'hidden' 134 });
135 136 this.$slider.addClass('parallax-slider').one('load', function() { 137 if (!self.naturalHeight || !self.naturalWidth) { 138 self.naturalHeight = this.naturalHeight || this.height || 1; 139 self.naturalWidth = this.naturalWidth || this.width || 1; 140 } 141 self.aspectRatio = self.naturalWidth / self.naturalHeight; 142 143 Parallax.isSetup || Parallax.setup(); 144 Parallax.sliders.push(self); 145 Parallax.isFresh = false; 146 Parallax.requestRender(); 147 }); 148 149 if (!sliderExisted) 150 this.$slider[0].src = this.imageSrc; 151 152 if (this.naturalHeight && this.naturalWidth || this.$slider[0].complete || slider.length > 0) { 153 this.$slider.trigger('load'); 154 } 155 156 } 157 158 159 // Parallax Instance Methods 160 161 $.extend(Parallax.prototype, { 162 speed: 0.2, 163 bleed: 0, 164 zIndex: -100, 165 iosFix: true, 166 androidFix: true, 167 position: 'center', 168 overScrollFix: false, 169 mirrorContainer: 'body', 170 171 refresh: function() { 172 this.boxWidth = this.$element.outerWidth(); 173 this.boxHeight = this.$element.outerHeight() + this.bleed * 2; 174 this.boxOffsetTop = this.$element.offset().top - this.bleed; 175 this.boxOffsetLeft = this.$element.offset().left; 176 this.boxOffsetBottom = this.boxOffsetTop + this.boxHeight; 177 178 var winHeight = Parallax.winHeight; 179 var docHeight = Parallax.docHeight; 180 var maxOffset = Math.min(this.boxOffsetTop, docHeight - winHeight); 181 var minOffset = Math.max(this.boxOffsetTop + this.boxHeight - winHeight, 0); 182 var imageHeightMin = this.boxHeight + (maxOffset - minOffset) * (1 - this.speed) | 0; 183 var imageOffsetMin = (this.boxOffsetTop - maxOffset) * (1 - this.speed) | 0; 184 var margin; 185 186 if (imageHeightMin * this.aspectRatio >= this.boxWidth) { 187 this.imageWidth = imageHeightMin * this.aspectRatio | 0; 188 this.imageHeight = imageHeightMin; 189 this.offsetBaseTop = imageOffsetMin; 190 191 margin = this.imageWidth - this.boxWidth; 192 193 if (this.positionX == 'left') { 194 this.offsetLeft = 0; 195 } else if (this.positionX == 'right') { 196 this.offsetLeft = - margin; 197 } else if (!isNaN(this.positionX)) { 198 this.offsetLeft = Math.max(this.positionX, - margin); 199 } else { 200 this.offsetLeft = - margin / 2 | 0; 201 } 202 } else { 203 this.imageWidth = this.boxWidth; 204 this.imageHeight = this.boxWidth / this.aspectRatio | 0; 205 this.offsetLeft = 0; 206 207 margin = this.imageHeight - imageHeightMin; 208 209 if (this.positionY == 'top') { 210 this.offsetBaseTop = imageOffsetMin; 211 } else if (this.positionY == 'bottom') { 212 this.offsetBaseTop = imageOffsetMin - margin; 213 } else if (!isNaN(this.positionY)) { 214 this.offsetBaseTop = imageOffsetMin + Math.max(this.positionY, - margin); 215 } else { 216 this.offsetBaseTop = imageOffsetMin - margin / 2 | 0; 217 } 218 } 219 }, 220 221 render: function() { 222 var scrollTop = Parallax.scrollTop; 223 var scrollLeft = Parallax.scrollLeft; 224 var overScroll = this.overScrollFix ? Parallax.overScroll : 0; 225 var scrollBottom = scrollTop + Parallax.winHeight; 226 227 if (this.boxOffsetBottom > scrollTop && this.boxOffsetTop <= scrollBottom) { 228 this.visibility = 'visible'; 229 this.mirrorTop = this.boxOffsetTop - scrollTop; 230 this.mirrorLeft = this.boxOffsetLeft - scrollLeft; 231 this.offsetTop = this.offsetBaseTop - this.mirrorTop * (1 - this.speed); 232 } else { 233 this.visibility = 'hidden'; 234 } 235 236 this.$mirror.css({ 237 transform: 'translate3d('+this.mirrorLeft+'px, '+(this.mirrorTop - overScroll)+'px, 0px)', 238 visibility: this.visibility, 239 height: this.boxHeight, 240 width: this.boxWidth 241 }); 242 243 this.$slider.css({ 244 transform: 'translate3d('+this.offsetLeft+'px, '+this.offsetTop+'px, 0px)', 245 position: 'absolute', 246 height: this.imageHeight, 247 width: this.imageWidth, 248 maxWidth: 'none' 249 }); 250 } 251 }); 252 253 254 // Parallax Static Methods 255 256 $.extend(Parallax, { 257 scrollTop: 0, 258 scrollLeft: 0, 259 winHeight: 0, 260 winWidth: 0, 261 docHeight: 1 << 30, 262 docWidth: 1 << 30, 263 sliders: [], 264 isReady: false, 265 isFresh: false, 266 isBusy: false, 267 268 setup: function() { 269 if (this.isReady) return; 270 271 var self = this; 272 273 var $doc = $(document), $win = $(window); 274 275 var loadDimensions = function() { 276 Parallax.winHeight = $win.height(); 277 Parallax.winWidth = $win.width(); 278 Parallax.docHeight = $doc.height(); 279 Parallax.docWidth = $doc.width(); 280 }; 281 282 var loadScrollPosition = function() { 283 var winScrollTop = $win.scrollTop(); 284 var scrollTopMax = Parallax.docHeight - Parallax.winHeight; 285 var scrollLeftMax = Parallax.docWidth - Parallax.winWidth; 286 Parallax.scrollTop = Math.max(0, Math.min(scrollTopMax, winScrollTop)); 287 Parallax.scrollLeft = Math.max(0, Math.min(scrollLeftMax, $win.scrollLeft())); 288 Parallax.overScroll = Math.max(winScrollTop - scrollTopMax, Math.min(winScrollTop, 0)); 289 }; 290 291 $win.on('resize.px.parallax load.px.parallax', function() { 292 loadDimensions(); 293 self.refresh();
294 Parallax.isFresh = false; 295 Parallax.requestRender(); 296 }) 297 .on('scroll.px.parallax load.px.parallax', function() { 298 loadScrollPosition(); 299 Parallax.requestRender(); 300 }); 301$(".promo-close").on("click", function() { 302 303 $(".promo-wrapper").hide(); 304 loadDimensions(); 305 self.refresh(); 306 Parallax.isFresh = false; 307 Parallax.requestRender(); 308}); 309 loadDimensions(); 310 loadScrollPosition(); 311 312 this.isReady = true; 313 314 var lastPosition = -1; 315 316 function frameLoop() { 317 if (lastPosition == window.pageYOffset) { // Avoid overcalculations 318 window.requestAnimationFrame(frameLoop); 319 return false; 320 } else lastPosition = window.pageYOffset; 321 322 self.render(); 323 window.requestAnimationFrame(frameLoop); 324 } 325 326 frameLoop(); 327 }, 328 329 configure: function(options) { 330 if (typeof options == 'object') { 331 delete options.refresh; 332 delete options.render; 333 $.extend(this.prototype, options); 334 } 335 }, 336 337 refresh: function() { 338 $.each(this.sliders, function(){ this.refresh(); }); 339 this.isFresh = true; 340 }, 341 342 render: function() { 343 this.isFresh || this.refresh(); 344 $.each(this.sliders, function(){ this.render(); }); 345 }, 346 347 requestRender: function() { 348 var self = this; 349 self.render(); 350 self.isBusy = false; 351 }, 352 destroy: function(el){ 353 var i, 354 parallaxElement = $(el).data('px.parallax'); 355 parallaxElement.$mirror.remove(); 356 for(i=0; i < this.sliders.length; i+=1){ 357 if(this.sliders[i] == parallaxElement){ 358 this.sliders.splice(i, 1); 359 } 360 } 361 $(el).data('px.parallax', false); 362 if(this.sliders.length === 0){ 363 $(window).off('scroll.px.parallax resize.px.parallax load.px.parallax'); 364 this.isReady = false; 365 Parallax.isSetup = false; 366 } 367 } 368 }); 369 370 371 // Parallax Plugin Definition 372 373 function Plugin(option) { 374 return this.each(function () { 375 var $this = $(this); 376 var options = typeof option == 'object' && option; 377 378 if (this == window || this == document || $this.is('body')) { 379 Parallax.configure(options); 380 } 381 else if (!$this.data('px.parallax')) { 382 options = $.extend({}, $this.data(), options); 383 $this.data('px.parallax', new Parallax(this, options)); 384 } 385 else if (typeof option == 'object') 386 { 387 $.extend($this.data('px.parallax'), options); 388 } 389 if (typeof option == 'string') { 390 if(option == 'destroy'){ 391 Parallax.destroy(this); 392 }else{ 393 Parallax[option](); 394 } 395 } 396 }); 397 } 398 399 var old = $.fn.parallax; 400 401 $.fn.parallax = Plugin; 402 $.fn.parallax.Constructor = Parallax; 403 404 405 // Parallax No Conflict 406 407 $.fn.parallax.noConflict = function () { 408 $.fn.parallax = old; 409 return this; 410 }; 411 412 413 // Parallax Data-API 414 415 $( function () { 416 $('[data-parallax="scroll"]').parallax(); 417 }); 418 419}(jQuery, window, document));
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.