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