Skip to content

Commit 02f590a

Browse files
committed
Release v0.1.0
1 parent ec9d24f commit 02f590a

File tree

2 files changed

+338
-0
lines changed

2 files changed

+338
-0
lines changed

dist/jquery.vide.js

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
/*
2+
* Vide - v0.1.0
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+
* Vide settings
14+
*/
15+
var pluginName = "vide",
16+
defaults = {
17+
volume: 1,
18+
playbackRate: 1,
19+
muted: true,
20+
loop: true,
21+
autoplay: true,
22+
position: "50% 50%"
23+
};
24+
25+
/**
26+
* Is iOs or Android?
27+
*/
28+
var iOS = /iPad|iPhone|iPod/i.test(navigator.userAgent),
29+
android = /Android/i.test(navigator.userAgent);
30+
31+
/**
32+
* Special plugin object for instances.
33+
* @type {Object}
34+
*/
35+
$[pluginName] = {
36+
lookup: []
37+
};
38+
39+
/**
40+
* Parse string with options
41+
* @param str
42+
* @returns {Object}
43+
*/
44+
var parseOptions = function (str) {
45+
var obj = {}, clearedStr, arr;
46+
47+
// remove spaces before and after delimiters
48+
clearedStr = str.replace(/\s*:\s*/g, ":").replace(/\s*,\s*/g, ",");
49+
50+
// parse string
51+
arr = clearedStr.split(",");
52+
var i, len, val;
53+
for (i = 0, len = arr.length; i < len; i++) {
54+
arr[i] = arr[i].split(":");
55+
val = arr[i][1];
56+
57+
// convert string value if it is like a boolean
58+
if (typeof val === "string" || val instanceof String) {
59+
val = val === "true" || (val === "false" ? false : val);
60+
}
61+
62+
// convert string value if it is like a number
63+
if (typeof val === "string" || val instanceof String) {
64+
val = !isNaN(val) ? +val : val;
65+
}
66+
67+
obj[arr[i][0]] = val;
68+
}
69+
70+
return obj;
71+
};
72+
73+
/**
74+
* Parse position option
75+
* @param str
76+
* @returns {{x: *, y: *}}
77+
*/
78+
var parsePosition = function (str) {
79+
var args = str.split(" ");
80+
81+
switch (args[0]) {
82+
case "left":
83+
args[0] = "0%";
84+
break;
85+
case "center":
86+
args[0] = "50%";
87+
break;
88+
case "right":
89+
args[0] = "100%";
90+
break;
91+
default:
92+
break;
93+
}
94+
95+
switch (args[1]) {
96+
case "top":
97+
args[1] = "0";
98+
break;
99+
case "middle":
100+
args[1] = "50%";
101+
break;
102+
case "bottom":
103+
args[1] = "100%";
104+
break;
105+
default:
106+
break;
107+
}
108+
109+
return { x: args[0], y: args[1] };
110+
};
111+
112+
/**
113+
* Vide constructor
114+
* @param element
115+
* @param path
116+
* @param options
117+
* @constructor
118+
*/
119+
function Vide(element, path, options) {
120+
this.element = $(element);
121+
this._defaults = defaults;
122+
this._name = pluginName;
123+
124+
// remove extension
125+
var index = path.lastIndexOf(".");
126+
path = path.slice(0, index < 0 ? path.length : index);
127+
128+
this.settings = $.extend({}, defaults, options);
129+
this.path = path;
130+
131+
this.init();
132+
}
133+
134+
/**
135+
* Initialization
136+
*/
137+
Vide.prototype.init = function () {
138+
var that = this;
139+
140+
this.wrapper = $("<div>");
141+
142+
// Set video wrapper styles
143+
this.wrapper.css({
144+
"position": "absolute",
145+
"z-index": -1,
146+
"top": 0,
147+
"left": 0,
148+
"bottom": 0,
149+
"right": 0,
150+
"overflow": "hidden",
151+
"-webkit-background-size": "cover",
152+
"-moz-background-size": "cover",
153+
"-o-background-size": "cover",
154+
"background-size": "cover",
155+
"background-repeat": "no-repeat",
156+
"background-position": "center center"
157+
});
158+
159+
// Set video poster
160+
$.get(this.path + ".png")
161+
.done(function () {
162+
that.wrapper.css("background-image", "url(" + that.path + ".png)");
163+
});
164+
$.get(this.path + ".jpg")
165+
.done(function () {
166+
that.wrapper.css("background-image", "url(" + that.path + ".jpg)");
167+
});
168+
$.get(this.path + ".gif")
169+
.done(function () {
170+
that.wrapper.css("background-image", "url(" + that.path + ".gif)");
171+
});
172+
173+
// if parent element has a static position, make it relative
174+
if (this.element.css("position") === "static") {
175+
this.element.css("position", "relative");
176+
}
177+
178+
this.element.prepend(this.wrapper);
179+
180+
if (!iOS && !android) {
181+
this.video = $("<video>" +
182+
"<source src='" + this.path + ".mp4' type='video/mp4'>" +
183+
"<source src='" + this.path + ".webm' type='video/webm'>" +
184+
"<source src='" + this.path + ".ogv' type='video/ogg'>" +
185+
"</video>");
186+
187+
// Disable visibility, while loading
188+
this.video.css("visibility", "hidden");
189+
190+
// Set video properties
191+
this.video.prop({
192+
autoplay: this.settings.autoplay,
193+
loop: this.settings.loop,
194+
volume: this.settings.volume,
195+
muted: this.settings.muted,
196+
playbackRate: this.settings.playbackRate
197+
});
198+
199+
// Append video
200+
this.wrapper.append(this.video);
201+
202+
// Video alignment
203+
var position = parsePosition(this.settings.position);
204+
this.video.css({
205+
"margin": "auto",
206+
"position": "absolute",
207+
"z-index": -1,
208+
"top": position.y,
209+
"left": position.x,
210+
"-webkit-transform": "translate(-" + position.x + ", -" + position.y + ")",
211+
"-ms-transform": "translate(-" + position.x + ", -" + position.y + ")",
212+
"transform": "translate(-" + position.x + ", -" + position.y + ")"
213+
});
214+
215+
// resize video, when it's loaded
216+
this.video.bind("loadedmetadata." + pluginName, function () {
217+
that.video.css("visibility", "visible");
218+
that.resize();
219+
});
220+
221+
// resize event is available only for 'window',
222+
// use another code solutions to detect DOM elements resizing
223+
$(this.element).bind("resize." + pluginName, function () {
224+
that.resize();
225+
});
226+
}
227+
};
228+
229+
/**
230+
* Get video element of the background
231+
* @returns {HTMLVideoElement}
232+
*/
233+
Vide.prototype.getVideoObject = function () {
234+
return this.video ? this.video[0] : null;
235+
};
236+
237+
/**
238+
* Resize video background
239+
*/
240+
Vide.prototype.resize = function () {
241+
if (!this.video) {
242+
return;
243+
}
244+
245+
// get native video size
246+
var videoHeight = this.video[0].videoHeight,
247+
videoWidth = this.video[0].videoWidth;
248+
249+
// get wrapper size
250+
var wrapperHeight = this.wrapper.height(),
251+
wrapperWidth = this.wrapper.width();
252+
253+
if (wrapperWidth / videoWidth > wrapperHeight / videoHeight) {
254+
this.video.css({
255+
"width": wrapperWidth + 2, // +2 pixels to prevent empty space after transformation
256+
"height": "auto"
257+
});
258+
} else {
259+
this.video.css({
260+
"width": "auto",
261+
"height": wrapperHeight + 2 // +2 pixels to prevent empty space after transformation
262+
});
263+
}
264+
};
265+
266+
/**
267+
* Destroy video background
268+
*/
269+
Vide.prototype.destroy = function () {
270+
this.element.unbind(pluginName);
271+
this.video.unbind(pluginName);
272+
delete $[pluginName].lookup[this.index];
273+
this.element.removeData(pluginName);
274+
this.wrapper.remove();
275+
};
276+
277+
/**
278+
* Plugin constructor
279+
* @param path
280+
* @param options
281+
* @returns {*}
282+
*/
283+
$.fn[pluginName] = function (path, options) {
284+
var instance;
285+
this.each(function () {
286+
instance = $.data(this, pluginName);
287+
if (instance) {
288+
// destroy plugin instance if exists
289+
instance.destroy();
290+
}
291+
// create plugin instance
292+
instance = new Vide(this, path, options);
293+
instance.index = $[pluginName].lookup.push(instance) - 1;
294+
$.data(this, pluginName, instance);
295+
});
296+
297+
return this;
298+
};
299+
300+
$(document).ready(function () {
301+
// window resize event listener
302+
$(window).bind("resize." + pluginName, function () {
303+
for (var len = $[pluginName].lookup.length, instance, i = 0; i < len; i++) {
304+
instance = $[pluginName].lookup[i];
305+
if (instance) {
306+
instance.resize();
307+
}
308+
}
309+
});
310+
311+
// Auto initialization.
312+
// Add 'data-vide-bg' attribute with a path to the video without extension.
313+
// Also you can pass options throw the 'data-vide-options' attribute.
314+
// 'data-vide-options' must be like "muted: false, volume: 0.5".
315+
$(document).find("[data-" + pluginName + "-bg]").each(function (i, element) {
316+
var $element = $(element),
317+
options = $element.data(pluginName + "-options"),
318+
path = $element.data(pluginName + "-bg");
319+
320+
if (!options) {
321+
options = {};
322+
} else {
323+
options = parseOptions(options);
324+
}
325+
326+
$element[pluginName](path, options);
327+
});
328+
});
329+
})(jQuery || Zepto, window, document, navigator);

dist/jquery.vide.min.js

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)