1(function(root, factory) { 2 if (typeof define === 'function' && define.amd) { 3 define(factory); 4 } else if (typeof exports === 'object') { 5 module.exports = factory(require, exports, module); 6 } else { 7 root.CountUp = factory(); 8 } 9}(this, function(require, exports, module) { 10 11/* 12 countUp.js 13 by @inorganik 14*/ 15 16// target = id of html element or var of previously selected html element where counting occurs 17// startVal = the value you want to begin at 18// endVal = the value you want to arrive at 19// decimals = number of decimal places, default 0 20// duration = duration of animation in seconds, default 2 21// options = optional object of options (see below) 22 23var CountUp = function(target, startVal, endVal, decimals, duration, options) { 24 25 var self = this; 26 self.version = function () { return '1.9.3'; }; 27 28 // default options 29 self.options = { 30 useEasing: true, // toggle easing 31 useGrouping: true, // 1,000,000 vs 1000000 32 separator: ',', // character to use as a separator 33 decimal: '.', // character to use as a decimal 34 easingFn: easeOutExpo, // optional custom easing function, default is Robert Penner's easeOutExpo 35 formattingFn: formatNumber, // optional custom formatting function, default is formatNumber above 36 prefix: '', // optional text before the result 37 suffix: '', // optional text after the result 38 numerals: [] // optionally pass an array of custom numerals for 0-9 39 }; 40 41 // extend default options with passed options object 42 if (options && typeof options === 'object') { 43 for (var key in self.options) { 44 if (options.hasOwnProperty(key) && options[key] !== null) { 45 self.options[key] = options[key]; 46 } 47 } 48 } 49 50 if (self.options.separator === '') { 51 self.options.useGrouping = false; 52 } 53 else { 54 // ensure the separator is a string (formatNumber assumes this) 55 self.options.separator = '' + self.options.separator; 56 } 57 58 // make sure requestAnimationFrame and cancelAnimationFrame are defined 59 // polyfill for browsers without native support 60 // by Opera engineer Erik Möller 61 var lastTime = 0; 62 var vendors = ['webkit', 'moz', 'ms', 'o']; 63 for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 64 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 65 window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; 66 } 67 if (!window.requestAnimationFrame) { 68 window.requestAnimationFrame = function(callback, element) { 69 var currTime = new Date().getTime(); 70 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 71 var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); 72 lastTime = currTime + timeToCall; 73 return id; 74 }; 75 } 76 if (!window.cancelAnimationFrame) { 77 window.cancelAnimationFrame = function(id) { 78 clearTimeout(id); 79 }; 80 } 81 82 function formatNumber(num) { 83 var neg = (num < 0), 84 x, x1, x2, x3, i, len; 85 num = Math.abs(num).toFixed(self.decimals); 86 num += ''; 87 x = num.split('.'); 88 x1 = x[0]; 89 x2 = x.length > 1 ? self.options.decimal + x[1] : ''; 90 if (self.options.useGrouping) { 91 x3 = ''; 92 for (i = 0, len = x1.length; i < len; ++i) { 93 if (i !== 0 && ((i % 3) === 0)) { 94 x3 = self.options.separator + x3; 95 } 96 x3 = x1[len - i - 1] + x3; 97 } 98 x1 = x3; 99 } 100 // optional numeral substitution 101 if (self.options.numerals.length) { 102 x1 = x1.replace(/[0-9]/g, function(w) { 103 return self.options.numerals[+w]; 104 }) 105 x2 = x2.replace(/[0-9]/g, function(w) { 106 return self.options.numerals[+w]; 107 }) 108 } 109 return (neg ? '-' : '') + self.options.prefix + x1 + x2 + self.options.suffix; 110 } 111 // Robert Penner's easeOutExpo 112 function easeOutExpo(t, b, c, d) { 113 return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b; 114 } 115 function ensureNumber(n) { 116 return (typeof n === 'number' && !isNaN(n)); 117 } 118 119 self.initialize = function() { 120 if (self.initialized) return true; 121 122 self.error = ''; 123 self.d = (typeof target === 'string') ? document.getElementById(target) : target; 124 if (!self.d) { 125 self.error = '[CountUp] target is null or undefined' 126 return false;
127 } 128 self.startVal = Number(startVal); 129 self.endVal = Number(endVal); 130 // error checks 131 if (ensureNumber(self.startVal) && ensureNumber(self.endVal)) { 132 self.decimals = Math.max(0, decimals || 0); 133 self.dec = Math.pow(10, self.decimals); 134 self.duration = Number(duration) * 1000 || 2000; 135 self.countDown = (self.startVal > self.endVal); 136 self.frameVal = self.startVal; 137 self.initialized = true; 138 return true; 139 } 140 else { 141 self.error = '[CountUp] startVal ('+startVal+') or endVal ('+endVal+') is not a number'; 142 return false; 143 } 144 }; 145 146 // Print value to target 147 self.printValue = function(value) { 148 var result = self.options.formattingFn(value); 149 150 if (self.d.tagName === 'INPUT') { 151 this.d.value = result; 152 } 153 else if (self.d.tagName === 'text' || self.d.tagName === 'tspan') { 154 this.d.textContent = result; 155 } 156 else { 157 this.d.innerHTML = result; 158 } 159 }; 160 161 self.count = function(timestamp) { 162 163 if (!self.startTime) { self.startTime = timestamp; } 164 165 self.timestamp = timestamp; 166 var progress = timestamp - self.startTime; 167 self.remaining = self.duration - progress; 168 169 // to ease or not to ease 170 if (self.options.useEasing) { 171 if (self.countDown) { 172 self.frameVal = self.startVal - self.options.easingFn(progress, 0, self.startVal - self.endVal, self.duration); 173 } else { 174 self.frameVal = self.options.easingFn(progress, self.startVal, self.endVal - self.startVal, self.duration); 175 } 176 } else { 177 if (self.countDown) { 178 self.frameVal = self.startVal - ((self.startVal - self.endVal) * (progress / self.duration)); 179 } else { 180 self.frameVal = self.startVal + (self.endVal - self.startVal) * (progress / self.duration); 181 } 182 } 183 184 // don't go past endVal since progress can exceed duration in the last frame 185 if (self.countDown) { 186 self.frameVal = (self.frameVal < self.endVal) ? self.endVal : self.frameVal; 187 } else { 188 self.frameVal = (self.frameVal > self.endVal) ? self.endVal : self.frameVal; 189 } 190 191 // decimal 192 self.frameVal = Math.round(self.frameVal*self.dec)/self.dec; 193 194 // format and print value 195 self.printValue(self.frameVal); 196 197 // whether to continue 198 if (progress < self.duration) { 199 self.rAF = requestAnimationFrame(self.count); 200 } else { 201 if (self.callback) self.callback(); 202 } 203 }; 204 // start your animation 205 self.start = function(callback) { 206 if (!self.initialize()) return; 207 self.callback = callback; 208 self.rAF = requestAnimationFrame(self.count); 209 }; 210 // toggles pause/resume animation 211 self.pauseResume = function() { 212 if (!self.paused) { 213 self.paused = true; 214 cancelAnimationFrame(self.rAF); 215 } else { 216 self.paused = false; 217 delete self.startTime; 218 self.duration = self.remaining; 219 self.startVal = self.frameVal; 220 requestAnimationFrame(self.count); 221 } 222 }; 223 // reset to startVal so animation can be run again 224 self.reset = function() { 225 self.paused = false; 226 delete self.startTime; 227 self.initialized = false; 228 if (self.initialize()) { 229 cancelAnimationFrame(self.rAF); 230 self.printValue(self.startVal); 231 } 232 }; 233 // pass a new endVal and start animation 234 self.update = function (newEndVal) { 235 if (!self.initialize()) return; 236 newEndVal = Number(newEndVal); 237 if (!ensureNumber(newEndVal)) { 238 self.error = '[CountUp] update() - new endVal is not a number: '+newEndVal; 239 return; 240 } 241 self.error = ''; 242 if (newEndVal === self.frameVal) return; 243 cancelAnimationFrame(self.rAF); 244 self.paused = false; 245 delete self.startTime; 246 self.startVal = self.frameVal; 247 self.endVal = newEndVal; 248 self.countDown = (self.startVal > self.endVal); 249 self.rAF = requestAnimationFrame(self.count); 250 }; 251 252 // format startVal on initialization 253 if (self.initialize()) self.printValue(self.startVal); 254}; 255 256return CountUp; 257 258}));
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.