Skip to content

Commit

Permalink
dts file, readme, manifest
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyraspopov committed Oct 18, 2024
1 parent d9208c2 commit 0224bd1
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 21 deletions.
134 changes: 133 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,138 @@
# Oscillation

Provides VanillaJS API for physics-based animations.
```bash
npm install oscillation
```

Oscillation is a physics-based animation library for creating smooth, natural-looking animations.

## Quick Start

```javascript
import { motion, spring } from "oscillation";

// Animate a single value
motion(spring(0, 100), (value) => {
console.log(value);
});

// Animate multiple properties
motion({ x: spring(0, 100), y: spring(0, 200) }, (state) => {
console.log(state.x, state.y);
});

// Animate an array of values
motion([spring([0, 0, 0], [255, 128, 0]), spring(0, 360)], ([color, rotation]) => {
console.log(color, rotation);
});
```

## API

### `motion(defs, callback, options?)`

Starts an animation and calls the callback with updated values on each frame. The `motion` function
is overloaded to support different input types:

1. Single motion object:

```javascript
motion(spring(0, 100), (value) => {
// value gets animated from 0 to 100
});
```

2. Object with motion properties:

```javascript
motion({ x: spring(0, 100), y: spring(-50, 50) }, ({ x, y }) => {
// x and y animated simultaneously
});
```

3. Array of motion objects:

```javascript
motion([spring([0, 0, 0], [255, 128, 0]), spring(0, 360)], ([color, rotation]) => {
// color and rotation animated simultaneously
});
```

Parameters:

- `defs`: A single `Motion` object, an object with `Motion` values, or an array of `Motion` objects.
- `callback`: A function called on each frame with the current state.
- `options`: Optional object with an `AbortSignal` to stop the animation.

### `spring(source, destination[, config])`

Creates a spring-based motion.

Parameters:

- `source`: Initial value(s).
- `destination`: Target value(s).
- `config`: Optional spring configuration (`damping`, `frequency`, `precision`).

Supports various numeric types: `number`, `Float64Array`, `Float32Array`, `Uint32Array`,
`Int32Array`, `Uint16Array`, `Int16Array`, `Uint8Array`, `Int8Array`, `Array<number>`.

## Types

Extra types provided for TypeScript:

- `Motion<Value>`: Represents an animatable value with methods:
- `update()`: Updates the motion state.
- `complete()`: Checks if the motion is complete.
- `interpolate(t: number)`: Interpolates the motion value at a given time t.

## Cancelling Animations

You can cancel ongoing animations using an `AbortSignal`:

```javascript
const controller = new AbortController();
const { signal } = controller;

motion(
spring(0, 100),
(value) => {
console.log(value);
},
{ signal },
);

// To cancel the animation:
controller.abort();
```

## Examples

### Animating UI Elements

```javascript
import { motion, spring } from "oscillation";

const button = document.querySelector("#myButton");

motion({ x: spring(0, 100), scale: spring(1, 1.2) }, (state) => {
button.style.transform = `translateX(${state.x}px) scale(${state.scale})`;
});
```

### Complex Color and Rotation Animation

```javascript
import { motion, spring } from "oscillation";

const element = document.querySelector("#animatedElement");

motion([spring([0, 0, 0], [255, 128, 0]), spring(0, 360)], ([color, rotation]) => {
const [r, g, b] = color;
element.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
element.style.transform = `rotate(${rotation}deg)`;
});
```

## Prior Art

Expand Down
71 changes: 52 additions & 19 deletions oscillation.d.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,74 @@
type Series =
| number
| Float64Array
| Float32Array
| Uint32Array
| Int32Array
| Uint16Array
| Int16Array
| Uint8Array
| Int8Array
| Array<number>;

/**
* Starts an animation and calls the callback with updated values on each frame.
* Provided motion defition is a single motion object.
*
* ```js
* motion(spring(0, 100), (value) => {
* // value gets animated from 0 to 100
* });
* ```
*/
export function motion<Value extends Motion<any>>(
defs: Value,
callback: (state: Value extends Motion<infer V> ? V : never) => void,
options?: { signal: AbortSignal },
): void;
/**
* Starts an animation and calls the callback with updated values on each frame.
* Provided motion defition is a single motion object.
*
* ```js
* motion({ x: spring(0, 100), y: spring(-50, 50) }, ({ x, y }) => {
* // callback receives an object which shape follows motion definition
* // x and y animated simultaneously
* });
* ```
*/
export function motion<Dict extends { [k: string]: Motion<any> }>(
defs: Dict,
callback: (state: { [k in keyof Dict]: Dict[k] extends Motion<infer V> ? V : never }) => void,
options?: { signal: AbortSignal },
): void;
export function motion<List extends Array<Motion<any>>>(
/**
* Starts an animation and calls the callback with updated values on each frame.
* Provided motion defition is a single motion object.
*
* ```js
* motion([
* spring([0, 0, 0], [255, 128, 0]),
* spring(0, 360),
* ], ([color, rotation]) => {
* // callback receives an array which elements follow the motion definition
* });
* ```
*/
export function motion<List extends [Motion<any>, ...Motion<any>[]]>(
defs: List,
callback: (state: List extends Array<Motion<infer V>> ? Array<V> : never) => void,
callback: (state: { [k in keyof List]: List[k] extends Motion<infer V> ? V : never }) => void,
options?: { signal: AbortSignal },
): void;

type Motion<Value> = {
export type Motion<Value> = {
update(): void;
complete(): boolean;
interpolate(t: number): Value;
};

type SpringConfig = { damping: number; frequency: number; precision: number };

export function spring<Value = Series>(
/** Creates a spring-based motion between source and destination values. */
export function spring<
Value =
| number
| Float64Array
| Float32Array
| Uint32Array
| Int32Array
| Uint16Array
| Int16Array
| Uint8Array
| Int8Array
| Array<number>,
>(
source: Value,
destination: Value,
config?: SpringConfig,
config?: { damping: number; frequency: number; precision: number },
): Motion<Value>;
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"name": "oscillation",
"description": "An animation library",
"version": "0.3.0",
"license": "ISC",
"author": "Oleksii Raspopov",
"repository": "UnknownPrinciple/oscillation",
"type": "module",
"scripts": {
"test": "playwright test",
Expand Down
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default defineConfig({
plugins: [
copy({
targets: [
{ src: ["LICENSE", "oscillation.d.ts"], dest: "build" },
{ src: ["README.md", "LICENSE", "oscillation.d.ts"], dest: "build" },
{ src: "package.json", dest: "build", transform: generatePackageJson },
],
}),
Expand Down

0 comments on commit 0224bd1

Please sign in to comment.