@petit-kit/animate
v0.0.23
Published
A lightweight, reactive web component framework with built-in plugins for modern web development.
Maintainers
Readme
@petit-kit/animate
A lightweight animation library with time-based lerp and spring controllers for scalar, array, and object values. Includes raf (requestAnimationFrame loop) and simplified runLerp / runSpring fire-and-forget helpers.
Installation
npm install @petit-kit/animate
# or
pnpm add @petit-kit/animatelerp
Time-based exponential smoothing. Interpolates toward a target using a per-frame factor (0–1) that is converted to time-based interpolation.
Usage
import { lerp } from '@petit-kit/animate';
// Scalar
const opacity = lerp({ from: 0, to: 1, lerp: 0.2 });
opacity.setTarget(1);
opacity.next(); // advance by real time (call each frame)
// Array
const position = lerp({ from: [0, 0], to: [1, 1], lerp: 0.15 });
position.setTarget([2, 3]);
// Object
const point = lerp({ from: { x: 0, y: 0 }, to: { x: 1, y: 1 } });
point.setTarget({ x: 2, y: 3 });Options
| Option | Type | Default | Description |
| ---------------- | --------- | ------- | --------------------------------------------- |
| from | T | 0 | Initial value |
| to | T | 1 | Initial target |
| lerp | number | 0.1 | Interpolation intensity (0–1) per 60fps frame |
| tolerance | number | 0.001 | Distance threshold to consider "at rest" |
| resumeOnTarget | boolean | true | Resume when a new target is set after done |
API
| Method | Description |
| ------------------------------- | --------------------------------------------------------------------------------- |
| setTarget(nextTarget) | Set the target value. Resumes if done and resumeOnTarget is true |
| setValue(nextValue, options?) | Set current value. Options: resetTime, setTarget, markDone |
| getValue() | Get current value (cloned) |
| isDone() | Whether the animation is at rest |
| onResume(handler) | Subscribe to resume events. Returns unsubscribe |
| step(dt) | Advance by dt seconds. Returns current value |
| next(now?) | Advance by real elapsed time since last call. Uses performance.now() by default |
Game loop example
const pos = lerp({ from: [0, 0], to: [100, 100], lerp: 0.1 });
function tick() {
const [x, y] = pos.next();
element.style.transform = `translate(${x}px, ${y}px)`;
requestAnimationFrame(tick);
}
tick();runLerp
Fire-and-forget lerp driven by RAF. Creates the controller internally and calls onUpdate each frame. Returns a stop function.
import { runLerp } from '@petit-kit/animate';
const stop = runLerp({
from: 0,
to: 1,
options: { lerp: 0.1, fps: 60 },
onStart: () => console.log('start'),
onUpdate: (v) => (el.style.opacity = v),
onComplete: () => console.log('done'),
});
// later: stop();| Option | Type | Default | Description |
| ------------------------ | -------------------- | ------- | --------------------------------------------------- |
| from | T | 0 | Initial value |
| to | T | 1 | Target value |
| options.lerp | number | - | Interpolation intensity (0–1) per 60fps frame |
| options.fps | number | - | Throttle RAF to target FPS |
| options.tolerance | number | - | Distance threshold to consider "at rest" |
| options.delay | number | - | Seconds before animation starts |
| options.resumeOnTarget | boolean | - | Resume when new target is set after done |
| onStart | () => void | - | Called when animation starts |
| onUpdate | (value: T) => void | - | Called each frame (required) |
| onComplete | () => void | - | Called when animation is done |
| immediate | boolean | true | Call onUpdate with initial value before first frame |
| stopWhenDone | boolean | true | Stop RAF loop when animation is done |
spring
Time-based spring physics. Uses mass, stiffness, and damping to animate toward a target with natural overshoot and settle.
Usage
import { spring } from '@petit-kit/animate';
// Scalar
const scale = spring({ from: 0.8, to: 1, stiffness: 200, damping: 18 });
scale.setTarget(1.2);
// Array
const position = spring({ from: [0, 0], to: [1, 1], stiffness: 160 });
position.setTarget([2, 3]);
// Object
const point = spring({ from: { x: 0, y: 0 }, to: { x: 1, y: 1 } });
point.setTarget({ x: 2, y: 3 });Options
| Option | Type | Default | Description |
| ---------------- | --------- | ------- | --------------------------------------------------------- |
| from | T | 0 | Initial value |
| to | T | 1 | Initial target |
| mass | number | 1 | Mass of the spring |
| stiffness | number | 120 | Spring stiffness (k) |
| damping | number | 14 | Damping coefficient (c) |
| velocity | T | 0 | Initial velocity |
| tolerance | number | 0.001 | Velocity and displacement threshold to consider "at rest" |
| resumeOnTarget | boolean | true | Resume when a new target is set after done |
API
| Method | Description |
| ------------------------------- | --------------------------------------------------------------------------------- |
| setTarget(nextTarget) | Set the target value. Resumes if done and resumeOnTarget is true |
| setValue(nextValue, options?) | Set current value. Options: resetVelocity, resetTime, setTarget, markDone |
| getValue() | Get current value (cloned) |
| isDone() | Whether the spring is at rest |
| onResume(handler) | Subscribe to resume events. Returns unsubscribe |
| step(dt) | Advance physics by dt seconds. Returns current value |
| next(now?) | Advance by real elapsed time since last call. Uses performance.now() by default |
Game loop example
const scale = spring({ from: 0.8, to: 1, stiffness: 200, damping: 18 });
function tick() {
const s = scale.next();
element.style.transform = `scale(${s})`;
requestAnimationFrame(tick);
}
tick();runSpring
Fire-and-forget spring driven by RAF. Creates the controller internally and calls onUpdate each frame. Returns a stop function.
import { runSpring } from '@petit-kit/animate';
const stop = runSpring({
from: 0.8,
to: 1,
options: { stiffness: 200, damping: 18, fps: 60 },
onStart: () => console.log('start'),
onUpdate: (v) => (el.style.transform = `scale(${v})`),
onComplete: () => console.log('done'),
});
// later: stop();| Option | Type | Default | Description |
| ------------------------ | -------------------- | ------- | ----------------------------------------------------- |
| from | T | 0 | Initial value |
| to | T | 1 | Target value |
| options.mass | number | - | Mass of the spring |
| options.stiffness | number | - | Spring stiffness (k) |
| options.damping | number | - | Damping coefficient (c) |
| options.velocity | T | - | Initial velocity |
| options.fps | number | - | Throttle RAF to target FPS |
| options.delay | number | - | Seconds before animation starts |
| options.tolerance | number | - | Velocity/displacement threshold to consider "at rest" |
| options.resumeOnTarget | boolean | - | Resume when new target is set after done |
| onStart | () => void | - | Called when animation starts |
| onUpdate | (value: T) => void | - | Called each frame (required) |
| onComplete | () => void | - | Called when animation is done |
| immediate | boolean | true | Call onUpdate with initial value before first frame |
| stopWhenDone | boolean | true | Stop RAF loop when animation is done |
raf
RequestAnimationFrame loop with optional FPS throttling. Returns an unsubscribe function.
import { raf } from '@petit-kit/animate';
const stop = raf((time, deltaTime) => {
position += velocity * (deltaTime / 1000);
});
// later: stop();// Throttle to 30 FPS
raf((time, dt) => update(dt), 30);curves
Easing functions for t in [0, 1]. Use with keyframe or timeline-based animations.
import { curves } from '@petit-kit/animate';
curves.linear(t);
curves.easeInQuad(t);
curves.easeOutQuad(t);
curves.easeInOutQuad(t);
curves.easeInCubic(t);
curves.easeOutCubic(t);
curves.easeInOutCubic(t);
// ... easeIn/Out/InOut for Quart, Quint, Expo, Circ, Back, Elastic, Bounce
curves.easeInSine(t);
curves.easeOutSine(t);
curves.easeInOutSine(t);