https://github.com/taystack/js-counter
JavaScript step-counter. Helpful for finding animation values for pure javascript animations.
https://github.com/taystack/js-counter
Last synced: 3 months ago
JSON representation
JavaScript step-counter. Helpful for finding animation values for pure javascript animations.
- Host: GitHub
- URL: https://github.com/taystack/js-counter
- Owner: taystack
- Created: 2019-01-27T23:58:18.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2019-01-29T17:54:21.000Z (over 6 years ago)
- Last Synced: 2025-04-10T00:55:20.933Z (3 months ago)
- Language: JavaScript
- Size: 112 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README

[](https://codecov.io/gh/taystack/js-counter)
[](https://travis-ci.org/taystack/js-counter)---
- [Installation](#installation)
- [What is it?](#what-is-it)
- [Use](#use)
- [Documentation](#documentation)
- [Constructor](#constructor)
- [Attributes](#attributes)
- [Methods](#methods)# Installation
```bash
yarn add @taystack/js-counter
```or
```bash
npm i @taystack/js-counter
```# What is it?
JsCounter is a step-counter written in JavaScript.
# What is it for?
JsCounter is helpful for finding animation values for pure JavaScript animations. Pure-css transitions can be used to accomplish most any animation task. Sometimes you cannot rely on pure-css to animate things you need.
# Why it was written
During an animation loop, I was given two coordinantes `{x1}`, `{x2}`. I needed `{x1}` to get closer to `{x2}` at a constant rate. Simple css transition, but there was one catch; `{x2}` is constantly moving.
"So, what?" you say? Well, css transitions are picky. Once they invoke, you can change the target value, but the rate of change to get there is a function of how much time is left. Css transformations get weird with dynamic end-values.
# Use
If I wanted to change the `style.position.x` property of a DOM item, then I would use this module to track the position of, say, an animal inside an animation loop:
```javascript
import Counter from "@taystack/js-counter";class Animal {
constructor(speed, position = 0) {
this.speed = speed;
this.currentPosition = position;
this.position = new Counter(position, position, {increment: this.speed});
}set target(distance) {
this.position.setTarget(distance);
}animate() {
this.currentPosition = this.position.turn();
this.style.position.x = this.currentPosition;
}
}
```I could then create an animation loop tracking the animal's position chasing, say, another `Animal`. How about a dog chasing a cat?
```javascript
const dog = new Animal(5);
const cat = new Animal(6, 10); // more speed, further starting position
cat.target = Infinity; // cat is now targeting Infinity (running away)(function animateDog() {
cat.animate();
dog.target = cat.currentPosition; // dog is targeting the cat's position
dog.animate():
setTimeout(() => {
requestAnimationFrame(animateDog);
}, FRAMERATE);
})();
```Now, the `dog` will constantly be "chasing" the `cat` by adjusting it's `target` towards the cat's `currentPosition`.
If you wanted the dog to do something after it caught the cat, you could modify the `set target(distance)` setter method into an instance method that accepts `onDone`. Let's say, `hunt(distance, onDone)`:
```javascript
class Hunter extends Animal {
...
eat(animal) {/* ... */}hunt(distance, onDone) {
this.onDone = onDone;
this.position.setTarget(distance, { onDone });
}
...
}
```Now we can actually do something if our `dog` ever catches the `cat`. Let's try a wolf with our new `Hunter` class:
```javascript
const wolf = new Hunter(7);
const cat = new Animal(6);
cat.target = Infinity;(function animate() {
cat.animate();
wolf.hunt(cat.currentPosition, () => { wolf.eat(cat) });
setTimeout(() => {
requestAnimationFrame(animate);
}, FRAMERATE);
})();
```# Documentation
## Constructor
### `const counter = new Couter(Number from, Number to[, Object options])`
#### Params
- #### `from (Number)`
The value that *`counter`* starts at.
- #### `to (Number)`
The value that *`counter`* works towards after each call to *`counter.turn()`*.
- #### `options (Object)` _\_
- ##### `increment (Number > 0)`
The value used to calculate the step size of *`counter.current`* towards *`counter.to`* each time *`counter.turn()`* is called.***Default***: `1`
***Note***: This value should always be positive
***TODO***: Make this use `Math.abs`
- ##### `onDone(value) (Function)`
`Function` to invoke when *`counter`* reaches it's target.***`onDone` params***
- `value (Number)` - *`counter.value`*## Attributes
- #### `counter.value`
The current value of the counter
## Methods
- #### `counter.turn()`
This will advance *`counter.current`* towards *`counter.to`*
***Returns:*** `counter.value`
- #### `counter.setTarget(Number to[, Number increment=1])`
Updates the target value of *`counter`*
***Note:*** *Params are the same as constructor [to, increment] params*