vendor: 4,193 bytes, lines 1-100
1 2(function($) { 3 $.fn.marquee = function(options) { 4 return this.each(function() { 5 // Extend the options if any provided 6 var o = $.extend({}, $.fn.marquee.defaults, options), 7 $this = $(this), 8 $marqueeWrapper, containerWidth, animationCss, verticalDir, elWidth, 9 loopCount = 3, 10 playState = 'animation-play-state', 11 css3AnimationIsSupported = false, 12 13 //Private methods 14 _prefixedEvent = function(element, type, callback) { 15 var pfx = ["webkit", "moz", "MS", "o", ""]; 16 for (var p = 0; p < pfx.length; p++) { 17 if (!pfx[p]) type = type.toLowerCase(); 18 element.addEventListener(pfx[p] + type, callback, false); 19 } 20 }, 21 22 _objToString = function(obj) { 23 var tabjson = []; 24 for (var p in obj) { 25 if (obj.hasOwnProperty(p)) { 26 tabjson.push(p + ':' + obj[p]); 27 } 28 } 29 tabjson.push(); 30 return '{' + tabjson.join(',') + '}'; 31 }, 32 33 _startAnimationWithDelay = function() { 34 $this.timer = setTimeout(animate, o.delayBeforeStart); 35 }, 36 37 //Public methods 38 methods = { 39 pause: function() { 40 if (css3AnimationIsSupported && o.allowCss3Support) { 41 $marqueeWrapper.css(playState, 'paused'); 42 } else { 43 //pause using pause plugin 44 if ($.fn.pause) { 45 $marqueeWrapper.pause(); 46 } 47 } 48 //save the status 49 $this.data('runningStatus', 'paused'); 50 //fire event 51 $this.trigger('paused'); 52 }, 53 54 resume: function() { 55 //resume using css3 56 if (css3AnimationIsSupported && o.allowCss3Support) { 57 $marqueeWrapper.css(playState, 'running'); 58 } else { 59 //resume using pause plugin 60 if ($.fn.resume) { 61 $marqueeWrapper.resume(); 62 } 63 } 64 //save the status 65 $this.data('runningStatus', 'resumed'); 66 //fire event 67 $this.trigger('resumed'); 68 }, 69 70 toggle: function() { 71 methods[$this.data('runningStatus') == 'resumed' ? 'pause' : 'resume'](); 72 }, 73 74 destroy: function() { 75 //Clear timer 76 clearTimeout($this.timer); 77 //Unbind all events 78 $this.find("*").andSelf().unbind(); 79 //Just unwrap the elements that has been added using this plugin 80 $this.htm($this.find('.js-marquee:first').htm()); 81 } 82 }; 83 84 //Check for methods 85 if (typeof options === 'string') { 86 if ($.isFunction(methods[options])) { 87 //Following two IF statements to support public methods 88 if (!$marqueeWrapper) { 89 $marqueeWrapper = $this.find('.js-marquee-wrapper'); 90 } 91 if ($this.data('css3AnimationIsSupported') === true) { 92 css3AnimationIsSupported = true; 93 } 94 methods[options](); 95 } 96 return; 97 } 98 99 /* Check if element has data attributes. They have top priority 100 For details https://twitter.com/aamirafridi/status/403848
100044069679104 - Can't find a better solution :/ 101 jQuery 1.3.2 doesn't support $.data().KEY hence writting the following */ 102 var dataAttributes = {}, 103 attr; 104 $.each(o, function(key, value) { 105 //Check if element has this data attribute 106 attr = $this.attr('data-' + key); 107 if (typeof attr !== 'undefined') { 108 //Now check if value is boolean or not 109 switch (attr) { 110 case 'true': 111 attr = true; 112 break; 113 case 'false': 114 attr = false; 115 break; 116 } 117 o[key] = attr; 118 } 119 }); 120 121 //since speed option is changed to duration, to support speed for those who are already using it 122 o.duration = o.speed || o.duration; 123 124 //Shortcut to see if direction is upward or downward 125 verticalDir = o.direction == 'up' || o.direction == 'down'; 126 127 //no gap if not duplicated 128 o.gap = o.duplicated ? parseInt(o.gap) : 0; 129 130 //wrap inner content into a div 131 $this.wrapInner('<div class="js-marquee"></div>'); 132 133 //Make copy of the element 134 var $el = $this.find('.js-marquee').css({ 135 'margin-right': o.gap, 136 'float': 'left' 137 }); 138 139 if (o.duplicated) { 140 $el.clone(true).appendTo($this); 141 } 142 143 //wrap both inner elements into one div 144 $this.wrapInner('<div style="width:100000px" class="js-marquee-wrapper"></div>'); 145 146 //Save the reference of the wrapper 147 $marqueeWrapper = $this.find('.js-marquee-wrapper'); 148 149 //If direction is up or down, get the height of main element 150 if (verticalDir) { 151 var containerHeight = $this.height(); 152 $marqueeWrapper.removeAttr('style'); 153 $this.height(containerHeight); 154 155 //Change the CSS for js-marquee element 156 $this.find('.js-marquee').css({ 157 'float': 'none', 158 'margin-bottom': o.gap, 159 'margin-right': 0 160 }); 161 162 //Remove bottom margin from 2nd element if duplicated 163 if (o.duplicated) $this.find('.js-marquee:last').css({ 164 'margin-bottom': 0 165 }); 166 167 var elHeight = $this.find('.js-marquee:first').height() + o.gap; 168 169 // adjust the animation speed according to the text length 170 // formula is to: (Height of the text node / Height of the main container) * speed; 171 o.duration = ((parseInt(elHeight, 10) + parseInt(containerHeight, 10)) / parseInt(containerHeight, 10)) * o.duration; 172 173 } else { 174 //Save the width of the each element so we can use it in animation 175 elWidth = $this.find('.js-marquee:first').width() + o.gap; 176 177 //container width 178 containerWidth = $this.width(); 179 180 // adjust the animation speed according to the text length 181 // formula is to: (Width of the text node / Width of the main container) * speed; 182 o.duration = ((parseInt(elWidth, 10) + parseInt(containerWidth, 10)) / parseInt(containerWidth, 10)) * o.duration; 183 } 184 185 //if duplicated than reduce the speed 186 if (o.duplicated) { 187 o.duration = o.duration / 4; 188 } 189 190 if (o.allowCss3Support) { 191 var 192 elm = document.body || document.createElement('div'), 193 animationName = 'marqueeAnimation-' + Math.floor(Math.random() * 10000000), 194 domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), 195 animationString = 'animation', 196 animationCss3Str = '', 197 keyframeString = ''; 198 199 //Check css3 support 200 if (elm.style.animation) { 201 keyframeString = '@keyframes ' + animationName + ' '; 202 css3AnimationIsSupported = true; 203 } 204 205 if (css3AnimationIsSupported === false) { 206 for (var i = 0; i < domPrefixes.length; i++) { 207 if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { 208 var prefix = '-' + domPrefixes[i].toLowerCase() + '-'; 209 animationString = prefix + animationString; 210 playState = prefix + playState; 211 keyframeString = '@' + prefix + 'keyframes ' + animationName + ' '; 212 css3AnimationIsSupported = true; 213 break; 214 } 215 } 216 } 217 218 if (css3AnimationIsSupported) { 219 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's infinite ' + o.css3easing; 220 $this.data('css3AnimationIsSupported', true); 221 } 222 } 223 224 var _rePositionVertically = function() { 225 $marqueeWrapper.css('margin-top', o.direction == 'up' ? containerHeight + 'px' : '-' + elHeight + 'px'); 226 }, 227 _rePositionHorizontally = function() { 228 $marqueeWrapper.css('margin-left', o.direction == 'left' ? containerWidth + 'px' : '-' + elWidth + 'px'); 229 }; 230 231 //if duplicated option is set to true than position the wrapper 232 if (o.duplicated) { 233 if (verticalDir) { 234 $marqueeWrapper.css('margin-top', o.direction == 'up' ? containerHeight + 'px' : '-' + ((elHeight * 2) - o.gap) + 'px'); 235 } else { 236 $marqueeWrapper.css('margin-left', o.direction == 'left' ? containerWidth + 'px' : '-' + ((elWidth * 2) - o.gap) + 'px'); 237 } 238 loopCount = 1; 239 } else { 240 if (verticalDir) { 241 _rePositionVertically(); 242 } else { 243 _rePositionHorizontally(); 244 } 245 } 246 247 //Animate recursive method 248 var animate = function() { 249 if (o.duplicated) { 250 //When duplicated, the first loop will be scroll longer so double the duration 251 if (loopCount === 1) { 252 o._originalDuration = o.duration; 253 if (verticalDir) { 254 o.duration = o.direction == 'up' ? o.duration + (containerHeight / ((elHeight) / o.duration)) : o.duration * 2; 255 } else { 256 o.duration = o.direction == 'left' ? o.duration + (containerWidth / ((elWidth) / o.duration)) : o.duration * 2; 257 } 258 //Adjust the css3 animation as well 259 if (animationCss3Str) { 260 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's ' + o.css3easing; 261 } 262 loopCount++; 263 } 264 //On 2nd loop things back to normal, normal duration for the rest of animations 265 else if (loopCount === 2) { 266 o.duration = o._originalDuration; 267 //Adjust the css3 animation as well 268 if (animationCss3Str) { 269 animationName = animationName + '0'; 270 keyframeString = $.trim(keyframeString) + '0 '; 271 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's 0s infinite ' + o.css3easing; 272 } 273 loopCount++; 274 } 275 } 276 277 if (verticalDir) { 278 if (o.duplicated) { 279 280 //Adjust the starting point of animation only when first loops finishes 281 if (loopCount > 2) { 282 $marqueeWrapper.css('margin-top', o.direction == 'up' ? 0 : '-' + elHeight + 'px'); 283 } 284 285 animationCss = { 286 'margin-top': o.direction == 'up' ? '-' + elHeight + 'px' : 0 287 }; 288 } else { 289 _rePositionVertically(); 290 animationCss = { 291 'margin-top': o.direction == 'up' ? '-' + ($marqueeWrapper.height()) + 'px' : containerHeight + 'px' 292 }; 293 } 294 } else { 295 if (o.duplicated) { 296 297 //Adjust the starting point of animation only when first loops finishes 298 if (loopCount > 2) { 299 $marqueeWrapper.css('margin-left', o.direction == 'left' ? 0 : '-' + elWidth + 'px'); 300 } 301 302 animationCss = { 303 'margin-left': o.direction == 'left' ? '-' + elWidth + 'px' : 0 304 }; 305 306 } else { 307 _rePositionHorizontally(); 308 animationCss = { 309 'margin-left': o.direction == 'left' ? '-' + elWidth + 'px' : containerWidth + 'px' 310 }; 311 } 312 } 313 314 //fire event 315 $this.trigger('beforeStarting'); 316 317 //If css3 support is available than do it with css3, otherwise use jQuery as fallback 318 if (css3AnimationIsSupported) { 319 //Add css3 animation to the element 320 $marqueeWrapper.css(animationString, animationCss3Str); 321 var keyframeCss = keyframeString + ' { 100% ' + _objToString(animationCss) + '}', 322 $styles = $('style'); 323 324 //Now add the keyframe animation to the head 325 if ($styles.length !== 0) { 326 //Bug fixed for jQuery 1.3.x - Instead of using .last(), use following 327 $styles.filter(":last").append(keyframeCss); 328 } else { 329 $('head').append('<style>' + keyframeCss + '</style>'); 330 } 331 332 //Animation iteration event 333 _prefixedEvent($marqueeWrapper[0], "AnimationIteration", function() { 334 $this.trigger('finished'); 335 }); 336 //Animation stopped 337 _prefixedEvent($marqueeWrapper[0], "AnimationEnd", function() { 338 animate(); 339 $this.trigger('finished'); 340 }); 341 342 } else { 343 //Start animating 344 $marqueeWrapper.animate(animationCss, o.duration, o.easing, function() { 345 //fire event 346 $this.trigger('finished'); 347 //animate again 348 if (o.pauseOnCycle) { 349 _startAnimationWithDelay(); 350 } else { 351 animate(); 352 } 353 }); 354 } 355 //save the status 356 $this.data('runningStatus', 'resumed'); 357 }; 358 359 //bind pause and resume events 360 $this.bind('pause', methods.pause); 361 $this.bind('resume', methods.resume); 362 363 if (o.pauseOnHover) { 364 $this.bind('mouseenter mouseleave', methods.toggle); 365 } 366 367 //If css3 animation is supported than call animate method at once 368 if (css3AnimationIsSupported && o.allowCss3Support) { 369 animate(); 370 } else { 371 //Starts the recursive method 372 _startAnimationWithDelay(); 373 } 374 375 }); 376 }; //End of Plugin 377 // Public: plugin defaults options 378 $.fn.marquee.defaults = { 379 //If you wish to always animate using jQuery 380 allowCss3Support: true, 381 //works when allowCss3Support is set to true - for full list see http://www.w3.org/TR/2013/WD-css3-transitions-20131119/#transition-timing-function 382 css3easing: 'linear', 383 //requires jQuery easing plugin. Default is 'linear' 384 easing: 'linear', 385 //pause time before the next animation turn in milliseconds 386 delayBeforeStart: 1000, 387 //'left', 'right', 'up' or 'down' 388 direction: 'left', 389 //true or false - should the marquee be duplicated to show an effect of continues flow 390 duplicated: false, 391 //speed in milliseconds of the marquee in milliseconds 392 duration: 5000, 393 //gap in pixels between the tickers 394 gap: 20, 395 //on cycle pause the marquee 396 pauseOnCycle: false, 397 //on hover pause the marquee - using jQuery plugin https://github.com/tobia/Pause 398 pauseOnHover: false 399 }; 400})(jQuery); 401 402$('.marquee').marquee({ 403 //speed in milliseconds of the marquee 404 duration: 32000, 405 //gap in pixels between the tickers 406 gap: 10, 407 //time in milliseconds before the marquee will start animating 408 delayBeforeStart: 0, 409 //'left' or 'right' 410 direction: 'left', 411 //true or false - should the marquee be duplicated to show an effect of continues flow 412 duplicated: true 413});
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.