Skip to content

Commit 7ab45a3

Browse files
author
Jamie Perkins
committed
2.0 ready to ship
1 parent ab40ea9 commit 7ab45a3

File tree

13 files changed

+158
-312
lines changed

13 files changed

+158
-312
lines changed

README.md

Lines changed: 63 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,109 @@
11
# CountUp.js
2-
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.
2+
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.
33

4-
Despite its name, CountUp can count in either direction, depending on the `startVal` and `endVal` params that you pass.
4+
Despite its name, CountUp can count in either direction, depending on the start value and end value that you pass.
55

6-
CountUp.js supports all browsers.
6+
CountUp.js supports all browsers. MIT license.
77

88
## [Try the demo](http://inorganik.github.io/countUp.js)
99

10+
## New in 2.0.0
11+
12+
- Completely rewritten in **Typescript**! The distributed code is still Javascript.
13+
- **New** cleaner [method signature](#example).
14+
- Tests with **Jest**. As much code coverage as possible mocking requestAnimationFrame.
15+
- **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).
16+
- **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.
17+
1018
## See Also
1119

12-
- **[CountUp.js Angular ^2 Module](https://github.com/inorganik/countUp.js-angular2)** ![New and improved!](http://img4me.com/sxa.gif)
20+
- **[CountUp.js Angular ^2 Module](https://github.com/inorganik/countUp.js-angular2)**
1321
- **[CountUp.js Angular 1.x Module](https://github.com/inorganik/countUp.js-angular1)**
1422
- **[CountUp.js React](https://github.com/glennreyes/react-countup)**
1523
- **[CountUp.js Vue component wrapper](https://github.com/xlsdg/vue-countup-v2)**
1624
- **[CountUp.js WordPress Plugin](https://wordpress.org/plugins/countup-js/)**
17-
18-
## Installation
19-
20-
Simply include the countUp.js file in your project or install via npm/yarn using the package name `countup.js`.
21-
22-
Before making a pull request, please [read this](#contributing). MIT License.
23-
24-
A jQuery version is also included, but needs to be included manually.
25+
- **[CountUp.js jQuery Plugin](https://gist.github.com/inorganik/b63dbe5b3810ff2c0175aee4670a4732)**
2526

2627
## Usage:
27-
Params:
28-
- `target` = id of html element, input, svg text element, or var of previously selected element/input where counting occurs
29-
- `startVal` = the value you want to begin at
30-
- `endVal` = the value you want to arrive at
31-
- `decimals` = (optional) number of decimal places in number, default 0
32-
- `duration` = (optional) duration in seconds, default 2
33-
- `options` = (optional, see demo) formatting/easing options object
3428

35-
Decimals, duration, and options can be left out to use the default values.
29+
**On npm**: `countup.js`
30+
31+
**Params**:
32+
- `target: string | HTMLElement | HTMLInputElement` - id of html element, input, svg text element, or DOM element reference where counting occurs
33+
- `endVal: number` - the value you want to arrive at
34+
- `options?: CountUpOptions` - optional configuration object for fine-grain control
35+
36+
**Options** (defaults in parentheses): <a name="options"></a>
37+
38+
```ts
39+
interface CountUpOptions {
40+
startVal?: number; // number to start at (0)
41+
decimalPlaces?: number; // number of decimal places (0)
42+
duration?: number; // animation duration in seconds (2)
43+
useGrouping?: boolean; // example: 1,000 vs 1000 (true)
44+
useEasing?: boolean; // ease animation (true)
45+
smartEasingThreshold?: number; // smooth easing for large numbers above this if useEasing (999)
46+
smartEasingAmount?: number; // amount to be eased for numbers above threshold (333)
47+
separator?: string; // grouping separator (',')
48+
decimal?: string; // decimal ('.')
49+
// easingFn: easing function for animation (easeOutExpo)
50+
easingFn?: (t: number, b: number, c: number, d: number) => number;
51+
formattingFn?: (n: number) => string; // this function formats result
52+
prefix?: string; // text prepended to result
53+
suffix?: string; // text appended to result
54+
numerals?: string[]; // numeral glyph substitution
55+
}
56+
```
57+
58+
**Example usage**: <a name="example"></a>
3659

3760
```js
38-
var numAnim = new CountUp("SomeElementYouWantToAnimate", 24.02, 99.99);
39-
if (!numAnim.error) {
40-
numAnim.start();
61+
const countUp = new CountUp('targetId', 5234);
62+
if (!countUp.error) {
63+
countUp.start();
4164
} else {
42-
console.error(numAnim.error);
65+
console.error(countUp.error);
4366
}
4467
```
4568

69+
Pass options:
70+
```js
71+
const countUp = new CountUp('targetId', 5234, options);
72+
```
73+
4674
with optional callback:
4775

4876
```js
49-
numAnim.start(someMethodToCallOnComplete);
77+
countUp.start(someMethodToCallOnComplete);
5078

5179
// or an anonymous function
52-
numAnim.start(function() {
53-
// do something
54-
})
80+
countUp.start(() => console.log('Complete!'));
5581
```
5682

57-
#### Other methods:
83+
**Other methods**:
84+
5885
Toggle pause/resume:
5986

6087
```js
61-
numAnim.pauseResume();
88+
countUp.pauseResume();
6289
```
6390

64-
Reset an animation:
91+
Reset the animation:
6592

6693
```js
67-
numAnim.reset();
94+
countUp.reset();
6895
```
6996

7097
Update the end value and animate:
7198

7299
```js
73-
var someValue = 1337;
74-
numAnim.update(someValue);
75-
```
76-
77-
#### Animating to large numbers
78-
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:
79-
```js
80-
var endVal = 9645.72;
81-
var numAnim = new CountUp('targetElem', 0, endVal - 100, 2, duration/2);
82-
numAnim.start(function() {
83-
numAnim.update(endVal);
84-
});
100+
countUp.update(989);
85101
```
86102

87103
## Contributing <a name="contributing"></a>
88104

89105
Before you make a pull request, please be sure to follow these instructions:
90106

91-
1. Do your work on `countUp.js` and/or other files in the root directory.
92-
2. In Terminal, `cd` to the `countUp.js` directory.
93-
3. Run `npm i`
94-
4. Run `npm run build`, which copies and minifies the .js files to the `dist` folder.
107+
1. Do your work on `src/countUp.ts`
108+
1. Test your work. Do manual tests on the demo in the browser and run `npm t`
109+
1. Run `npm run build`, which copies and minifies the .js files to the `dist` folder.

countUp-jquery.js

Lines changed: 0 additions & 34 deletions
This file was deleted.

dist/countUp.d.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
export interface CountUpOptions {
2+
startVal?: number;
3+
decimalPlaces?: number;
4+
duration?: number;
5+
useGrouping?: boolean;
6+
useEasing?: boolean;
7+
smartEasingThreshold?: number;
8+
smartEasingAmount?: number;
9+
separator?: string;
10+
decimal?: string;
11+
easingFn?: (t: number, b: number, c: number, d: number) => number;
12+
formattingFn?: (n: number) => string;
13+
prefix?: string;
14+
suffix?: string;
15+
numerals?: string[];
16+
}
17+
export declare class CountUp {
18+
private target;
19+
private endVal;
20+
private options?;
21+
version: string;
22+
private defaults;
23+
private el;
24+
private rAF;
25+
private startTime;
26+
private decimalMult;
27+
private remaining;
28+
private finalEndVal;
29+
private useEasing;
30+
private countDown;
31+
formattingFn: (num: number) => string;
32+
easingFn?: (t: number, b: number, c: number, d: number) => number;
33+
callback: (args?: any) => any;
34+
error: string;
35+
startVal: number;
36+
duration: number;
37+
paused: boolean;
38+
frameVal: number;
39+
constructor(target: string | HTMLElement | HTMLInputElement, endVal: number, options?: CountUpOptions);
40+
private determineDirectionAndSmartEasing;
41+
start(callback?: (args?: any) => any): void;
42+
pauseResume(): void;
43+
reset(): void;
44+
update(newEndVal: any): void;
45+
count: (timestamp: number) => void;
46+
printValue(val: number): void;
47+
ensureNumber(n: any): boolean;
48+
validateValue(value: number): number;
49+
private resetDuration;
50+
formatNumber: (num: number) => string;
51+
easeOutExpo: (t: number, b: number, c: number, d: number) => number;
52+
}

dist/countUp.js

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,14 @@ var __assign = (this && this.__assign) || function () {
3434
duration: 2,
3535
useEasing: true,
3636
useGrouping: true,
37-
smartEaseEnabled: true,
38-
smartEaseThreshold: 999,
39-
smartEaseAmount: 333,
37+
smartEasingThreshold: 999,
38+
smartEasingAmount: 333,
4039
separator: ',',
4140
decimal: '.',
4241
prefix: '',
4342
suffix: ''
4443
};
45-
this.finalEndVal = null; // for auto-smoothing
44+
this.finalEndVal = null; // for smart easing
4645
this.useEasing = true;
4746
this.countDown = false;
4847
this.error = '';
@@ -87,7 +86,7 @@ var __assign = (this && this.__assign) || function () {
8786
_this.rAF = requestAnimationFrame(_this.count);
8887
}
8988
else if (_this.finalEndVal !== null) {
90-
// for auto-smoothing
89+
// smart easing
9190
_this.update(_this.finalEndVal);
9291
}
9392
else {
@@ -122,7 +121,6 @@ var __assign = (this && this.__assign) || function () {
122121
}
123122
return neg + _this.options.prefix + x1 + x2 + _this.options.suffix;
124123
};
125-
// t: current time, b: beginning value, c: change in value, d: duration
126124
this.easeOutExpo = function (t, b, c, d) {
127125
return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b;
128126
};
@@ -150,20 +148,19 @@ var __assign = (this && this.__assign) || function () {
150148
this.error = '[CountUp] target is null or undefined';
151149
}
152150
}
153-
CountUp.prototype.determineCountDownAndSmartEase = function (start, end) {
154-
this.countDown = (start > end);
155-
if (!this.options.smartEaseEnabled) {
156-
return;
157-
}
158-
var animateAmount = end - start;
159-
if (Math.abs(animateAmount) > this.options.smartEaseThreshold) {
151+
// determines where easing starts and whether to count down or up
152+
CountUp.prototype.determineDirectionAndSmartEasing = function () {
153+
var end = (this.finalEndVal) ? this.finalEndVal : this.endVal;
154+
this.countDown = (this.startVal > end);
155+
var animateAmount = end - this.startVal;
156+
if (Math.abs(animateAmount) > this.options.smartEasingThreshold) {
160157
this.finalEndVal = end;
161158
var up = (this.countDown) ? 1 : -1;
162-
this.endVal = this.endVal + (up * this.options.smartEaseAmount);
159+
this.endVal = end + (up * this.options.smartEasingAmount);
163160
this.duration = this.duration / 2;
164161
}
165162
else {
166-
this.endVal = (this.finalEndVal) ? this.finalEndVal : this.endVal;
163+
this.endVal = end;
167164
this.finalEndVal = null;
168165
}
169166
if (this.finalEndVal) {
@@ -180,8 +177,7 @@ var __assign = (this && this.__assign) || function () {
180177
}
181178
this.callback = callback;
182179
if (this.duration > 0) {
183-
// auto-smooth large numbers
184-
this.determineCountDownAndSmartEase(this.startVal, this.endVal);
180+
this.determineDirectionAndSmartEasing();
185181
this.paused = false;
186182
this.rAF = requestAnimationFrame(this.count);
187183
}
@@ -198,6 +194,7 @@ var __assign = (this && this.__assign) || function () {
198194
this.startTime = null;
199195
this.duration = this.remaining;
200196
this.startVal = this.frameVal;
197+
this.determineDirectionAndSmartEasing();
201198
this.rAF = requestAnimationFrame(this.count);
202199
}
203200
this.paused = !this.paused;
@@ -207,7 +204,6 @@ var __assign = (this && this.__assign) || function () {
207204
cancelAnimationFrame(this.rAF);
208205
this.paused = true;
209206
this.resetDuration();
210-
this.finalEndVal = null;
211207
this.startVal = this.validateValue(this.options.startVal);
212208
this.frameVal = this.startVal;
213209
this.printValue(this.startVal);
@@ -220,12 +216,11 @@ var __assign = (this && this.__assign) || function () {
220216
if (this.endVal === this.frameVal) {
221217
return;
222218
}
219+
this.startVal = this.frameVal;
223220
if (!this.finalEndVal) {
224221
this.resetDuration();
225222
}
226-
this.finalEndVal = null;
227-
this.startVal = this.frameVal;
228-
this.determineCountDownAndSmartEase(this.startVal, this.endVal);
223+
this.determineDirectionAndSmartEasing();
229224
this.rAF = requestAnimationFrame(this.count);
230225
};
231226
CountUp.prototype.printValue = function (val) {

dist/countUp.legacy.min.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)