Documentation menu
Reference
API reference
Every export of @animaly/dom 0.1 with its signature, its options and their defaults. Signatures are simplified from the published type definitions.
animate
One function animates elements, motion values, numbers, strings, objects and sequences. The first argument decides which overload applies. Every call returns Controls for all the values it started.
import type { AnimateOptions, Controls, ElementOptions, MotionValue, ObjectValues, Target, ValueKeyframes, ValueOptions, Values } from "@animaly/dom";
declare function animate(target: Target, values: Values, options?: ElementOptions): Controls;
declare function animate<T extends number | string>(value: MotionValue<T>, keyframes: ValueKeyframes<T>, options?: ValueOptions<T>): Controls;
declare function animate(from: number, to: ValueKeyframes<number>, options?: ValueOptions<number>): Controls;
declare function animate(from: string, to: ValueKeyframes<string>, options?: ValueOptions<string>): Controls;
declare function animate<Subject extends object>(target: Subject | readonly Subject[], values: ObjectValues, options?: ValueOptions<Subject>): Controls;
export type { AnimateOptions };import { animate } from "@animaly/dom";
animate(".button", { scale: [1, 0.95, 1], backgroundColor: "#7c3aed" }, { duration: 0.25 });import { animate } from "@animaly/dom";
animate(0, 1, { type: "spring", onUpdate: (latest) => console.log(latest) });import { animate } from "@animaly/dom";
animate([
[".title", { y: [20, 0], opacity: [0, 1] }, { duration: 0.4 }],
[".lede", { opacity: [0, 1] }, { at: "-0.2" }],
]);Callbacks
onComplete runs when every value of the call finishes. On elements, onUpdate receives each value and its property name; on values, numbers and objects it receives the latest value or the whole object.
import { animate } from "@animaly/dom";
animate(".box", { x: 100, opacity: 0.5 }, {
onUpdate: (latest, name) => console.log(name, latest),
onComplete: () => console.log("done"),
});AnimateOptions
type picks the driver. Without it, single values tween and arrays play as keyframes. delay takes seconds or a stagger.
import type { Ease, InertiaOptions, KeyframeOptions, SpringOptions } from "@animaly/core";
import type { Stagger } from "@animaly/dom";
type Delay = number | Stagger;
type TweenAnimation = { type?: "tween" | "keyframes"; delay?: Delay } & Omit<KeyframeOptions, "delay">;
type SpringAnimation = { type: "spring"; delay?: Delay } & Omit<SpringOptions, "delay">;
type InertiaAnimation = { type: "inertia"; delay?: Delay } & Omit<InertiaOptions, "delay">;
type AnimateOptions = TweenAnimation | SpringAnimation | InertiaAnimation;
export type { AnimateOptions, Ease };Tween and keyframes
| Option | Type | Default | What it does |
|---|---|---|---|
| duration | number | 0.3 | Seconds. |
| ease | Ease | Ease[] | "easeInOut" | linear, easeIn, easeOut, easeInOut, four bezier numbers or a function. An array sets one ease per keyframe segment. |
| times | number[] | none | Offsets from 0 to 1, one per keyframe. |
| repeat | number | 0 | How many extra times to play. |
| repeatType | "loop" | "reverse" | "mirror" | "loop" | How each repeat plays. |
| repeatDelay | number | 0 | Seconds between repeats. |
| delay | number | Stagger | 0 | Seconds before starting. |
import { animate } from "@animaly/dom";
animate(".loader", { rotate: 360 }, {
duration: 1,
ease: "linear",
repeat: 4,
repeatType: "loop",
repeatDelay: 0,
});Spring
| Option | Type | Default | What it does |
|---|---|---|---|
| stiffness | number | 100 | Higher is snappier. |
| damping | number | 10 | Higher settles with less bounce. |
| mass | number | 1 | Higher is heavier and slower. |
| velocity | number | none | Starting velocity in units per second. Retargeting keeps the current velocity. |
| duration | number | none | Seconds; settles the spring at a fixed duration instead of using stiffness. |
| restDelta | number | none | Distance from the target that counts as at rest. |
| restSpeed | number | none | Speed below which the spring counts as at rest. |
import { animate } from "@animaly/dom";
animate(".sheet", { y: 0 }, { type: "spring", stiffness: 300, damping: 30, mass: 1, velocity: 0, restDelta: 0.5 });Inertia
| Option | Type | Default | What it does |
|---|---|---|---|
| velocity | number | none | Starting velocity in units per second. |
| power | number | 0.8 | How far the value travels for a given velocity. |
| timeConstant | number | 325 | Milliseconds; higher glides longer. |
| min, max | number | none | Limits; past them a spring bounces the value back. |
| bounceStiffness | number | 500 | Stiffness of that bounce. |
| bounceDamping | number | 10 | Damping of that bounce. |
| modifyTarget | (ideal) => number | none | Change where the value comes to rest, for example to snap to a grid. |
| restDelta | number | 0.5 | Distance that counts as at rest. |
import { animate } from "@animaly/dom";
animate(".puck", { x: 0 }, { type: "inertia", velocity: 900, power: 0.8, timeConstant: 325, min: -200, max: 200 });Controls
time is in seconds and counts from the call, including delays. Negative speed plays backwards, for every driver except inertia. Controls are awaitable.
type Controls = {
time: number;
speed: number;
readonly duration: number;
readonly finished: Promise<void>;
pause(): void;
play(): void;
stop(): void;
complete(): void;
cancel(): void;
then(onResolve?: () => unknown, onReject?: (reason: unknown) => unknown): Promise<unknown>;
};
export type { Controls };import { animate } from "@animaly/dom";
const controls = animate(".panel", { x: 300 }, { duration: 2 });
controls.pause();
controls.time = 0.5;
controls.speed = 2;
controls.play();
await controls.finished;
console.log("done");stagger
| Option | Type | Default | What it does |
|---|---|---|---|
| duration | number | 0.1 | Seconds between neighbours (the first argument). |
| from | "first" | "last" | "center" | number | "first" | Which element starts. |
| startDelay | number | 0 | Seconds added to every delay. |
| ease | Ease | none | Spreads the delays along an ease instead of evenly. |
import type { Ease } from "@animaly/core";
type StaggerOptions = { startDelay?: number; from?: "first" | "last" | "center" | number; ease?: Ease };
declare function stagger(duration?: number, options?: StaggerOptions): (index: number, total: number) => number;
export type { StaggerOptions };import { animate, stagger } from "@animaly/dom";
animate(".dot", { scale: [1, 1.5, 1] }, { duration: 0.5, delay: stagger(0.08, { from: "center", startDelay: 0.2 }) });import { stagger } from "@animaly/dom";
const delay = stagger(0.1, { from: "last" });
console.log([0, 1, 2, 3].map((index) => delay(index, 4).toFixed(1))); // ["0.3", "0.2", "0.1", "0.0"]Sequences
Pass an array of segments and labels to animate. at takes seconds, "+0.5" or "-0.2" relative to the previous segment, "<" for the previous segment's start, or a label.
import type { AnimateOptions, Target, Values } from "@animaly/dom";
type At = number | string;
type Segment = readonly [Target, Values] | readonly [Target, Values, AnimateOptions & { at?: At }];
type Label = string | { name: string; at: At };
type Sequence = readonly (Segment | Label)[];
type SequenceOptions = { repeat?: number; delay?: number; defaultTransition?: AnimateOptions };
export type { Sequence, SequenceOptions };import { animate } from "@animaly/dom";
animate(
[
[".a", { x: 100 }],
"middle",
[".b", { x: 100 }, { at: "middle" }],
],
{ repeat: 1, delay: 0.2, defaultTransition: { duration: 0.3, ease: "easeOut" } },
);motionValue
Returns a MotionValue with get, set, jump, getVelocity, getPrevious, isAnimating, stop, destroy and on. See motion values for every method.
import type { MotionValue } from "@animaly/dom";
declare function motionValue(initial: number): MotionValue<number>;
declare function motionValue(initial: string): MotionValue<string>;
export type { MotionValue };import { animate, motionValue } from "@animaly/dom";
const x = motionValue(0);
x.on("change", (latest) => console.log(latest));
animate(x, 100, { type: "spring" });createAnimator and sharedAnimator
The exported animate and motionValue use one shared animator. createAnimator makes an independent one with its own engine and settings; sharedAnimator returns the shared one.
| Option | Type | Default | What it does |
|---|---|---|---|
| scheduler | Scheduler | browser frames | Where frame times come from; pass a ManualScheduler from @animaly/core in tests. |
| maxAccelerated | number | 0 | How many elements may run as CSS animations at once. The default 0 keeps everything on the JS path; a positive number opts calls that only touch x, y, rotate, scale and opacity into the CSS path. |
| colorMix | "linear" | "squared" | "linear" | How colors are mixed between keyframes. |
import type { Scheduler } from "@animaly/core";
import type { Animator } from "@animaly/dom";
type AnimatorOptions = { scheduler?: Scheduler; maxAccelerated?: number; colorMix?: "linear" | "squared" };
declare function createAnimator(options?: AnimatorOptions): Animator;
declare function sharedAnimator(): Animator;
export type { AnimatorOptions };import { createAnimator } from "@animaly/dom";
const animator = createAnimator({ maxAccelerated: 0, colorMix: "squared" });
animator.animate(".tile", { x: 80, backgroundColor: "#ec4899" }, { duration: 0.4 });import { animate, sharedAnimator } from "@animaly/dom";
const box = document.querySelector<HTMLElement>(".box")!;
animate(box, { x: 200 }, { duration: 1 });
setTimeout(() => {
const animator = sharedAnimator();
console.log(animator.isAnimating(box, "x"), Math.round(animator.valueOf(box, "x") ?? 0));
}, 300);canAnimate and parseColor
canAnimate(element, name) tells you whether a property name can be animated on an element: transforms, CSS properties, CSS variables and SVG attributes. parseColor returns red, green, blue and alpha.
import { canAnimate } from "@animaly/dom";
const box = document.querySelector<HTMLElement>(".box")!;
console.log(canAnimate(box, "x")); // true
console.log(canAnimate(box, "--accent")); // true
console.log(canAnimate(box, "notAProperty")); // falseimport { parseColor } from "@animaly/dom";
console.log(parseColor("#7c3aed")); // [124, 58, 237, 1]
console.log(parseColor("rgba(236, 72, 153, 0.5)")); // [236, 72, 153, 0.5]parseColor accepts hex, rgb(), rgba(), hsl() and hsla(). Named colors such as red throw an error.