PageSourceSearch

https://fundacion.mtc.es/plugins/vide/jquery.vide.js

js mtc.es collected 2026-10-02 11:05:37 UTC 11,420 bytes, 466 lines download raw bytes

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.