1/*! 2 * Name : Just Another Parallax [Jarallax] 3 * Version : 1.0.0 4 * Author : _nK http://nkdev.info 5 * GitHub : https://github.com/nk-o/jarallax 6 */ 7(function(factory) { 8 'use strict'; 9 if (typeof define === 'function' && define.amd) { 10 define(['jquery'], factory); 11 } else if (typeof exports !== 'undefined') { 12 module.exports = factory(require('jquery')); 13 } else { 14 factory(jQuery); 15 } 16}(function($) { 17 // Adapted from https://gist.github.com/paulirish/1579671 18 if (!Date.now) 19 Date.now = function() { return new Date().getTime(); }; 20 if(!window.requestAnimationFrame) 21 (function() { 22 'use strict'; 23 24 var vendors = ['webkit', 'moz']; 25 for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { 26 var vp = vendors[i]; 27 window.requestAnimationFrame = window[vp+'RequestAnimationFrame']; 28 window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame'] 29 || window[vp+'CancelRequestAnimationFrame']); 30 } 31 if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy 32 || !window.requestAnimationFrame || !window.cancelAnimationFrame) { 33 var lastTime = 0; 34 window.requestAnimationFrame = function(callback) { 35 var now = Date.now(); 36 var nextTime = Math.max(lastTime + 16, now); 37 return setTimeout(function() { callback(lastTime = nextTime); }, 38 nextTime - now); 39 }; 40 window.cancelAnimationFrame = clearTimeout; 41 } 42 }()); 43 44 var supportTransform = (function() { 45 var prefixes = 'transform WebkitTransform MozTransform OTransform msTransform'.split(' '); 46 var div = document.createElement('div'); 47 for(var i = 0; i < prefixes.length; i++) { 48 if(div && div.style[prefixes[i]] !== undefined) { 49 return prefixes[i]; 50 } 51 } 52 return false; 53 }()); 54 55 var support3dtransform = (function() { 56 if (!window.getComputedStyle) { 57 return false; 58 } 59 60 var el = document.createElement('p'), 61 has3d, 62 transforms = { 63 'webkitTransform':'-webkit-transform',
64 'OTransform':'-o-transform', 65 'msTransform':'-ms-transform', 66 'MozTransform':'-moz-transform', 67 'transform':'transform' 68 }; 69 70 // Add it to the body to get the computed style. 71 (document.body || document.documentElement).insertBefore(el, null); 72 73 for (var t in transforms) { 74 if (el.style[t] !== undefined) { 75 el.style[t] = "translate3d(1px,1px,1px)"; 76 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 77 } 78 } 79 80 (document.body || document.documentElement).removeChild(el); 81 82 return (has3d !== undefined && has3d.length > 0 && has3d !== "none"); 83 }()); 84 85 86 // Jarallax instance 87 var Jarallax = (function() { 88 var instanceID = 0; 89 90 function Jarallax(item, userOptions) { 91 var _this = this, 92 dataOptions; 93 94 _this.$item = $(item); 95 96 _this.defaults = { 97 speed : 0.5, 98 imgSrc : null, 99 imgWidth : null, 100 imgHeight : null, 101 enableTransform : true, 102 zIndex : -100 103 }; 104 dataOptions = _this.$item.data('jarallax') || {}; 105 _this.options = $.extend({}, _this.defaults, dataOptions, userOptions); 106 107 // fix speed option [0.0, 1.0] 108 _this.options.speed = Math.min(1, Math.max(0, parseFloat(_this.options.speed))); 109 110 _this.instanceID = instanceID++; 111 112 _this.image = { 113 src : _this.options.imgSrc || null, 114 $container : null, 115 $item : null, 116 width : _this.options.imgWidth || null, 117 height : _this.options.imgHeight || null 118 } 119 120 if(_this.initImg()) { 121 _this.initEvents(); 122 123 _this.init(); 124 } 125 } 126 127 return Jarallax; 128 }()); 129 130 Jarallax.prototype.initImg = function() { 131 var _this = this; 132 133 // get image src 134 if(_this.image.src === null) { 135 _this.image.src = _this.$item.css('background-image').replace(/^url\(['"]?/g,'').replace(/['"]?\)$/g,''); 136 } 137 if(!_this.image.src || _this.image.src === 'none') { 138 return false; 139 } 140 return true; 141 } 142 143 Jarallax.prototype.init = function() { 144 var _this = this; 145 146 // container for parallax image
147 _this.image.$container = $('<div>') 148 .css({ 149 position : 'absolute', 150 top : 0, 151 left : 0, 152 width : '100%', 153 height : '100%', 154 overflow : 'hidden', 155 'pointer-events' : 'none', 156 'transition' : 'transform linear -1ms, -webkit-transform linear -1ms' 157 }) 158 .prependTo(_this.$item); 159 160 // item with background image (this will be moved to create parallax effect) 161 _this.image.$item = _this.image.$container.clone() 162 .css({ 163 position : 'fixed', 164 'pointer-events' : 'none', 165 'background-position' : '50% 50%', 166 'background-repeat' : 'no-repeat no-repeat', 167 'background-image' : 'url(' + _this.image.src + ')' 168 }) 169 .prependTo(_this.image.$container); 170 171 // insert to item 172 _this.image.$container 173 .css({ 174 visibility : 'hidden', 175 'z-index' : _this.options.zIndex 176 }) 177 .attr('id', 'jarallax-container-' + _this.instanceID) 178 .prependTo(_this.$item) 179 180 // cover image and init parallax position after image load 181 _this.getImageSize(_this.image.src, function(width, height) { 182 _this.image.width = width; 183 _this.image.height = height; 184 185 window.requestAnimationFrame($.proxy(_this.coverImage, _this)); 186 window.requestAnimationFrame($.proxy(_this.clipContainer, _this)); 187 window.requestAnimationFrame($.proxy(_this.onScroll, _this)); 188 189 // remove default user background 190 _this.$item.data('JarallaxOriginalStyles', _this.$item.attr('style')); 191 192 // timeout to fix IE blinking 193 setTimeout(function() { 194 _this.$item.css({ 195 'background-image' : 'none', 196 'background-attachment' : 'scroll', 197 'background-size' : 'auto' 198 }); 199 }, 0); 200 }); 201 }; 202 203 Jarallax.prototype.initEvents = function() { 204 var _this = this; 205 206 $(window).on('scroll.jarallax.jarallax-' + _this.instanceID, function() { 207 window.requestAnimationFrame($.proxy(_this.onScroll, _this)); 208 }); 209 210 var timeout; 211 $(window).on('resize.jarallax.jarallax-' + _this.instanceID + ' load.jarallax.jarallax-' + _this.instanceID + '', function() { 212 clearTimeout(timeout); 213 timeout = setTimeout(function() { 214 window.requestAnimationFrame(function() { 215 _this.coverImage(); 216 _this.clipContainer(); 217 _this.onScroll(); 218 }); 219 }, 100); 220 }); 221 } 222 223 Jarallax.prototype.destroy = function() { 224 var _this = this; 225 226 // remove additional styles for clip 227 $('head #jarallax-clip-' + _this.instanceID).remove(); 228 229 $(window).off('.jarallax-' + _this.instanceID); 230 231 _this.$item.attr('style', _this.$item.data('JarallaxOriginalStyles')); 232 _this.$item.removeData('JarallaxOriginalStyles'); 233 234 _this.image.$container.remove(); 235 236 delete _this.$item[0].jarallax; 237 } 238 239 Jarallax.prototype.getImageSize = function(src, callback) { 240 if(!src || !callback) { 241 return false; 242 } 243 244 var tempImg = new Image(); 245 tempImg.onload = function() { 246 callback(tempImg.width, tempImg.height) 247 } 248 tempImg.src = src; 249 } 250 251 // it will remove some image overlapping 252 // overlapping occur due to an image position fixed inside absolute possition element (webkit based browsers works without any fix) 253 Jarallax.prototype.clipContainer = function() { 254 var _this = this, 255 width = _this.image.$container.outerWidth(true), 256 height = _this.image.$container.outerHeight(true); 257 258 var $styles = $('head #jarallax-clip-' + _this.instanceID); 259 if(!$styles.length) { 260 $('head').append('<style type="text/css" id="jarallax-clip-' + _this.instanceID + '"></style>'); 261 $styles = $('head #jarallax-clip-' + _this.instanceID); 262 } 263 264 var css = [ 265 '#jarallax-container-' + _this.instanceID + ' {', 266 ' clip: rect(0px ' + width + 'px ' + height + 'px 0);', 267 ' clip: rect(0px, ' + width + 'px, ' + height + 'px, 0);', 268 '}' 269 ].join('\n'); 270 271 // add clip styles inline (this method need for support IE8 and less browsers) 272 if ($styles[0].styleSheet) { 273 $styles[0].styleSheet.cssText = css; 274 } else { 275 $styles.html(css); 276 } 277 } 278 279 Jarallax.prototype.coverImage = function() { 280 var _this = this; 281 282 if(!_this.image.width || !_this.image.height) { 283 return; 284 } 285 286 var contW = _this.image.$container.outerWidth(true), 287 contH = _this.image.$container.outerHeight(true), 288 wndW = $(window).outerWidth(true), 289 whdH = $(window).outerHeight(true), 290 imgW = _this.image.width, 291 imgH = _this.image.height; 292 293 var css = { 294 width : Math.max(wndW, contW) * Math.max(_this.options.speed, 1), 295 height : Math.max(whdH, contH) * Math.max(_this.options.speed, 1) 296 }; 297 298 // cover by width 299 if(css.width / css.height > imgW / imgH) { 300 var h = css.width * imgH / imgW; 301 css.backgroundSize = css.width + 'px ' + h + 'px'; 302 } 303 304 // cover by height 305 else { 306 var w = css.height * imgW / imgH; 307 css.backgroundSize = w + 'px ' + css.height + 'px'; 308 } 309 310 _this.image.$item.css(css); 311 }; 312 313 Jarallax.prototype.onScroll = function() { 314 var _this = this; 315 316 if(!_this.image.width || !_this.image.height) { 317 return; 318 } 319 320 var scrollTop = $(window).scrollTop(), 321 wndHeight = $(window).height(), 322 // starting position of each element to have parallax applied to it 323 sectionTop = _this.$item.offset().top, 324 sectionHeight = _this.$item.outerHeight(true), 325 css = { 326 visibility : 'visible', 327 backgroundPosition : '50% 50%' 328 }; 329 330 // Check if totally above or totally below viewport 331 if (sectionTop + sectionHeight < scrollTop || sectionTop > scrollTop + wndHeight) { 332 return; 333 } 334 335 // calculate parallax 336 var position = - (scrollTop - sectionTop) * _this.options.speed; 337 338 if(supportTransform && _this.options.enableTransform) { 339 css.transform = 'translateY(' + position + 'px)'; 340 if(support3dtransform) { 341 css.transform = 'translate3d(0, ' + position + 'px, 0)'; 342 } 343 } else { 344 css.backgroundPosition = '50% ' + Math.round(position) + 'px'; 345 } 346 347 _this.image.$item.css(css); 348 } 349 350 var oldJarallax = $.fn.jarallax; 351 352 $.fn.jarallax = function() { 353 var items = this, 354 options = arguments[0], 355 args = Array.prototype.slice.call(arguments, 1), 356 len = items.length, 357 k = 0, 358 ret; 359 360 for (k; k < len; k++) { 361 if (typeof options === 'object' || typeof options === 'undefined') 362 items[k].jarallax = new Jarallax(items[k], options); 363 else 364 ret = items[k].jarallax[options].apply(items[k].jarallax, args); 365 if (typeof ret !== 'undefined') return ret; 366 } 367 368 return this; 369 }; 370 371 // no conflict 372 $.fn.jarallax.noConflict = function () { 373 $.fn.jarallax = oldJarallax; 374 return this; 375 }; 376 377 // data-jarallax initialization 378 $(document).on('ready.data-jarallax', function () { 379 $('[data-jarallax]').jarallax();
380 }); 381}));
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.