Skip to content

Commit

Permalink
2.0 ready to ship
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamie Perkins committed Feb 21, 2019
1 parent ab40ea9 commit 7ab45a3
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 312 deletions.
111 changes: 63 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,94 +1,109 @@
# 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)

## New in 2.0.0

- 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)** ![New and improved!](http://img4me.com/sxa.gif)
- **[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 React](https://github.com/glennreyes/react-countup)**
- **[CountUp.js Vue component wrapper](https://github.com/xlsdg/vue-countup-v2)**
- **[CountUp.js WordPress Plugin](https://wordpress.org/plugins/countup-js/)**

## Installation

Simply include the countUp.js file in your project or install via npm/yarn using the package name `countup.js`.

Before making a pull request, please [read this](#contributing). MIT License.

A jQuery version is also included, but needs to be included manually.
- **[CountUp.js jQuery Plugin](https://gist.github.com/inorganik/b63dbe5b3810ff2c0175aee4670a4732)**

## 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

Decimals, duration, and options can be left out to use the default values.
**On npm**: `countup.js`

**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

**Options** (defaults in parentheses): <a name="options"></a>

```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
}
```

**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();
```

Update the end value and animate:

```js
var someValue = 1337;
numAnim.update(someValue);
```

#### 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);
});
countUp.update(989);
```

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

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 i`
4. Run `npm run build`, 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.
34 changes: 0 additions & 34 deletions countUp-jquery.js

This file was deleted.

52 changes: 52 additions & 0 deletions dist/countUp.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
export interface CountUpOptions {
startVal?: number;
decimalPlaces?: number;
duration?: number;
useGrouping?: boolean;
useEasing?: boolean;
smartEasingThreshold?: number;
smartEasingAmount?: number;
separator?: string;
decimal?: string;
easingFn?: (t: number, b: number, c: number, d: number) => number;
formattingFn?: (n: number) => string;
prefix?: string;
suffix?: string;
numerals?: string[];
}
export declare class CountUp {
private target;
private endVal;
private options?;
version: string;
private defaults;
private el;
private rAF;
private startTime;
private decimalMult;
private remaining;
private finalEndVal;
private useEasing;
private countDown;
formattingFn: (num: number) => string;
easingFn?: (t: number, b: number, c: number, d: number) => number;
callback: (args?: any) => any;
error: string;
startVal: number;
duration: number;
paused: boolean;
frameVal: number;
constructor(target: string | HTMLElement | HTMLInputElement, endVal: number, options?: CountUpOptions);
private determineDirectionAndSmartEasing;
start(callback?: (args?: any) => any): void;
pauseResume(): void;
reset(): void;
update(newEndVal: any): void;
count: (timestamp: number) => void;
printValue(val: number): void;
ensureNumber(n: any): boolean;
validateValue(value: number): number;
private resetDuration;
formatNumber: (num: number) => string;
easeOutExpo: (t: number, b: number, c: number, d: number) => number;
}
37 changes: 16 additions & 21 deletions dist/countUp.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ var __assign = (this && this.__assign) || function () {
duration: 2,
useEasing: true,
useGrouping: true,
smartEaseEnabled: true,
smartEaseThreshold: 999,
smartEaseAmount: 333,
smartEasingThreshold: 999,
smartEasingAmount: 333,
separator: ',',
decimal: '.',
prefix: '',
suffix: ''
};
this.finalEndVal = null; // for auto-smoothing
this.finalEndVal = null; // for smart easing
this.useEasing = true;
this.countDown = false;
this.error = '';
Expand Down Expand Up @@ -87,7 +86,7 @@ var __assign = (this && this.__assign) || function () {
_this.rAF = requestAnimationFrame(_this.count);
}
else if (_this.finalEndVal !== null) {
// for auto-smoothing
// smart easing
_this.update(_this.finalEndVal);
}
else {
Expand Down Expand Up @@ -122,7 +121,6 @@ var __assign = (this && this.__assign) || function () {
}
return neg + _this.options.prefix + x1 + x2 + _this.options.suffix;
};
// t: current time, b: beginning value, c: change in value, d: duration
this.easeOutExpo = function (t, b, c, d) {
return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b;
};
Expand Down Expand Up @@ -150,20 +148,19 @@ var __assign = (this && this.__assign) || function () {
this.error = '[CountUp] target is null or undefined';
}
}
CountUp.prototype.determineCountDownAndSmartEase = function (start, end) {
this.countDown = (start > end);
if (!this.options.smartEaseEnabled) {
return;
}
var animateAmount = end - start;
if (Math.abs(animateAmount) > this.options.smartEaseThreshold) {
// 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 = this.endVal + (up * this.options.smartEaseAmount);
this.endVal = end + (up * this.options.smartEasingAmount);
this.duration = this.duration / 2;
}
else {
this.endVal = (this.finalEndVal) ? this.finalEndVal : this.endVal;
this.endVal = end;
this.finalEndVal = null;
}
if (this.finalEndVal) {
Expand All @@ -180,8 +177,7 @@ var __assign = (this && this.__assign) || function () {
}
this.callback = callback;
if (this.duration > 0) {
// auto-smooth large numbers
this.determineCountDownAndSmartEase(this.startVal, this.endVal);
this.determineDirectionAndSmartEasing();
this.paused = false;
this.rAF = requestAnimationFrame(this.count);
}
Expand All @@ -198,6 +194,7 @@ var __assign = (this && this.__assign) || function () {
this.startTime = null;
this.duration = this.remaining;
this.startVal = this.frameVal;
this.determineDirectionAndSmartEasing();
this.rAF = requestAnimationFrame(this.count);
}
this.paused = !this.paused;
Expand All @@ -207,7 +204,6 @@ var __assign = (this && this.__assign) || function () {
cancelAnimationFrame(this.rAF);
this.paused = true;
this.resetDuration();
this.finalEndVal = null;
this.startVal = this.validateValue(this.options.startVal);
this.frameVal = this.startVal;
this.printValue(this.startVal);
Expand All @@ -220,12 +216,11 @@ var __assign = (this && this.__assign) || function () {
if (this.endVal === this.frameVal) {
return;
}
this.startVal = this.frameVal;
if (!this.finalEndVal) {
this.resetDuration();
}
this.finalEndVal = null;
this.startVal = this.frameVal;
this.determineCountDownAndSmartEase(this.startVal, this.endVal);
this.determineDirectionAndSmartEasing();
this.rAF = requestAnimationFrame(this.count);
};
CountUp.prototype.printValue = function (val) {
Expand Down
1 change: 0 additions & 1 deletion dist/countUp.legacy.min.js

This file was deleted.

Loading

0 comments on commit 7ab45a3

Please sign in to comment.