|
|
/* * YoutubeBackground - A wrapper for the Youtube API - Great for fullscreen background videos or just regular videos. * * Licensed under the MIT license: * http://www.opensource.org/licenses/mit-license.php
* * * Version: 1.0.5 * */
// Chain of Responsibility pattern. Creates base class that can be overridden.
if (typeof Object.create !== "function") { Object.create = function(obj) { function F() {} F.prototype = obj; return new F(); }; }
(function($, window, document) { var loadAPI = function loadAPI(callback) {
// Load Youtube API
var tag = document.createElement('script'), head = document.getElementsByTagName('head')[0]; if(window.location.origin == 'file://') { tag.src = 'http://www.youtube.com/iframe_api'; } else { tag.src = '//www.youtube.com/iframe_api'; } head.appendChild(tag);
// Clean up Tags.
head = null; tag = null;
iframeIsReady(callback); }, iframeIsReady = function iframeIsReady(callback) { // Listen for Gobal YT player callback
if (typeof YT === 'undefined' && typeof window.loadingPlayer === 'undefined') { // Prevents Ready Event from being called twice
window.loadingPlayer = true;
// Creates deferred so, other players know when to wait.
window.dfd = $.Deferred(); window.onYouTubeIframeAPIReady = function() { window.onYouTubeIframeAPIReady = null; window.dfd.resolve( "done" ); callback(); }; } else if (typeof YT === 'object') { callback(); } else { window.dfd.done(function( name ) { callback(); }); } };
// YTPlayer Object
YTPlayer = { player: null,
// Defaults
defaults: { ratio: 16 / 9, videoId: 'LSmgKRx5pBo', mute: true, repeat: true, width: $(window).width(), playButtonClass: 'YTPlayer-play', pauseButtonClass: 'YTPlayer-pause', muteButtonClass: 'YTPlayer-mute', volumeUpClass: 'YTPlayer-volume-up', volumeDownClass: 'YTPlayer-volume-down', start: 0, pauseOnScroll: false, fitToBackground: true, playerVars: { iv_load_policy: 3, modestbranding: 1, autoplay: 1, controls: 0, showinfo: 0, wmode: 'opaque', branding: 0, autohide: 0 }, events: null },
/** * @function init * Intializes YTPlayer object */ init: function init(node, userOptions) { var self = this;
self.userOptions = userOptions;
self.$body = $('body'), self.$node = $(node), self.$window = $(window);
// Setup event defaults with the reference to this
self.defaults.events = { 'onReady': function(e) { self.onPlayerReady(e);
// setup up pause on scroll
if (self.options.pauseOnScroll) { self.pauseOnScroll(); }
// Callback for when finished
if (typeof self.options.callback == 'function') { self.options.callback.call(this); } }, 'onStateChange': function(e) { if (e.data === 1) {
self.$node.find('img').fadeOut(400); self.$node.addClass('loaded'); } else if (e.data === 0 && self.options.repeat) { // video ended and repeat option is set true
self.player.seekTo(self.options.start); } } }
self.options = $.extend(true, {}, self.defaults, self.userOptions); self.options.height = Math.ceil(self.options.width / self.options.ratio); self.ID = (new Date()).getTime(); self.holderID = 'YTPlayer-ID-' + self.ID;
if (self.options.fitToBackground) { self.createBackgroundVideo(); } else { self.createContainerVideo(); } // Listen for Resize Event
self.$window.on('resize.YTplayer' + self.ID, function() { self.resize(self); });
loadAPI(self.onYouTubeIframeAPIReady.bind(self));
self.resize(self);
return self; },
/** * @function pauseOnScroll * Adds window events to pause video on scroll. */ pauseOnScroll: function pauseOnScroll() { var self = this; self.$window.on('scroll.YTplayer' + self.ID, function() { var state = self.player.getPlayerState(); if (state === 1) { self.player.pauseVideo(); } }); self.$window.scrollStopped(function(){ var state = self.player.getPlayerState(); if (state === 2) { self.player.playVideo(); } }); }, /** * @function createContainerVideo * Adds HTML for video in a container */ createContainerVideo: function createContainerVideo() { var self = this;
/*jshint multistr: true */ var $YTPlayerString = $('<div id="ytplayer-container' + self.ID + '" >\ <div id="' + self.holderID + '" class="ytplayer-player-inline"></div> \ </div> \ <div id="ytplayer-shield" class="ytplayer-shield"></div>');
self.$node.append($YTPlayerString); self.$YTPlayerString = $YTPlayerString; $YTPlayerString = null; },
/** * @function createBackgroundVideo * Adds HTML for video background */ createBackgroundVideo: function createBackgroundVideo() { /*jshint multistr: true */ var self = this, $YTPlayerString = $('<div id="ytplayer-container' + self.ID + '" class="ytplayer-container background">\ <div id="' + self.holderID + '" class="ytplayer-player"></div>\ </div>\ <div id="ytplayer-shield" class="ytplayer-shield"></div>');
self.$node.append($YTPlayerString); self.$YTPlayerString = $YTPlayerString; $YTPlayerString = null; },
/** * @function resize * Resize event to change video size */ resize: function resize(self) { //var self = this;
var container = $(window);
if (!self.options.fitToBackground) { container = self.$node; }
var width = container.width(), pWidth, // player width, to be defined
height = container.height(), pHeight, // player height, tbd
$YTPlayerPlayer = $('#' + self.holderID);
// when screen aspect ratio differs from video, video must center and underlay one dimension
if (width / self.options.ratio < height) { pWidth = Math.ceil(height * self.options.ratio); // get new player width
$YTPlayerPlayer.width(pWidth).height(height).css({ left: (width - pWidth) / 2, top: 0 }); // player width is greater, offset left; reset top
} else { // new video width < window width (gap to right)
pHeight = Math.ceil(width / self.options.ratio); // get new player height
$YTPlayerPlayer.width(width).height(pHeight).css({ left: 0, top: (height - pHeight) / 2 }); // player height is greater, offset top; reset left
}
$YTPlayerPlayer = null; container = null; },
/** * @function onYouTubeIframeAPIReady * @ params {object} YTPlayer object for access to options * Youtube API calls this function when the player is ready. */ onYouTubeIframeAPIReady: function onYouTubeIframeAPIReady() { var self = this; self.player = new window.YT.Player(self.holderID, self.options); },
/** * @function onPlayerReady * @ params {event} window event from youtube player */ onPlayerReady: function onPlayerReady(e) { if (this.options.mute) { e.target.mute(); } e.target.playVideo(); },
/** * @function getPlayer * returns youtube player */ getPlayer: function getPlayer() { return this.player; },
/** * @function destroy * destroys all! */ destroy: function destroy() { var self = this;
self.$node .removeData('yt-init') .removeData('ytPlayer') .removeClass('loaded');
self.$YTPlayerString.remove();
$(window).off('resize.YTplayer' + self.ID); $(window).off('scroll.YTplayer' + self.ID); self.$body = null; self.$node = null; self.$YTPlayerString = null; self.player.destroy(); self.player = null; } };
// Scroll Stopped event.
$.fn.scrollStopped = function(callback) { var $this = $(this), self = this; $this.scroll(function(){ if ($this.data('scrollTimeout')) { clearTimeout($this.data('scrollTimeout')); } $this.data('scrollTimeout', setTimeout(callback,250,self)); }); };
// Create plugin
$.fn.YTPlayer = function(options) {
return this.each(function() { var el = this;
$(el).data("yt-init", true); var player = Object.create(YTPlayer); player.init(el, options); $.data(el, "ytPlayer", player); }); };
})(jQuery, window, document);
|