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