From 0224bd1fdf76564b7ea9c0328e1eb182d9a4098c Mon Sep 17 00:00:00 2001 From: Oleksii Raspopov Date: Thu, 17 Oct 2024 21:54:35 -0400 Subject: [PATCH] dts file, readme, manifest --- README.md | 134 ++++++++++++++++++++++++++++++++++++++++++++++- oscillation.d.ts | 71 ++++++++++++++++++------- package.json | 4 ++ rollup.config.js | 2 +- 4 files changed, 190 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index a99fdab..73788c3 100644 --- a/README.md +++ b/README.md @@ -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`. + +## Types + +Extra types provided for TypeScript: + +- `Motion`: 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 diff --git a/oscillation.d.ts b/oscillation.d.ts index 2edf521..de17b17 100644 --- a/oscillation.d.ts +++ b/oscillation.d.ts @@ -1,41 +1,74 @@ -type Series = - | number - | Float64Array - | Float32Array - | Uint32Array - | Int32Array - | Uint16Array - | Int16Array - | Uint8Array - | Int8Array - | Array; - +/** + * 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>( defs: Value, callback: (state: Value extends Motion ? 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 }>( defs: Dict, callback: (state: { [k in keyof Dict]: Dict[k] extends Motion ? V : never }) => void, options?: { signal: AbortSignal }, ): void; -export function motion>>( +/** + * 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, ...Motion[]]>( defs: List, - callback: (state: List extends Array> ? Array : never) => void, + callback: (state: { [k in keyof List]: List[k] extends Motion ? V : never }) => void, options?: { signal: AbortSignal }, ): void; -type Motion = { +export type Motion = { update(): void; complete(): boolean; interpolate(t: number): Value; }; -type SpringConfig = { damping: number; frequency: number; precision: number }; - -export function spring( +/** Creates a spring-based motion between source and destination values. */ +export function spring< + Value = + | number + | Float64Array + | Float32Array + | Uint32Array + | Int32Array + | Uint16Array + | Int16Array + | Uint8Array + | Int8Array + | Array, +>( source: Value, destination: Value, - config?: SpringConfig, + config?: { damping: number; frequency: number; precision: number }, ): Motion; diff --git a/package.json b/package.json index 2490af2..18c6fa6 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/rollup.config.js b/rollup.config.js index 5ca931d..d438c74 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -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 }, ], }),