1/* 2* Gifplayer v0.3.4 3* Customizable jquery plugin to play and stop animated gifs. Similar to 9gag's 4* (c)2014 Rubén Torres - [email protected] 5* Released under the MIT license 6*/ 7 8(function (factory) { 9 if(typeof module === "object" && typeof module.exports === "object") { 10 module.exports = factory(require("jquery")); 11 } else { 12 factory(jQuery); 13 } 14}(function($) { 15 16 function GifPlayer(preview, options){ 17 this.previewElement = preview; 18 this.options = options; 19 this.animationLoaded = false; 20 } 21 22 GifPlayer.scopes = new Array(); 23 24 GifPlayer.prototype = { 25 26 supportedFormats: ['gif', 'jpeg', 'jpg', 'png'], 27 28 activate: function(){ 29 var self = this; 30 if(this.previewElement.width() === 0){ 31 setTimeout(function(){ 32 self.activate(); 33 }, 100); 34 }else{ 35 self.mode = self.getOption('mode'); 36 self.wrap(); 37 self.addSpinner(); 38 self.addControl(); 39 self.addEvents(); 40 } 41 }, 42 43 wrap: function(){ 44 this.previewElement.addClass('gifplayer-ready'); 45 this.wrapper = this.previewElement.wrap("<div class='gifplayer-wrapper'></div>").parent(); 46 this.wrapper.css('width', this.previewElement.width()); 47 this.wrapper.css('height', this.previewElement.height()); 48 this.previewElement.css('cursor','pointer'); 49 }, 50 51 addSpinner: function(){ 52 this.spinnerElement = $("<div class = 'spinner'></div>"); 53 this.wrapper.append(this.spinnerElement); 54 this.spinnerElement.hide(); 55 }, 56 57 getOption: function(option){ 58 var dataOption = this.previewElement.data(option.toLowerCase()); 59 if(dataOption != undefined && dataOption != ''){ 60 return dataOption; 61 }else{ 62 return this.options[option]; 63 } 64 }, 65 66 addControl: function(){ 67 var label = this.getOption('label'); 68 this.playElement = $("<ins class='play-gif'>" + "Play" + "</ins>"); 69 this.wrapper.append(this.playElement); 70 this.playElement.css('top', this.previewElement.height()/2 - this.playElement.height()/2); 71 this.playElement.css('left', this.previewElement.width()/2 - this.playElement.width()/2); 72 }, 73 74 addEvents: function(){ 75 var gp = this; 76 var playOn = this.getOption('playOn'); 77 78 switch(playOn){ 79 case 'click': 80 gp.playElement.on( 'click', function(e){ 81 gp.previewElement.trigger('click'); 82 }); 83 gp.previewElement.on( 'click', function(e){ 84 // Fire event onClick 85 gp.getOption('onClick').call(gp.previewElement, e); 86 87 gp.loadAnimation(); 88 e.preventDefault(); 89 e.stopPropagation(); 90 }); 91 92 break; 93 case 'hover': 94 gp.previewElement.on( 'click mouseover', function(e){ 95 gp.loadAnimation(); 96 e.preventDefault(); 97 e.stopPropagation(); 98 }); 99 break; 100 case 'auto': 101 console.log('auto not implemented yet'); 102 break; 103 default: 104 console.log(playOn + ' is not accepted as playOn value.'); 105 } 106 }, 107 108 processScope: function(){ 109 var scope = this.getOption('scope'); 110 if( scope ){ 111 if(GifPlayer.scopes[scope]){ 112 GifPlayer.scopes[scope].stopGif(); 113 } 114 GifPlayer.scopes[scope] = this; 115 } 116 }, 117 118 loadAnimation: function(){ 119 this.processScope(); 120 121 this.spinnerElement.show(); 122 123 if( this.mode == 'gif'){ 124 this.loadGif(); 125 }else if(this.mode == 'video'){ 126 if(!this.videoLoaded){ 127 this.loadVideo(); 128 }else{ 129 this.playVideo(); 130 } 131 132 } 133 // Fire event onPlay 134 this.getOption('onPlay').call(this.previewElement); 135 }, 136 137 stopGif: function(){ 138 this.gifElement.hide(); 139 this.previewElement.show(); 140 this.playElement.show(); 141 this.resetEvents(); 142 this.getOption('onStop').call(this.previewElement); 143 }, 144 145 getFile: function( ext ){ 146 // Obtain the resource default path 147 var gif = this.getOption(ext); 148 if(gif != undefined && gif != ''){ 149 return gif; 150 }else{ 151 replaceString = this.previewElement.attr('src'); 152 153 for (i = 0; i < this.supportedFormats.length; i++) { 154 pattrn = new RegExp( this.supportedFormats[i]+'$', 'i' ); 155 replaceString = replaceString.replace( pattrn, ext ); 156 } 157 158 return replaceString; 159 } 160 }, 161 162 loadGif: function(){ 163 var gp = this; 164 165 gp.playElement.hide(); 166 167 if(!this.animationLoaded){ 168 this.enableAbort(); 169 } 170 var gifSrc = this.getFile('gif'); 171 var gifWidth = this.previewElement.width(); 172 var gifHeight = this.previewElement.height(); 173 174 this.gifElement=$("<img class='gp-gif-element' width='"+ gifWidth + "' height=' "+ gifHeight +" '/>"); 175 176 var wait = this.getOption('wait'); 177 if(wait){ 178 //Wait until gif loads 179 this.gifElement.on({ load: function(){ 180 gp.animationLoaded = true; 181 gp.resetEvents(); 182 gp.previewElement.hide(); 183 gp.wrapper.append(gp.gifElement); 184 gp.spinnerElement.hide(); 185 gp.getOption('onLoadComplete').call(gp.previewElement); 186 }}); 187 }else{ 188 //Try to show gif instantly 189 gp.animationLoaded = true; 190 gp.resetEvents(); 191 gp.previewElement.hide(); 192 gp.wrapper.append(gp.gifElement); 193 gp.spinnerElement.hide(); 194 } 195 this.gifElement.css('cursor','pointer'); 196 this.gifElement.css('position','absolute'); 197 this.gifElement.css('top','0'); 198 this.gifElement.css('left','0'); 199 this.gifElement.attr('src', gifSrc); 200 this.gifElement.click( function(e){ 201 // Fire event onClick 202 gp.getOption('onClick').call(gp.previewElement, e); 203 204 $(this).remove(); 205 gp.stopGif(); 206 e.preventDefault(); 207 e.stopPropagation(); 208 }); 209 gp.getOption('onLoad').call(gp.previewElement); 210 211 }, 212 213 loadVideo: function(){ 214 this.videoLoaded = true; 215 216 var videoSrcMp4 = this.getFile('mp4'); 217 var videoSrcWebm = this.getFile('webm'); 218 var videoWidth = this.previewElement.width(); 219 var videoHeight = this.previewElement.height(); 220 221 this.videoElement = $('<video class="gp-video-element" width="' + 222 videoWidth + 'px" height="' + videoHeight + '" style="margin:0 auto;width:' + 223 videoWidth + 'px;height:' + videoHeight + 'px;" autoplay="autoplay" loop="loop" muted="muted" poster="' + 224 this.previewElement.attr('src') + '"><source type="video/mp4" src="' + 225 videoSrcMp4 + '"><source type="video/webm" src="' + videoSrcWebm + '"></video>'); 226 227 var gp = this; 228 229 var checkLoad = function(){ 230 if(gp.videoElement[0].readyState === 4){ 231 gp.playVideo(); 232 gp.animationLoaded = true; 233 }else{ 234 setTimeout(checkLoad, 100); 235 } 236 }; 237 238 var wait = this.getOption('wait'); 239 if(wait){ 240 checkLoad(); 241 }else{ 242 this.playVideo(); 243 } 244 245 this.videoElement.on('click', function(){ 246 if(gp.videoPaused){ 247 gp.resumeVideo(); 248 }else{ 249 gp.pauseVideo(); 250 } 251 }); 252 }, 253 254 playVideo: function(){ 255 this.spinnerElement.hide(); 256 this.previewElement.hide(); 257 this.playElement.hide(); 258 259 this.gifLoaded = true; 260 this.previewElement.hide(); 261 this.wrapper.append(this.videoElement); 262 this.videoPaused = false;
263 this.videoElement[0].play(); 264 this.getOption('onPlay').call(this.previewElement); 265 }, 266 267 pauseVideo: function(){ 268 this.videoPaused = true; 269 this.videoElement[0].pause(); 270 this.playElement.show(); 271 this.mouseoverEnabled = false; 272 this.getOption('onStop').call(this.previewElement); 273 }, 274 275 resumeVideo: function(){ 276 this.videoPaused = false; 277 this.videoElement[0].play(); 278 this.playElement.hide(); 279 this.getOption('onPlay').call(this.previewElement); 280 }, 281 282 enableAbort: function(){ 283 var gp = this; 284 this.previewElement.click( function(e){ 285 gp.abortLoading(e); 286 }); 287 this.spinnerElement.click( function(e){ 288 gp.abortLoading(e); 289 }); 290 }, 291 292 abortLoading: function(e){ 293 this.spinnerElement.hide(); 294 this.playElement.show(); 295 e.preventDefault(); 296 e.stopPropagation(); 297 this.gifElement.off('load').on( 'load', function(ev){ 298 ev.preventDefault(); 299 ev.stopPropagation(); 300 }); 301 this.resetEvents(); 302 this.getOption('onStop').call(this.previewElement); 303 }, 304 305 resetEvents: function(){ 306 this.previewElement.off('click'); 307 this.previewElement.off('mouseover'); 308 this.playElement.off('click'); 309 this.spinnerElement.off('click'); 310 this.addEvents(); 311 } 312 313 }; 314 315 $.fn.gifplayer = function(options) { 316 317 // Check if we should operate with some method 318 if (/^(play|stop)$/i.test(options)) { 319 320 return this.each( function(){ 321 // Normalize method's name 322 options = options.toLowerCase(); 323 if($(this).hasClass('gifplayer-ready')){ 324 //Setup gifplayer object 325 var gp = new GifPlayer($(this), null); 326 gp.options = {}; 327 gp.options = $.extend({}, $.fn.gifplayer.defaults, gp.options); 328 gp.wrapper = $(this).parent(); 329 gp.spinnerElement = gp.wrapper.find('.spinner'); 330 gp.playElement = gp.wrapper.find('.play-gif'); 331 gp.gifElement = gp.wrapper.find('.gp-gif-element'); 332 gp.videoElement = gp.wrapper.find('.gp-video-element'); 333 gp.mode = gp.getOption('mode'); 334 335 switch(options){ 336 case 'play': 337 gp.playElement.trigger('click'); 338 break; 339 case 'stop': 340 if(!gp.playElement.is(':visible')){ 341 if(gp.mode == 'gif'){ 342 gp.stopGif(); 343 }else if( gp.mode == 'video'){ 344 gp.videoElement.trigger('click'); 345 } 346 } 347 break; 348 } 349 } 350 }); 351 352 }else{ //Create instance 353 return this.each(function(){ 354 options = $.extend({}, $.fn.gifplayer.defaults, options); 355 var gifplayer = new GifPlayer($(this), options); 356 gifplayer.activate(); 357 }); 358 } 359 }; 360 361 $.fn.gifplayer.defaults = { 362 label: 'GIF', 363 playOn: 'click', 364 mode: 'gif', 365 gif: '', 366 mp4: '', 367 webm: '', 368 wait: false, 369 scope: false, 370 onPlay: function(){}, 371 onStop: function(){}, 372 onClick: function(){}, 373 onLoad: function(){}, 374 onLoadComplete: function(){} 375 }; 376 377 return GifPlayer; 378 379}));
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.