/** * target: 目标元素的id *必填 * startval:开始的值(从哪个值开始) *必填 * endval:结束的值(滚动到哪个值结束) *必填 * decimals:小数位数,默认值为0 *可选 * duration:动画持续时间,单位为秒,默认值为2 *可选 * options:选项的可选对象 *可选 * useeasing:true --是否使用缓动动画,默认为缓动,可设置为false让其匀速 * usegrouping:true --对数字进行分组,如12345,按三位一组变为类似12,345这样的 * separator: ',' --分组时使用的分隔符默认是逗号 * decimal: '.' --小数点 * prefix: '' --添加前缀如12345,变为¥12345 * suffix: '' --添加后缀如12345 通过添加后缀变为12345$,12345元之类的 */ var countup = function(target, startval, endval, decimals, duration, options) { var self = this; self.version = function() { return "1.9.2" }; self.options = { useeasing: true, usegrouping: true, separator: ",", decimal: ".", easingfn: easeoutexpo, formattingfn: formatnumber, prefix: "", suffix: "", numerals: [] }; 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) { num = num.tofixed(self.decimals); num += ""; var x, x1, x2, x3, i, l; x = num.split("."); x1 = x[0]; x2 = x.length > 1 ? self.options.decimal + x[1] : ""; if (self.options.usegrouping) { x3 = ""; for (i = 0, l = x1.length; i < l; ++i) { if (i !== 0 && ((i % 3) === 0)) { x3 = self.options.separator + x3 } x3 = x1[l - 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 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) } };