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