(function (root, factory) { if (typeof define === 'function' && define.amd) { define(factory); } else if (typeof exports === 'object') { module.exports = factory(require, exports, module); } else { root.countup = factory(); } }(this, function (require, exports, module) { var countup = function (target, startval, endval, decimals, duration, options) { var self = this; self.version = function () { return '1.9.3'; }; self.options = { useeasing: true, usegrouping: true, separator: ',', decimal: '.', easingfn: easeoutexpo, formattingfn: formatnumber, prefix: '', suffix: '', numerals: [50] }; if (options && typeof options === 'object') { for (var key in self.options) { if (options.hasownproperty(key) && options[key] !== null) { self.options[key] = options[key]; } } } if (self.options.separator === '') { self.options.usegrouping = false; } else { self.options.separator = '' + self.options.separator; } var lasttime = 0; var vendors = ['webkit', 'moz', 'ms', 'o']; for (var x = 0; x < vendors.length && !window.requestanimationframe; ++x) { window.requestanimationframe = window[vendors[x] + 'requestanimationframe']; window.cancelanimationframe = window[vendors[x] + 'cancelanimationframe'] || window[vendors[x] + 'cancelrequestanimationframe']; } if (!window.requestanimationframe) { window.requestanimationframe = function (callback, element) { var currtime = new date().gettime(); var timetocall = math.max(0, 16 - (currtime - lasttime)); var id = window.settimeout(function () { callback(currtime + timetocall); }, timetocall); lasttime = currtime + timetocall; return id; }; } if (!window.cancelanimationframe) { window.cancelanimationframe = function (id) { cleartimeout(id); }; } function formatnumber(num) { var neg = (num < 0), x, x1, x2, x3, i, len; num = math.abs(num).tofixed(self.decimals); num += ''; x = num.split('.'); x1 = x[0]; x2 = x.length > 1 ? self.options.decimal + x[1] : ''; if (self.options.usegrouping) { x3 = ''; for (i = 0, len = x1.length; i < len; ++i) { if (i !== 0 && ((i % 3) === 0)) { x3 = self.options.separator + x3; } x3 = x1[len - i - 1] + x3; } x1 = x3; } if (self.options.numerals.length) { x1 = x1.replace(/[0-9]/g, function (w) { return self.options.numerals[+w]; }) x2 = x2.replace(/[0-9]/g, function (w) { return self.options.numerals[+w]; }) } return (neg ? '-' : '') + self.options.prefix + x1 + x2 + self.options.suffix; } function easeoutexpo(t, b, c, d) { return c * (-math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b; } function ensurenumber(n) { return (typeof n === 'number' && !isnan(n)); } self.initialize = function () { if (self.initialized) return true; self.error = ''; self.d = (typeof target === 'string') ? document.getelementbyid(target) : target; if (!self.d) { self.error = '[countup] target is null or undefined' return false; } self.startval = number(startval); self.endval = number(endval); if (ensurenumber(self.startval) && ensurenumber(self.endval)) { self.decimals = math.max(0, decimals || 0); self.dec = math.pow(10, self.decimals); self.duration = number(duration) * 1000 || 2000; self.countdown = (self.startval > self.endval); self.frameval = self.startval; self.initialized = true; return true; } else { self.error = '[countup] startval (' + startval + ') or endval (' + endval + ') is not a number'; return false; } }; self.printvalue = function (value) { var result = self.options.formattingfn(value); if (self.d.tagname === 'input') { this.d.value = result; } else if (self.d.tagname === 'text' || self.d.tagname === 'tspan') { this.d.textcontent = result; } else { this.d.innerhtml = result; } }; self.count = function (timestamp) { if (!self.starttime) { self.starttime = timestamp; } self.timestamp = timestamp; var progress = timestamp - self.starttime; self.remaining = self.duration - progress; if (self.options.useeasing) { if (self.countdown) { self.frameval = self.startval - self.options.easingfn(progress, 0, self.startval - self.endval, self.duration); } else { self.frameval = self.options.easingfn(progress, self.startval, self.endval - self.startval, self.duration); } } else { if (self.countdown) { self.frameval = self.startval - ((self.startval - self.endval) * (progress / self.duration)); } else { self.frameval = self.startval + (self.endval - self.startval) * (progress / self.duration); } } if (self.countdown) { self.frameval = (self.frameval < self.endval) ? self.endval : self.frameval; } else { self.frameval = (self.frameval > self.endval) ? self.endval : self.frameval; } self.frameval = math.round(self.frameval * self.dec) / self.dec; self.printvalue(self.frameval); if (progress < self.duration) { self.raf = requestanimationframe(self.count); } else { if (self.callback) self.callback(); } }; self.start = function (callback) { if (!self.initialize()) return; self.callback = callback; self.raf = requestanimationframe(self.count); }; self.pauseresume = function () { if (!self.paused) { self.paused = true; cancelanimationframe(self.raf); } else { self.paused = false; delete self.starttime; self.duration = self.remaining; self.startval = self.frameval; requestanimationframe(self.count); } }; self.reset = function () { self.paused = false; delete self.starttime; self.initialized = false; if (self.initialize()) { cancelanimationframe(self.raf); self.printvalue(self.startval); } }; self.update = function (newendval) { if (!self.initialize()) return; newendval = number(newendval); if (!ensurenumber(newendval)) { self.error = '[countup] update() - new endval is not a number: ' + newendval; return; } self.error = ''; if (newendval === self.frameval) return; cancelanimationframe(self.raf); self.paused = false; delete self.starttime; self.startval = self.frameval; self.endval = newendval; self.countdown = (self.startval > self.endval); self.raf = requestanimationframe(self.count); }; if (self.initialize()) self.printvalue(self.startval); }; return countup; }));