1/* 2 * YoutubeBackground - A wrapper for the Youtube API - Great for fullscreen background videos or just regular videos. 3 * 4 * Licensed under the MIT license: 5 * http://www.opensource.org/licenses/mit-license.php 6 * 7 * 8 * Version: 1.0.1 9 * 10 */ 11 12// Chain of Responsibility pattern. Creates base class that can be overridden. 13if (typeof Object.create !== "function") { 14 Object.create = function(obj) { 15 function F() {} 16 F.prototype = obj; 17 return new F(); 18 }; 19} 20 21(function($, window, document) { 22 var 23 loadAPI = function loadAPI(callback) { 24 25 // Load Youtube API 26 var tag = document.createElement('script'), 27 head = document.getElementsByTagName('head')[0]; 28 29 tag.src = location.protocol + '//www.youtube.com/iframe_api'; 30 31 head.appendChild(tag); 32 33 // Clean up Tags. 34 head = null; 35 tag = null; 36 37 iframeIsReady(callback); 38 }, 39 iframeIsReady = function iframeIsReady(callback) { 40 // Listen for Gobal YT player callback 41 42 if (typeof YT === 'undefined' && typeof window.loadingPlayer === 'undefined') { 43 // Prevents Ready Event from being called twice 44 window.loadingPlayer = true; 45 46 // Creates deferred so, other players know when to wait. 47 window.dfd = $.Deferred(); 48 window.onYouTubeIframeAPIReady = function() { 49 window.onYouTubeIframeAPIReady = null; 50 window.dfd.resolve( "John" ); 51 callback(); 52 }; 53 } else { 54 window.dfd.done(function( name ) { 55 callback(); 56 }); 57 } 58 }; 59 60 // YTPlayer Object 61 YTPlayer = { 62 player: null, 63 64 // Defaults 65 defaults: { 66 ratio: 16 / 9, 67 videoId: 'LSmgKRx5pBo', 68 mute: true, 69 repeat: true, 70 width: $(window).width(), 71 playButtonClass: 'YTPlayer-play', 72 pauseButtonClass: 'YTPlayer-pause', 73 muteButtonClass: 'YTPlayer-mute', 74 volumeUpClass: 'YTPlayer-volume-up', 75 volumeDownClass: 'YTPlayer-volume-down', 76 start: 0, 77 pauseOnScroll: false, 78 fitToBackground: true, 79 playerVars: { 80 modestbranding: 1, 81 autoplay: 1, 82 controls: 0, 83 showinfo: 0, 84 wmode: 'transparent', 85 branding: 0, 86 rel: 0, 87 autohide: 0, 88 origin: window.location.origin 89 }, 90 events: null 91 }, 92 93 /** 94 * @function init 95 * Intializes YTPlayer object 96 */ 97 init: function init(node, userOptions) { 98 var self = this; 99 100 self.userOptions = userOptions; 101 102 self.$body = $('body'), 103 self.$node = $(node), 104 self.$window = $(window); 105 106 // Setup event defaults with the reference to this 107 self.defaults.events = { 108 onReady: function(e) { 109 self.onPlayerReady(e); 110 111 // setup up pause on scroll 112 if (self.options.pauseOnScroll) { 113 self.pauseOnScroll(); 114 } 115 116 // Callback for when finished 117 if (typeof self.options.callback == 'function') { 118 self.options.callback.call(this); 119 } 120 }, 121 onStateChange: function(e) { 122 if (e.data === 1) { 123 self.$node.addClass('loaded'); 124 } else if (e.data === 0 && self.options.repeat) { // video ended and repeat option is set true 125 self.player.seekTo(self.options.start); 126 } 127 } 128 } 129 130 self.options = $.extend(true, {}, self.defaults, self.userOptions); 131 132 self.ID = (new Date()).getTime(); 133 self.holderID = 'YTPlayer-ID-' + self.ID; 134 135 if (self.options.fitToBackground) { 136 self.createBackgroundVideo(); 137 } else { 138 self.createContainerVideo(); 139 } 140 // Listen for Resize Event 141 self.$window.on('resize.YTplayer' + self.ID, function() { 142 self.resize(self); 143 }); 144 145 loadAPI(self.onYouTubeIframeAPIReady.bind(self)); 146 147 self.resize(self); 148 149 return self; 150 }, 151 152 153 /** 154 * @function pauseOnScroll 155 * Adds window events to pause video on scroll. 156 */ 157 pauseOnScroll: function pauseOnScroll() { 158 var self = this; 159 self.$window.on('scroll.YTplayer' + self.ID, function() { 160 var state = self.player.getPlayerState(); 161 if (state === 1) { 162 self.player.pauseVideo(); 163 } 164 }); 165 self.$window.scrollStopped(function(){ 166 var state = self.player.getPlayerState(); 167 if (state === 2) { 168 self.player.playVideo(); 169 } 170 }); 171 }, 172 173 /** 174 * @function createContainerVideo 175 * Adds HTML for video in a container 176 */ 177 createContainerVideo: function createContainerVideo() { 178 var self = this; 179 180 /*jshint multistr: true */ 181 var $YTPlayerString = $('<div id="ytplayer-container' + self.ID + '" >\ 182 <div id="' + self.holderID + '" class="ytplayer-player"></div> \ 183 </div> \ 184 <div id="ytplayer-shield"></div>'); 185 186 self.$node.append($YTPlayerString); 187 self.$YTPlayerString = $YTPlayerString; 188 $YTPlayerString = null; 189 }, 190 191 /**
192 * @function createBackgroundVideo 193 * Adds HTML for video background 194 */ 195 createBackgroundVideo: function createBackgroundVideo() { 196 /*jshint multistr: true */ 197 var self = this, 198 $YTPlayerString = $('<div id="ytplayer-container' + self.ID + '" class="ytplayer-container background">\ 199 <div id="' + self.holderID + '" class="ytplayer-player"></div>\ 200 </div>\ 201 <div id="ytplayer-shield"></div>'); 202 203 self.$node.append($YTPlayerString); 204 self.$YTPlayerString = $YTPlayerString; 205 $YTPlayerString = null; 206 }, 207 208 /** 209 * @function resize 210 * Resize event to change video size 211 */ 212 resize: function resize(self) { 213 //var self = this; 214 var container = $(window); 215 216 if (!self.options.fitToBackground) { 217 container = self.$node; 218 } 219 220 var width = container.width(), 221 pWidth, // player width, to be defined 222 height = container.height(), 223 pHeight, // player height, tbd 224 $YTPlayerPlayer = $('#' + self.holderID); 225 226 // when screen aspect ratio differs from video, video must center and underlay one dimension 227 if (width / self.options.ratio < height) { 228 pWidth = Math.ceil(height * self.options.ratio); // get new player width 229 $YTPlayerPlayer.width(pWidth).height(height).css({ 230 left: (width - pWidth) / 2, 231 top: 0 232 }); // player width is greater, offset left; reset top 233 } else { // new video width < window width (gap to right) 234 pHeight = Math.ceil(width / self.options.ratio); // get new player height 235 $YTPlayerPlayer.width(width).height(pHeight).css({ 236 left: 0, 237 top: 0 238 }); // player height is greater, offset top; reset left 239 } 240 241 $YTPlayerPlayer = null; 242 container = null; 243 }, 244 245 /** 246 * @function onYouTubeIframeAPIReady 247 * @ params {object} YTPlayer object for access to options 248 * Youtube API calls this function when the player is ready. 249 */ 250 onYouTubeIframeAPIReady: function onYouTubeIframeAPIReady() { 251 var self = this; 252 253 self.player = new window.YT.Player(self.holderID, { 254 width: self.options.width, 255 height: Math.ceil(self.options.width / self.options.ratio), 256 videoId: self.options.videoId, 257 playerVars: self.options.playerVars, 258 events: self.options.events 259 }); 260 }, 261 262 /** 263 * @function onPlayerReady 264 * @ params {event} window event from youtube player 265 */ 266 onPlayerReady: function onPlayerReady(e) { 267 if (this.options.mute) { 268 e.target.mute(); 269 } 270 e.target.playVideo(); 271 }, 272 273 /** 274 * @function getPlayer 275 * returns youtube player 276 */ 277 getPlayer: function getPlayer() { 278 return this.player; 279 }, 280 281 /** 282 * @function destroy 283 * destroys all! 284 */ 285 destroy: function destroy() { 286 var self = this; 287 288 self.$node 289 .removeData('yt-init') 290 .removeData('ytPlayer') 291 .removeClass('loaded'); 292 293 self.$YTPlayerString.remove(); 294 295 $(window).off('resize.YTplayer' + self.ID); 296 $(window).off('scroll.YTplayer' + self.ID); 297 self.$body = null; 298 self.$node = null; 299 self.$YTPlayerString = null; 300 self.player.destroy(); 301 self.player = null; 302 } 303 }; 304 305 // Scroll Stopped event. 306 $.fn.scrollStopped = function(callback) { 307 var $this = $(this), self = this; 308 $this.scroll(function(){ 309 if ($this.data('scrollTimeout')) { 310 clearTimeout($this.data('scrollTimeout')); 311 } 312 $this.data('scrollTimeout', setTimeout(callback,250,self)); 313 }); 314 }; 315 316 // Create plugin 317 $.fn.YTPlayer = function(options) { 318 319 return this.each(function() { 320 var el = this; 321 322 $(el).data("yt-init", true); 323 var player = Object.create(YTPlayer); 324 player.init(el, options); 325 $.data(el, "ytPlayer", player); 326 }); 327 }; 328 329})(jQuery, window, document);
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.