vendor: 4,532 bytes, lines 1-219
1/* 2 * Vide - v0.3.2 3 * Easy as hell jQuery plugin for video backgrounds. 4 * http://vodkabears.github.io/vide/ 5 * 6 * Made by Ilya Makarov 7 * Under MIT License 8 */ 9!(function($, window, document, navigator) { 10 'use strict'; 11 12 /** 13 * Name of the plugin 14 * @private 15 */ 16 var pluginName = 'vide'; 17 18 /** 19 * Default settings 20 * @private 21 */ 22 var defaults = { 23 volume: 1, 24 playbackRate: 1, 25 muted: true, 26 loop: true, 27 autoplay: true, 28 position: '50% 50%', 29 posterType: 'detect', 30 resizing: true 31 }; 32 33 /** 34 * Is iOs? 35 * @private 36 */ 37 var isIOS = /iPad|iPhone|iPod/i.test(navigator.userAgent); 38 39 /** 40 * Is Android? 41 * @private 42 */ 43 var isAndroid = /Android/i.test(navigator.userAgent); 44 45 /** 46 * Parse a string with options 47 * @private 48 * @param {String} str 49 * @returns {Object|String} 50 */ 51 function parseOptions(str) { 52 var obj = {}; 53 var delimiterIndex; 54 var option; 55 var prop; 56 var val; 57 var arr; 58 var len; 59 var i; 60 61 // Remove spaces around delimiters and split 62 arr = str.replace(/\s*:\s*/g, ':').replace(/\s*,\s*/g, ',').split(','); 63 64 // Parse a string 65 for (i = 0, len = arr.length; i < len; i++) { 66 option = arr[i]; 67 68 // Ignore urls and a string without colon delimiters 69 if ( 70 option.search(/^(http|https|ftp):\/\//) !== -1 || 71 option.search(':') === -1 72 ) { 73 break; 74 } 75 76 delimiterIndex = option.indexOf(':'); 77 prop = option.substring(0, delimiterIndex); 78 val = option.substring(delimiterIndex + 1); 79 80 // If val is an empty string, make it undefined 81 if (!val) { 82 val = undefined; 83 } 84 85 // Convert a string value if it is like a boolean 86 if (typeof val === 'string') { 87 val = val === 'true' || (val === 'false' ? false : val); 88 } 89 90 // Convert a string value if it is like a number 91 if (typeof val === 'string') { 92 val = !isNaN(val) ? +val : val; 93 } 94 95 obj[prop] = val; 96 } 97 98 // If nothing is parsed 99 if (prop == null && val == null) { 100 return str; 101 } 102 103 return obj; 104 } 105 106 /** 107 * Parse a position option 108 * @private 109 * @param {String} str 110 * @returns {Object} 111 */ 112 function parsePosition(str) { 113 str = '' + str; 114 115 // Default value is a center 116 var args = str.split(/\s+/); 117 var x = '50%'; 118 var y = '50%'; 119 var len; 120 var arg; 121 var i; 122 123 for (i = 0, len = args.length; i < len; i++) { 124 arg = args[i]; 125 126 // Convert values 127 if (arg === 'left') { 128 x = '0%'; 129 } else if (arg === 'right') { 130 x = '100%'; 131 } else if (arg === 'top') { 132 y = '0%'; 133 } else if (arg === 'bottom') { 134 y = '100%'; 135 } else if (arg === 'center') { 136 if (i === 0) { 137 x = '50%'; 138 } else { 139 y = '50%'; 140 } 141 } else { 142 if (i === 0) { 143 x = arg; 144 } else { 145 y = arg; 146 } 147 } 148 } 149 150 return { x: x, y: y }; 151 } 152 153 /** 154 * Search a poster 155 * @private 156 * @param {String} path 157 * @param {Function} callback 158 */ 159 function findPoster(path, callback) { 160 var onLoad = function() { 161 callback(this.src); 162 }; 163 164 $('<img src="' + path + '.gif">').load(onLoad); 165 $('<img src="' + path + '.jpg">').load(onLoad); 166 $('<img src="' + path + '.jpeg">').load(onLoad); 167 $('<img src="' + path + '.png">').load(onLoad); 168 } 169 170 /** 171 * Vide constructor 172 * @param {HTMLElement} element 173 * @param {Object|String} path 174 * @param {Object|String} options 175 * @constructor 176 */ 177 function Vide(element, path, options) { 178 this.$element = $(element); 179 180 // Parse path 181 if (typeof path === 'string') { 182 path = parseOptions(path); 183 } 184 185 // Parse options 186 if (!options) { 187 options = {}; 188 } else if (typeof options === 'string') { 189 options = parseOptions(options); 190 } 191 192 // Remove an extension 193 if (typeof path === 'string') { 194 path = path.replace(/\.\w*$/, ''); 195 } else if (typeof path === 'object') { 196 for (var i in path) { 197 if (path.hasOwnProperty(i)) { 198 path[i] = path[i].replace(/\.\w*$/, ''); 199 } 200 } 201 } 202 203 this.settings = $.extend({}, defaults, options); 204 this.path = path; 205 206 this.init(); 207 } 208 209 /** 210 * Initialization 211 * @public 212 */ 213 Vide.prototype.init = function() { 214 var vide = this; 215 var position = parsePosition(vide.settings.position); 216 var sources; 217 var poster; 218 219 // Set styles of a video wrapper
220 vide.$wrapper = $('<div>').css({ 221 position: 'absolute', 222 'z-index': -1, 223 top: 0, 224 left: 0, 225 bottom: 0, 226 right: 0, 227 overflow: 'hidden', 228 '-webkit-background-size': 'cover', 229 '-moz-background-size': 'cover', 230 '-o-background-size': 'cover', 231 'background-size': 'cover', 232 'background-repeat': 'no-repeat', 233 'background-position': position.x + ' ' + position.y 234 }); 235 236 // Get a poster path 237 poster = vide.path; 238 if (typeof vide.path === 'object') { 239 if (vide.path.poster) { 240 poster = vide.path.poster; 241 } else { 242 if (vide.path.mp4) { 243 poster = vide.path.mp4; 244 } else if (vide.path.webm) { 245 poster = vide.path.webm; 246 } else if (vide.path.ogv) { 247 poster = vide.path.ogv; 248 } 249 } 250 } 251 252 // Set a video poster 253 if (vide.settings.posterType === 'detect') { 254 findPoster(poster, function(url) { 255 vide.$wrapper.css('background-image', 'url(' + url + ')'); 256 }); 257 } else if (vide.settings.posterType !== 'none') { 258 vide.$wrapper 259 .css('background-image', 'url(' + poster + '.' + vide.settings.posterType + ')'); 260 } 261 262 // If a parent element has a static position, make it relative 263 if (vide.$element.css('position') === 'static') { 264 vide.$element.css('position', 'relative'); 265 } 266 267 vide.$element.prepend(vide.$wrapper); 268 269 if (!isIOS && !isAndroid) { 270 sources = ''; 271 272 if (typeof vide.path === 'object') { 273 if (vide.path.mp4) { 274 sources += '<source src="' + vide.path.mp4 + '.mp4" type="video/mp4">'; 275 } 276 277 if (vide.path.webm) { 278 sources += '<source src="' + vide.path.webm + '.webm" type="video/webm">'; 279 } 280 281 if (vide.path.ogv) { 282 sources += '<source src="' + vide.path.ogv + '.ogv" type="video/ogv">'; 283 } 284 285 vide.$video = $('<video>' + sources + '</video>'); 286 } else { 287 vide.$video = $('<video>' + 288 '<source src="' + vide.path + '.mp4" type="video/mp4">' + 289 '<source src="' + vide.path + '.webm" type="video/webm">' + 290 '<source src="' + vide.path + '.ogv" type="video/ogg">' + 291 '</video>'); 292 } 293 294 // Disable visibility, while loading 295 vide.$video.css('visibility', 'hidden'); 296 297 // Set video properties 298 vide.$video.prop({ 299 autoplay: vide.settings.autoplay, 300 loop: vide.settings.loop, 301 volume: vide.settings.volume, 302 muted: vide.settings.muted, 303 defaultMuted: vide.settings.muted, 304 playbackRate: vide.settings.playbackRate, 305 defaultPlaybackRate: vide.settings.playbackRate 306 }); 307 308 // Append a video 309 vide.$wrapper.append(vide.$video); 310 311 // Video alignment 312 vide.$video.css({ 313 margin: 'auto', 314 position: 'absolute', 315 'z-index': -1, 316 top: position.y, 317 left: position.x, 318 '-webkit-transform': 'translate(-' + position.x + ', -' + position.y + ')',
319 '-ms-transform': 'translate(-' + position.x + ', -' + position.y + ')', 320 '-moz-transform': 'translate(-' + position.x + ', -' + position.y + ')', 321 transform: 'translate(-' + position.x + ', -' + position.y + ')' 322 }); 323 324 // Resize a video, when it's loaded 325 vide.$video.on('canplaythrough.' + pluginName, function() { 326 vide.$video.css('visibility', 'visible'); 327 328 // Force to play, important for Safari 329 vide.$video.prop('autoplay') && vide.$video[0].play(); 330 331 vide.resize(); 332 vide.$wrapper.css('background-image', 'none'); 333 }); 334 335 // Resize event is available only for 'window' 336 // Use another code solutions to detect DOM elements resizing 337 vide.$element.on('resize.' + pluginName, function() { 338 if (vide.settings.resizing) { 339 vide.resize(); 340 } 341 }); 342 } 343 }; 344 345 /** 346 * Get a video element 347 * @public 348 * @returns {HTMLVideoElement|null} 349 */ 350 Vide.prototype.getVideoObject = function() { 351 return this.$video ? this.$video[0] : null; 352 }; 353 354 /** 355 * Resize a video background 356 * @public 357 */ 358 Vide.prototype.resize = function() { 359 if (!this.$video) { 360 return; 361 } 362 363 // Get a native video size 364 var videoHeight = this.$video[0].videoHeight; 365 var videoWidth = this.$video[0].videoWidth; 366 367 // Get a wrapper size 368 var wrapperHeight = this.$wrapper.height(); 369 var wrapperWidth = this.$wrapper.width(); 370 371 if (wrapperWidth / videoWidth > wrapperHeight / videoHeight) { 372 this.$video.css({ 373 374 // +2 pixels to prevent an empty space after transformation
vendor: 2,253 bytes, lines 375-466
375 width: wrapperWidth + 2, 376 height: 'auto' 377 }); 378 } else { 379 this.$video.css({ 380 width: 'auto', 381 382 // +2 pixels to prevent an empty space after transformation 383 height: wrapperHeight + 2 384 }); 385 } 386 }; 387 388 /** 389 * Destroy a video background 390 * @public 391 */ 392 Vide.prototype.destroy = function() { 393 this.$element.off(pluginName); 394 395 if (this.$video) { 396 this.$video.off(pluginName); 397 } 398 399 delete $[pluginName].lookup[this.index]; 400 this.$element.removeData(pluginName); 401 this.$wrapper.remove(); 402 }; 403 404 /** 405 * Special plugin object for instances. 406 * @public 407 * @type {Object} 408 */ 409 $[pluginName] = { 410 lookup: [] 411 }; 412 413 /** 414 * Plugin constructor 415 * @param {Object|String} path 416 * @param {Object|String} options 417 * @returns {JQuery} 418 * @constructor 419 */ 420 $.fn[pluginName] = function(path, options) { 421 var instance; 422 423 this.each(function() { 424 instance = $.data(this, pluginName); 425 426 if (instance) { 427 428 // Destroy the plugin instance if exists 429 instance.destroy(); 430 } 431 432 // Create the plugin instance 433 instance = new Vide(this, path, options); 434 instance.index = $[pluginName].lookup.push(instance) - 1; 435 $.data(this, pluginName, instance); 436 }); 437 438 return this; 439 }; 440 441 $(document).ready(function() { 442 443 // Window resize event listener 444 $(window).on('resize.' + pluginName, function() { 445 for (var len = $[pluginName].lookup.length, i = 0, instance; i < len; i++) { 446 instance = $[pluginName].lookup[i]; 447 448 if (instance && instance.settings.resizing) { 449 instance.resize(); 450 } 451 } 452 }); 453 454 // Auto initialization 455 // Add 'data-vide-bg' attribute with a path to the video without extension 456 // Also you can pass options throw the 'data-vide-options' attribute 457 // 'data-vide-options' must be like 'muted: false, volume: 0.5' 458 $(document).find('[data-' + pluginName + '-bg]').each(function(i, element) { 459 var $element = $(element); 460 var options = $element.data(pluginName + '-options'); 461 var path = $element.data(pluginName + '-bg'); 462 463 $element[pluginName](path, options); 464 }); 465 }); 466})(window.jQuery, window, document, navigator);
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.