countup.js
Advanced tools
Comparing version 1.9.3 to 2.0.0
@@ -1,261 +0,260 @@ | ||
(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) { | ||
/* | ||
countUp.js | ||
by @inorganik | ||
*/ | ||
// target = id of html element or var of previously selected html element where counting occurs | ||
// startVal = the value you want to begin at | ||
// endVal = the value you want to arrive at | ||
// decimals = number of decimal places, default 0 | ||
// duration = duration of animation in seconds, default 2 | ||
// options = optional object of options (see below) | ||
var CountUp = function(target, startVal, endVal, decimals, duration, options) { | ||
var self = this; | ||
self.version = function () { return '1.9.3'; }; | ||
// default options | ||
self.options = { | ||
useEasing: true, // toggle easing | ||
useGrouping: true, // 1,000,000 vs 1000000 | ||
separator: ',', // character to use as a separator | ||
decimal: '.', // character to use as a decimal | ||
easingFn: easeOutExpo, // optional custom easing function, default is Robert Penner's easeOutExpo | ||
formattingFn: formatNumber, // optional custom formatting function, default is formatNumber above | ||
prefix: '', // optional text before the result | ||
suffix: '', // optional text after the result | ||
numerals: [] // optionally pass an array of custom numerals for 0-9 | ||
}; | ||
// extend default options with passed options object | ||
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 { | ||
// ensure the separator is a string (formatNumber assumes this) | ||
self.options.separator = '' + self.options.separator; | ||
} | ||
// make sure requestAnimationFrame and cancelAnimationFrame are defined | ||
// polyfill for browsers without native support | ||
// by Opera engineer Erik Möller | ||
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; | ||
} | ||
// optional numeral substitution | ||
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; | ||
} | ||
// Robert Penner's easeOutExpo | ||
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); | ||
// error checks | ||
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; | ||
} | ||
}; | ||
// Print value to target | ||
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; | ||
// to ease or not to ease | ||
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); | ||
} | ||
} | ||
// don't go past endVal since progress can exceed duration in the last frame | ||
if (self.countDown) { | ||
self.frameVal = (self.frameVal < self.endVal) ? self.endVal : self.frameVal; | ||
} else { | ||
self.frameVal = (self.frameVal > self.endVal) ? self.endVal : self.frameVal; | ||
} | ||
// decimal | ||
self.frameVal = Math.round(self.frameVal*self.dec)/self.dec; | ||
// format and print value | ||
self.printValue(self.frameVal); | ||
// whether to continue | ||
if (progress < self.duration) { | ||
self.rAF = requestAnimationFrame(self.count); | ||
} else { | ||
if (self.callback) self.callback(); | ||
} | ||
}; | ||
// start your animation | ||
self.start = function(callback) { | ||
if (!self.initialize()) return; | ||
self.callback = callback; | ||
self.rAF = requestAnimationFrame(self.count); | ||
}; | ||
// toggles pause/resume animation | ||
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); | ||
} | ||
}; | ||
// reset to startVal so animation can be run again | ||
self.reset = function() { | ||
self.paused = false; | ||
delete self.startTime; | ||
self.initialized = false; | ||
if (self.initialize()) { | ||
cancelAnimationFrame(self.rAF); | ||
self.printValue(self.startVal); | ||
} | ||
}; | ||
// pass a new endVal and start animation | ||
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); | ||
}; | ||
// format startVal on initialization | ||
if (self.initialize()) self.printValue(self.startVal); | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
return CountUp; | ||
})); | ||
(function (factory) { | ||
if (typeof module === "object" && typeof module.exports === "object") { | ||
var v = factory(require, exports); | ||
if (v !== undefined) module.exports = v; | ||
} | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports"], factory); | ||
} | ||
})(function (require, exports) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// playground: stackblitz.com/edit/countup-typescript | ||
var CountUp = /** @class */ (function () { | ||
function CountUp(target, endVal, options) { | ||
var _this = this; | ||
this.target = target; | ||
this.endVal = endVal; | ||
this.options = options; | ||
this.version = '2.0.0'; | ||
this.defaults = { | ||
startVal: 0, | ||
decimalPlaces: 0, | ||
duration: 2, | ||
useEasing: true, | ||
useGrouping: true, | ||
smartEasingThreshold: 999, | ||
smartEasingAmount: 333, | ||
separator: ',', | ||
decimal: '.', | ||
prefix: '', | ||
suffix: '' | ||
}; | ||
this.finalEndVal = null; // for smart easing | ||
this.useEasing = true; | ||
this.countDown = false; | ||
this.error = ''; | ||
this.startVal = 0; | ||
this.paused = true; | ||
this.count = function (timestamp) { | ||
if (!_this.startTime) { | ||
_this.startTime = timestamp; | ||
} | ||
var progress = timestamp - _this.startTime; | ||
_this.remaining = _this.duration - progress; | ||
// to ease or not to ease | ||
if (_this.useEasing) { | ||
if (_this.countDown) { | ||
_this.frameVal = _this.startVal - _this.easingFn(progress, 0, _this.startVal - _this.endVal, _this.duration); | ||
} | ||
else { | ||
_this.frameVal = _this.easingFn(progress, _this.startVal, _this.endVal - _this.startVal, _this.duration); | ||
} | ||
} | ||
else { | ||
if (_this.countDown) { | ||
_this.frameVal = _this.startVal - ((_this.startVal - _this.endVal) * (progress / _this.duration)); | ||
} | ||
else { | ||
_this.frameVal = _this.startVal + (_this.endVal - _this.startVal) * (progress / _this.duration); | ||
} | ||
} | ||
// don't go past endVal since progress can exceed duration in the last frame | ||
if (_this.countDown) { | ||
_this.frameVal = (_this.frameVal < _this.endVal) ? _this.endVal : _this.frameVal; | ||
} | ||
else { | ||
_this.frameVal = (_this.frameVal > _this.endVal) ? _this.endVal : _this.frameVal; | ||
} | ||
// decimal | ||
_this.frameVal = Math.round(_this.frameVal * _this.decimalMult) / _this.decimalMult; | ||
// format and print value | ||
_this.printValue(_this.frameVal); | ||
// whether to continue | ||
if (progress < _this.duration) { | ||
_this.rAF = requestAnimationFrame(_this.count); | ||
} | ||
else if (_this.finalEndVal !== null) { | ||
// smart easing | ||
_this.update(_this.finalEndVal); | ||
} | ||
else { | ||
if (_this.callback) { | ||
_this.callback(); | ||
} | ||
} | ||
}; | ||
// default format and easing functions | ||
this.formatNumber = function (num) { | ||
var neg = (num < 0) ? '-' : ''; | ||
var result, x, x1, x2, x3; | ||
result = Math.abs(num).toFixed(_this.options.decimalPlaces); | ||
result += ''; | ||
x = result.split('.'); | ||
x1 = x[0]; | ||
x2 = x.length > 1 ? _this.options.decimal + x[1] : ''; | ||
if (_this.options.useGrouping) { | ||
x3 = ''; | ||
for (var i = 0, len = x1.length; i < len; ++i) { | ||
if (i !== 0 && (i % 3) === 0) { | ||
x3 = _this.options.separator + x3; | ||
} | ||
x3 = x1[len - i - 1] + x3; | ||
} | ||
x1 = x3; | ||
} | ||
// optional numeral substitution | ||
if (_this.options.numerals && _this.options.numerals.length) { | ||
x1 = x1.replace(/[0-9]/g, function (w) { return _this.options.numerals[+w]; }); | ||
x2 = x2.replace(/[0-9]/g, function (w) { return _this.options.numerals[+w]; }); | ||
} | ||
return neg + _this.options.prefix + x1 + x2 + _this.options.suffix; | ||
}; | ||
this.easeOutExpo = function (t, b, c, d) { | ||
return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b; | ||
}; | ||
this.options = __assign({}, this.defaults, options); | ||
this.formattingFn = (this.options.formattingFn) ? | ||
this.options.formattingFn : this.formatNumber; | ||
this.easingFn = (this.options.easingFn) ? | ||
this.options.easingFn : this.easeOutExpo; | ||
this.startVal = this.validateValue(this.options.startVal); | ||
this.frameVal = this.startVal; | ||
this.endVal = this.validateValue(endVal); | ||
this.options.decimalPlaces = Math.max(0 || this.options.decimalPlaces); | ||
this.decimalMult = Math.pow(10, this.options.decimalPlaces); | ||
this.resetDuration(); | ||
this.options.separator = String(this.options.separator); | ||
this.useEasing = this.options.useEasing; | ||
if (this.options.separator === '') { | ||
this.options.useGrouping = false; | ||
} | ||
this.el = (typeof target === 'string') ? document.getElementById(target) : target; | ||
if (this.el) { | ||
this.printValue(this.startVal); | ||
} | ||
else { | ||
this.error = '[CountUp] target is null or undefined'; | ||
} | ||
} | ||
// determines where easing starts and whether to count down or up | ||
CountUp.prototype.determineDirectionAndSmartEasing = function () { | ||
var end = (this.finalEndVal) ? this.finalEndVal : this.endVal; | ||
this.countDown = (this.startVal > end); | ||
var animateAmount = end - this.startVal; | ||
if (Math.abs(animateAmount) > this.options.smartEasingThreshold) { | ||
this.finalEndVal = end; | ||
var up = (this.countDown) ? 1 : -1; | ||
this.endVal = end + (up * this.options.smartEasingAmount); | ||
this.duration = this.duration / 2; | ||
} | ||
else { | ||
this.endVal = end; | ||
this.finalEndVal = null; | ||
} | ||
if (this.finalEndVal) { | ||
this.useEasing = false; | ||
} | ||
else { | ||
this.useEasing = this.options.useEasing; | ||
} | ||
}; | ||
// start animation | ||
CountUp.prototype.start = function (callback) { | ||
if (this.error) { | ||
return; | ||
} | ||
this.callback = callback; | ||
if (this.duration > 0) { | ||
this.determineDirectionAndSmartEasing(); | ||
this.paused = false; | ||
this.rAF = requestAnimationFrame(this.count); | ||
} | ||
else { | ||
this.printValue(this.endVal); | ||
} | ||
}; | ||
// pause/resume animation | ||
CountUp.prototype.pauseResume = function () { | ||
if (!this.paused) { | ||
cancelAnimationFrame(this.rAF); | ||
} | ||
else { | ||
this.startTime = null; | ||
this.duration = this.remaining; | ||
this.startVal = this.frameVal; | ||
this.determineDirectionAndSmartEasing(); | ||
this.rAF = requestAnimationFrame(this.count); | ||
} | ||
this.paused = !this.paused; | ||
}; | ||
// reset to startVal so animation can be run again | ||
CountUp.prototype.reset = function () { | ||
cancelAnimationFrame(this.rAF); | ||
this.paused = true; | ||
this.resetDuration(); | ||
this.startVal = this.validateValue(this.options.startVal); | ||
this.frameVal = this.startVal; | ||
this.printValue(this.startVal); | ||
}; | ||
// pass a new endVal and start animation | ||
CountUp.prototype.update = function (newEndVal) { | ||
cancelAnimationFrame(this.rAF); | ||
this.startTime = null; | ||
this.endVal = this.validateValue(newEndVal); | ||
if (this.endVal === this.frameVal) { | ||
return; | ||
} | ||
this.startVal = this.frameVal; | ||
if (!this.finalEndVal) { | ||
this.resetDuration(); | ||
} | ||
this.determineDirectionAndSmartEasing(); | ||
this.rAF = requestAnimationFrame(this.count); | ||
}; | ||
CountUp.prototype.printValue = function (val) { | ||
var result = this.formattingFn(val); | ||
if (this.el.tagName === 'INPUT') { | ||
var input = this.el; | ||
input.value = result; | ||
} | ||
else if (this.el.tagName === 'text' || this.el.tagName === 'tspan') { | ||
this.el.textContent = result; | ||
} | ||
else { | ||
this.el.innerHTML = result; | ||
} | ||
}; | ||
CountUp.prototype.ensureNumber = function (n) { | ||
return (typeof n === 'number' && !isNaN(n)); | ||
}; | ||
CountUp.prototype.validateValue = function (value) { | ||
var newValue = Number(value); | ||
if (!this.ensureNumber(newValue)) { | ||
this.error = "[CountUp] invalid start or end value: " + value; | ||
return null; | ||
} | ||
else { | ||
return newValue; | ||
} | ||
}; | ||
CountUp.prototype.resetDuration = function () { | ||
this.startTime = null; | ||
this.duration = Number(this.options.duration) * 1000; | ||
this.remaining = this.duration; | ||
}; | ||
return CountUp; | ||
}()); | ||
exports.CountUp = CountUp; | ||
}); |
@@ -1,1 +0,1 @@ | ||
!function(a,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n(require,exports,module):a.CountUp=n()}(this,function(a,n,t){var e=function(a,n,t,e,i,r){function o(a){var n,t,e,i,r,o,s=a<0;if(a=Math.abs(a).toFixed(l.decimals),a+="",n=a.split("."),t=n[0],e=n.length>1?l.options.decimal+n[1]:"",l.options.useGrouping){for(i="",r=0,o=t.length;r<o;++r)0!==r&&r%3===0&&(i=l.options.separator+i),i=t[o-r-1]+i;t=i}return l.options.numerals.length&&(t=t.replace(/[0-9]/g,function(a){return l.options.numerals[+a]}),e=e.replace(/[0-9]/g,function(a){return l.options.numerals[+a]})),(s?"-":"")+l.options.prefix+t+e+l.options.suffix}function s(a,n,t,e){return t*(-Math.pow(2,-10*a/e)+1)*1024/1023+n}function u(a){return"number"==typeof a&&!isNaN(a)}var l=this;if(l.version=function(){return"1.9.3"},l.options={useEasing:!0,useGrouping:!0,separator:",",decimal:".",easingFn:s,formattingFn:o,prefix:"",suffix:"",numerals:[]},r&&"object"==typeof r)for(var m in l.options)r.hasOwnProperty(m)&&null!==r[m]&&(l.options[m]=r[m]);""===l.options.separator?l.options.useGrouping=!1:l.options.separator=""+l.options.separator;for(var d=0,c=["webkit","moz","ms","o"],f=0;f<c.length&&!window.requestAnimationFrame;++f)window.requestAnimationFrame=window[c[f]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[c[f]+"CancelAnimationFrame"]||window[c[f]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(a,n){var t=(new Date).getTime(),e=Math.max(0,16-(t-d)),i=window.setTimeout(function(){a(t+e)},e);return d=t+e,i}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(a){clearTimeout(a)}),l.initialize=function(){return!!l.initialized||(l.error="",l.d="string"==typeof a?document.getElementById(a):a,l.d?(l.startVal=Number(n),l.endVal=Number(t),u(l.startVal)&&u(l.endVal)?(l.decimals=Math.max(0,e||0),l.dec=Math.pow(10,l.decimals),l.duration=1e3*Number(i)||2e3,l.countDown=l.startVal>l.endVal,l.frameVal=l.startVal,l.initialized=!0,!0):(l.error="[CountUp] startVal ("+n+") or endVal ("+t+") is not a number",!1)):(l.error="[CountUp] target is null or undefined",!1))},l.printValue=function(a){var n=l.options.formattingFn(a);"INPUT"===l.d.tagName?this.d.value=n:"text"===l.d.tagName||"tspan"===l.d.tagName?this.d.textContent=n:this.d.innerHTML=n},l.count=function(a){l.startTime||(l.startTime=a),l.timestamp=a;var n=a-l.startTime;l.remaining=l.duration-n,l.options.useEasing?l.countDown?l.frameVal=l.startVal-l.options.easingFn(n,0,l.startVal-l.endVal,l.duration):l.frameVal=l.options.easingFn(n,l.startVal,l.endVal-l.startVal,l.duration):l.countDown?l.frameVal=l.startVal-(l.startVal-l.endVal)*(n/l.duration):l.frameVal=l.startVal+(l.endVal-l.startVal)*(n/l.duration),l.countDown?l.frameVal=l.frameVal<l.endVal?l.endVal:l.frameVal:l.frameVal=l.frameVal>l.endVal?l.endVal:l.frameVal,l.frameVal=Math.round(l.frameVal*l.dec)/l.dec,l.printValue(l.frameVal),n<l.duration?l.rAF=requestAnimationFrame(l.count):l.callback&&l.callback()},l.start=function(a){l.initialize()&&(l.callback=a,l.rAF=requestAnimationFrame(l.count))},l.pauseResume=function(){l.paused?(l.paused=!1,delete l.startTime,l.duration=l.remaining,l.startVal=l.frameVal,requestAnimationFrame(l.count)):(l.paused=!0,cancelAnimationFrame(l.rAF))},l.reset=function(){l.paused=!1,delete l.startTime,l.initialized=!1,l.initialize()&&(cancelAnimationFrame(l.rAF),l.printValue(l.startVal))},l.update=function(a){if(l.initialize()){if(a=Number(a),!u(a))return void(l.error="[CountUp] update() - new endVal is not a number: "+a);l.error="",a!==l.frameVal&&(cancelAnimationFrame(l.rAF),l.paused=!1,delete l.startTime,l.startVal=l.frameVal,l.endVal=a,l.countDown=l.startVal>l.endVal,l.rAF=requestAnimationFrame(l.count))}},l.initialize()&&l.printValue(l.startVal)};return e}); | ||
var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(t){for(var i,a=1,s=arguments.length;a<s;a++)for(var n in i=arguments[a])Object.prototype.hasOwnProperty.call(i,n)&&(t[n]=i[n]);return t}).apply(this,arguments)};!function(t){if("object"==typeof module&&"object"==typeof module.exports){var i=t(require,exports);void 0!==i&&(module.exports=i)}else"function"==typeof define&&define.amd&&define(["require","exports"],t)}(function(t,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var a=function(){function t(t,i,a){var u=this;this.target=t,this.endVal=i,this.options=a,this.version="2.0.0",this.defaults={startVal:0,decimalPlaces:0,duration:2,useEasing:!0,useGrouping:!0,smartEasingThreshold:999,smartEasingAmount:333,separator:",",decimal:".",prefix:"",suffix:""},this.finalEndVal=null,this.useEasing=!0,this.countDown=!1,this.error="",this.startVal=0,this.paused=!0,this.count=function(t){u.startTime||(u.startTime=t);var i=t-u.startTime;u.remaining=u.duration-i,u.useEasing?u.countDown?u.frameVal=u.startVal-u.easingFn(i,0,u.startVal-u.endVal,u.duration):u.frameVal=u.easingFn(i,u.startVal,u.endVal-u.startVal,u.duration):u.countDown?u.frameVal=u.startVal-(u.startVal-u.endVal)*(i/u.duration):u.frameVal=u.startVal+(u.endVal-u.startVal)*(i/u.duration),u.countDown?u.frameVal=u.frameVal<u.endVal?u.endVal:u.frameVal:u.frameVal=u.frameVal>u.endVal?u.endVal:u.frameVal,u.frameVal=Math.round(u.frameVal*u.decimalMult)/u.decimalMult,u.printValue(u.frameVal),i<u.duration?u.rAF=requestAnimationFrame(u.count):null!==u.finalEndVal?u.update(u.finalEndVal):u.callback&&u.callback()},this.formatNumber=function(t){var i,a,s,n,e,r=t<0?"-":"";if(i=Math.abs(t).toFixed(u.options.decimalPlaces),s=(a=(i+="").split("."))[0],n=1<a.length?u.options.decimal+a[1]:"",u.options.useGrouping){e="";for(var o=0,l=s.length;o<l;++o)0!==o&&o%3==0&&(e=u.options.separator+e),e=s[l-o-1]+e;s=e}return u.options.numerals&&u.options.numerals.length&&(s=s.replace(/[0-9]/g,function(t){return u.options.numerals[+t]}),n=n.replace(/[0-9]/g,function(t){return u.options.numerals[+t]})),r+u.options.prefix+s+n+u.options.suffix},this.easeOutExpo=function(t,i,a,s){return a*(1-Math.pow(2,-10*t/s))*1024/1023+i},this.options=__assign({},this.defaults,a),this.formattingFn=this.options.formattingFn?this.options.formattingFn:this.formatNumber,this.easingFn=this.options.easingFn?this.options.easingFn:this.easeOutExpo,this.startVal=this.validateValue(this.options.startVal),this.frameVal=this.startVal,this.endVal=this.validateValue(i),this.options.decimalPlaces=Math.max(this.options.decimalPlaces),this.decimalMult=Math.pow(10,this.options.decimalPlaces),this.resetDuration(),this.options.separator=String(this.options.separator),this.useEasing=this.options.useEasing,""===this.options.separator&&(this.options.useGrouping=!1),this.el="string"==typeof t?document.getElementById(t):t,this.el?this.printValue(this.startVal):this.error="[CountUp] target is null or undefined"}return t.prototype.determineDirectionAndSmartEasing=function(){var t=this.finalEndVal?this.finalEndVal:this.endVal;this.countDown=this.startVal>t;var i=t-this.startVal;if(Math.abs(i)>this.options.smartEasingThreshold){this.finalEndVal=t;var a=this.countDown?1:-1;this.endVal=t+a*this.options.smartEasingAmount,this.duration=this.duration/2}else this.endVal=t,this.finalEndVal=null;this.finalEndVal?this.useEasing=!1:this.useEasing=this.options.useEasing},t.prototype.start=function(t){this.error||(this.callback=t,0<this.duration?(this.determineDirectionAndSmartEasing(),this.paused=!1,this.rAF=requestAnimationFrame(this.count)):this.printValue(this.endVal))},t.prototype.pauseResume=function(){this.paused?(this.startTime=null,this.duration=this.remaining,this.startVal=this.frameVal,this.determineDirectionAndSmartEasing(),this.rAF=requestAnimationFrame(this.count)):cancelAnimationFrame(this.rAF),this.paused=!this.paused},t.prototype.reset=function(){cancelAnimationFrame(this.rAF),this.paused=!0,this.resetDuration(),this.startVal=this.validateValue(this.options.startVal),this.frameVal=this.startVal,this.printValue(this.startVal)},t.prototype.update=function(t){cancelAnimationFrame(this.rAF),this.startTime=null,this.endVal=this.validateValue(t),this.endVal!==this.frameVal&&(this.startVal=this.frameVal,this.finalEndVal||this.resetDuration(),this.determineDirectionAndSmartEasing(),this.rAF=requestAnimationFrame(this.count))},t.prototype.printValue=function(t){var i=this.formattingFn(t);"INPUT"===this.el.tagName?this.el.value=i:"text"===this.el.tagName||"tspan"===this.el.tagName?this.el.textContent=i:this.el.innerHTML=i},t.prototype.ensureNumber=function(t){return"number"==typeof t&&!isNaN(t)},t.prototype.validateValue=function(t){var i=Number(t);return this.ensureNumber(i)?i:(this.error="[CountUp] invalid start or end value: "+t,null)},t.prototype.resetDuration=function(){this.startTime=null,this.duration=1e3*Number(this.options.duration),this.remaining=this.duration},t}();i.CountUp=a}); |
@@ -1,28 +0,30 @@ | ||
var gulp = require('gulp'); | ||
var wrap = require('gulp-wrap-umd'); | ||
var uglify = require('gulp-uglify'); | ||
var rename = require('gulp-rename'); | ||
var del = require('del'); | ||
const gulp = require('gulp'); | ||
const uglify = require('gulp-uglify'); | ||
const concat = require('gulp-concat'); | ||
const del = require('del'); | ||
gulp.task('clean', function(cb) { | ||
del(['dist/*']); | ||
return cb(); | ||
}); | ||
const clean = () => del(['dist/*']); | ||
gulp.task('umd', ['clean'], function(file) { | ||
var umdCountup = gulp | ||
.src('countUp.js') | ||
.pipe(wrap({ | ||
namespace: 'CountUp', | ||
exports: 'CountUp' | ||
})) | ||
.pipe(gulp.dest('dist/')) | ||
.pipe(uglify({preserveComments: 'license'})) | ||
.pipe(rename({ | ||
suffix: '.min' | ||
})) | ||
.pipe(gulp.dest('dist/')); | ||
}); | ||
const buildNormal = () => { | ||
return gulp.src('./dist/countUp.js') | ||
.pipe(concat('countUp.min.js')) | ||
.pipe(uglify()) | ||
.pipe(gulp.dest('dist')); | ||
} | ||
gulp.task('build', ['umd']); | ||
gulp.task('default', ['build']); | ||
const buildLegacy = () => { | ||
return gulp.src([ | ||
'./requestAnimationFrame.polyfill.js', | ||
'./dist/countUp.js' | ||
]) | ||
.pipe(concat('countUp.withPolyfill.min.js')) | ||
.pipe(uglify()) | ||
.pipe(gulp.dest('dist')); | ||
} | ||
gulp.task('clean', clean); | ||
const build = gulp.series(buildNormal, buildLegacy); | ||
gulp.task('build', build); | ||
exports.clean = clean; | ||
exports.default = build; |
{ | ||
"name": "countup.js", | ||
"description": "Animates a numerical value by counting to it", | ||
"version": "1.9.3", | ||
"version": "2.0.0", | ||
"license": "MIT", | ||
@@ -13,12 +13,19 @@ "main": "./dist/countUp.min.js", | ||
"devDependencies": { | ||
"del": "~0.1.3", | ||
"gulp": "~3.8.10", | ||
"gulp-rename": "~1.2.0", | ||
"gulp-uglify": "^1.4.2", | ||
"gulp-wrap-umd": "~0.2.1" | ||
"@types/jest": "^24.0.6", | ||
"del": "^3.0.0", | ||
"gulp": "^4.0.0", | ||
"gulp-concat": "^2.6.1", | ||
"gulp-uglify": "^3.0.1", | ||
"jest": "^24.1.0", | ||
"ts-jest": "^24.0.0", | ||
"tslint": "^5.12.1", | ||
"typescript": "^3.3.3" | ||
}, | ||
"scripts": { | ||
"build": "gulp", | ||
"clean": "gulp clean" | ||
"build": "npm run clean && tsc && gulp", | ||
"clean": "gulp clean", | ||
"lint": "tslint --project tsconfig.json", | ||
"test": "jest", | ||
"test:watch": "jest --watch" | ||
} | ||
} |
109
README.md
# CountUp.js | ||
CountUp.js is a dependency-free, lightweight JavaScript "class" that can be used to quickly create animations that display numerical data in a more interesting way. | ||
CountUp.js is a dependency-free, lightweight Javascript class that can be used to quickly create animations that display numerical data in a more interesting way. | ||
Despite its name, CountUp can count in either direction, depending on the `startVal` and `endVal` params that you pass. | ||
Despite its name, CountUp can count in either direction, depending on the start value and end value that you pass. | ||
CountUp.js supports all browsers. | ||
CountUp.js supports all browsers. MIT license. | ||
## [Try the demo](http://inorganik.github.io/countUp.js) | ||
## Please note | ||
## New in 2.0.0 | ||
_Angular 1 and 2 modules used to be part of this repo_. **As of v1.9.0, they have moved.** See links below. | ||
- Completely rewritten in **Typescript**! The distributed code is still Javascript. | ||
- **New** cleaner [method signature](#example). | ||
- Tests with **Jest**. As much code coverage as possible mocking requestAnimationFrame. | ||
- **Smart easing**: CountUp intelligently defers easing until it gets close enough to the end value for easing to be visually noticeable. Configureable in the [options](#options). | ||
- **Separate bundles** for with and without the requestAnimationFrame polyfill. Choose `countUp.min.js` for modern browsers or `countUp.withPolyfill.min.js` for IE9 and older, and Opera mini. | ||
## See Also | ||
- **[CountUp.js Angular ^2 Module](https://github.com/inorganik/countUp.js-angular2)** | ||
- **[CountUp.js Angular 1.x Module](https://github.com/inorganik/countUp.js-angular1)** | ||
- **[CountUp.js Angular ^2 Module](https://github.com/inorganik/countUp.js-angular2)** | ||
- **[CountUp.js React](https://github.com/glennreyes/react-countup)** | ||
- **[CountUp.js Vue component wrapper](https://github.com/xlsdg/vue-countup-v2?ref=madewithvuejs.com)** | ||
- **[CountUp.js Vue component wrapper](https://github.com/xlsdg/vue-countup-v2)** | ||
- **[CountUp.js WordPress Plugin](https://wordpress.org/plugins/countup-js/)** | ||
- **[CountUp.js jQuery Plugin](https://gist.github.com/inorganik/b63dbe5b3810ff2c0175aee4670a4732)** | ||
## Installation | ||
## Usage: | ||
Simply include the countUp.js file in your project or install via npm or bower using the package name `countup.js` or `countUp.js` respectively. | ||
**On npm**: `countup.js` | ||
Before making a pull request, please [read this](#contributing). MIT License. | ||
**Params**: | ||
- `target: string | HTMLElement | HTMLInputElement` - id of html element, input, svg text element, or DOM element reference where counting occurs | ||
- `endVal: number` - the value you want to arrive at | ||
- `options?: CountUpOptions` - optional configuration object for fine-grain control | ||
A jQuery version is also included in case you like dollar signs. | ||
**Options** (defaults in parentheses): <a name="options"></a> | ||
## Usage: | ||
Params: | ||
- `target` = id of html element, input, svg text element, or var of previously selected element/input where counting occurs | ||
- `startVal` = the value you want to begin at | ||
- `endVal` = the value you want to arrive at | ||
- `decimals` = (optional) number of decimal places in number, default 0 | ||
- `duration` = (optional) duration in seconds, default 2 | ||
- `options` = (optional, see demo) formatting/easing options object | ||
```ts | ||
interface CountUpOptions { | ||
startVal?: number; // number to start at (0) | ||
decimalPlaces?: number; // number of decimal places (0) | ||
duration?: number; // animation duration in seconds (2) | ||
useGrouping?: boolean; // example: 1,000 vs 1000 (true) | ||
useEasing?: boolean; // ease animation (true) | ||
smartEasingThreshold?: number; // smooth easing for large numbers above this if useEasing (999) | ||
smartEasingAmount?: number; // amount to be eased for numbers above threshold (333) | ||
separator?: string; // grouping separator (',') | ||
decimal?: string; // decimal ('.') | ||
// easingFn: easing function for animation (easeOutExpo) | ||
easingFn?: (t: number, b: number, c: number, d: number) => number; | ||
formattingFn?: (n: number) => string; // this function formats result | ||
prefix?: string; // text prepended to result | ||
suffix?: string; // text appended to result | ||
numerals?: string[]; // numeral glyph substitution | ||
} | ||
``` | ||
Decimals, duration, and options can be left out to use the default values. | ||
**Example usage**: <a name="example"></a> | ||
```js | ||
var numAnim = new CountUp("SomeElementYouWantToAnimate", 24.02, 99.99); | ||
if (!numAnim.error) { | ||
numAnim.start(); | ||
const countUp = new CountUp('targetId', 5234); | ||
if (!countUp.error) { | ||
countUp.start(); | ||
} else { | ||
console.error(numAnim.error); | ||
console.error(countUp.error); | ||
} | ||
``` | ||
Pass options: | ||
```js | ||
const countUp = new CountUp('targetId', 5234, options); | ||
``` | ||
with optional callback: | ||
```js | ||
numAnim.start(someMethodToCallOnComplete); | ||
countUp.start(someMethodToCallOnComplete); | ||
// or an anonymous function | ||
numAnim.start(function() { | ||
// do something | ||
}) | ||
countUp.start(() => console.log('Complete!')); | ||
``` | ||
#### Other methods: | ||
**Other methods**: | ||
Toggle pause/resume: | ||
```js | ||
numAnim.pauseResume(); | ||
countUp.pauseResume(); | ||
``` | ||
Reset an animation: | ||
Reset the animation: | ||
```js | ||
numAnim.reset(); | ||
countUp.reset(); | ||
``` | ||
@@ -77,23 +100,11 @@ | ||
```js | ||
var someValue = 1337; | ||
numAnim.update(someValue); | ||
countUp.update(989); | ||
``` | ||
#### Animating to large numbers | ||
For large numbers, since CountUp has a long way to go in just a few seconds, the animation seems to abruptly stop. The solution is to subtract 100 from your `endVal`, then use the callback to invoke the `update` method which completes the animation with the same duration with a difference of only 100 to animate: | ||
```js | ||
var endVal = 9645.72; | ||
var numAnim = new CountUp("targetElem", 0, endVal - 100, 2, duration/2); | ||
numAnim.start(function() { | ||
numAnim.update(endVal); | ||
}); | ||
``` | ||
## Contributing <a name="contributing"></a> | ||
Before you make a pull request, please be sure to follow these super simple instructions: | ||
Before you make a pull request, please be sure to follow these instructions: | ||
1. Do your work on `countUp.js` and/or other files in the root directory. | ||
2. In Terminal, `cd` to the `countUp.js` directory. | ||
3. Run `npm install`, which installs gulp and its dependencies. | ||
4. Run `gulp`, which copies and minifies the .js files to the `dist` folder. | ||
1. Do your work on `src/countUp.ts` | ||
1. Test your work. Do manual tests on the demo in the browser and run `npm t` | ||
1. Run `npm run build`, which copies and minifies the .js files to the `dist` folder. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
22
110
75902
9
1458