1/* 2 countUp.js 3 by @inorganik 4*/ 5// target = id of html element or var of previously selected html element where counting occurs 6// startVal = the value you want to begin at 7// endVal = the value you want to arrive at 8// decimals = number of decimal places, default 0 9// duration = duration of animation in seconds, default 2 10// options = optional object of options (see below) 11var CountUp = function(target, startVal, endVal, decimals, duration, options) { 12 // make sure requestAnimationFrame and cancelAnimationFrame are defined 13 // polyfill for browsers without native support 14 // by Opera engineer Erik Möller 15 var lastTime = 0; 16 var vendors = ['webkit', 'moz', 'ms', 'o']; 17 for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 18 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 19 window.cancelAnimationFrame = 20 window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; 21 } 22 if (!window.requestAnimationFrame) { 23 window.requestAnimationFrame = function(callback, element) { 24 var currTime = new Date().getTime(); 25 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 26 var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 27 timeToCall); 28 lastTime = currTime + timeToCall; 29 return id; 30 }; 31 } 32 if (!window.cancelAnimationFrame) { 33 window.cancelAnimationFrame = function(id) { 34 clearTimeout(id); 35 }; 36 } 37 // default options 38 this.options = { 39 useEasing : true, // toggle easing 40 useGrouping : true, // 1,000,000 vs 1191414 41 separator : ',', // character to use as a separator 42 decimal : '.' // character to use as a decimal 43 }; 44 // extend default options with passed options object 45 for (var key in options) { 46 if (options.hasOwnProperty(key)) { 47 this.options[key] = options[key]; 48 } 49 } 50 if (this.options.separator === '') this.options.useGrouping = false; 51 if (!this.options.prefix) this.options.prefix = ''; 52 if (!this.options.suffix) this.options.suffix = ''; 53 this.d = (typeof target === 'string') ? document.getElementById(target) : target; 54 this.startVal = Number(startVal); 55 this.endVal = Number(endVal); 56 this.countDown = (this.startVal > this.endVal); 57 this.frameVal = this.startVal; 58 this.decimals = Math.max(0, decimals || 0); 59 this.dec = Math.pow(10, this.decimals); 60 this.duration = Number(duration) * 1000 || 2000; 61 var self = this; 62 this.version = function () { return '1.6.0'; }; 63 // Print value to target 64 this.printValue = function(value) { 65 var result = (!isNaN(value)) ? self.formatNumber(value) : '--'; 66 if (self.d.tagName == 'INPUT') { 67 this.d.value = result; 68 } 69 else if (self.d.tagName == 'text' || self.d.tagName == 'tspan') { 70 this.d.textContent = result; 71 } 72 else { 73 this.d.innerHTML = result; 74 } 75 }; 76 // Robert Penner's easeOutExpo 77 this.easeOutExpo = function(t, b, c, d) { 78 return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b; 79 }; 80 this.count = function(timestamp) { 81 if (!self.startTime) self.startTime = timestamp; 82 self.timestamp = timestamp; 83 var progress = timestamp - self.startTime; 84 self.remaining = self.duration - progress; 85 // to ease or not to ease 86 if (self.options.useEasing) { 87 if (self.countDown) { 88 self.frameVal = self.startVal - self.easeOutExpo(progress, 0, self.startVal - self.endVal, self.duration); 89 } else { 90 self.frameVal = self.easeOutExpo(progress, self.startVal, self.endVal - self.startVal, self.duration); 91 } 92 } else { 93 if (self.countDown) { 94 self.frameVal = self.startVal - ((self.startVal - self.endVal) * (progress / self.duration)); 95 } else { 96 self.frameVal = self.startVal + (self.endVal - self.startVal) * (progress / self.duration); 97 } 98 } 99 // don't go past endVal since progress can exceed duration in the last frame 100 if (self.countDown) { 101 self.frameVal = (self.frameVal < self.endVal) ? self.endVal : self.frameVal; 102 } else { 103 self.frameVal = (self.frameVal > self.endVal) ? self.endVal : self.frameVal; 104 } 105 // decimal 106 self.frameVal = Math.round(self.frameVal*self.dec)/self.dec; 107 // format and print value 108 self.printValue(self.frameVal); 109 // whether to continue 110 if (progress < self.duration) { 111 self.rAF = requestAnimationFrame(self.count); 112 } else { 113 if (self.callback) self.callback(); 114 } 115 }; 116 // start your animation 117 this.start = function(callback) { 118 self.callback = callback; 119 self.rAF = requestAnimationFrame(self.count); 120 return false; 121 }; 122 // toggles pause/resume animation 123 this.pauseResume = function() { 124 if (!self.paused) { 125 self.paused = true; 126 cancelAnimationFrame(self.rAF); 127 } else { 128 self.paused = false; 129 delete self.startTime; 130 self.duration = self.remaining; 131 self.startVal = self.frameVal; 132 requestAnimationFrame(self.count); 133 } 134 }; 135 // reset to startVal so animation can be run again 136 this.reset = function() { 137 self.paused = false; 138 delete self.startTime; 139 self.startVal = startVal; 140 cancelAnimationFrame(self.rAF); 141 self.printValue(self.startVal); 142 }; 143 // pass a new endVal and start animation 144 this.update = function (newEndVal) { 145 cancelAnimationFrame(self.rAF); 146 self.paused = false; 147 delete self.startTime; 148 self.startVal = self.frameVal; 149 self.endVal = Number(newEndVal); 150 self.countDown = (self.startVal > self.endVal); 151 self.rAF = requestAnimationFrame(self.count); 152 }; 153 this.formatNumber = function(nStr) { 154 nStr = nStr.toFixed(self.decimals); 155 nStr += ''; 156 var x, x1, x2, rgx; 157 x = nStr.split('.'); 158 x1 = x[0]; 159 x2 = x.length > 1 ? self.options.decimal + x[1] : ''; 160 rgx = /(\d+)(\d{3})/; 161 if (self.options.useGrouping) { 162 while (rgx.test(x1)) { 163 x1 = x1.replace(rgx, '$1' + self.options.separator + '$2'); 164 } 165 } 166 return self.options.prefix + x1 + x2 + self.options.suffix; 167 }; 168 // format startVal on initialization 169 self.printValue(self.startVal); 170};
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.