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