0
# DOM Animation
1
2
Core DOM animation functionality for animating elements directly without framework dependencies. Provides imperative animation controls with spring physics, keyframe support, and scroll-based animations.
3
4
## Capabilities
5
6
### Animate Function
7
8
Animates DOM elements using CSS properties with various animation types including springs, keyframes, and tweens.
9
10
```typescript { .api }
11
/**
12
* Animate one or more DOM elements
13
* @param target - CSS selector, Element, or array of Elements to animate
14
* @param keyframes - Animation values (single value or keyframe array)
15
* @param options - Animation configuration options
16
* @returns Animation controls for the created animation
17
*/
18
function animate(
19
target: ElementOrSelector,
20
keyframes: DOMKeyframesDefinition,
21
options?: AnimationOptions
22
): AnimationPlaybackControlsWithThen;
23
24
type ElementOrSelector = Element | Element[] | NodeListOf<Element> | string;
25
26
interface AnimationPlaybackControlsWithThen {
27
/** The current time of the animation, in seconds */
28
time: number;
29
/** The playback speed of the animation (1 = normal, 2 = double, 0.5 = half) */
30
speed: number;
31
/** The start time of the animation, in milliseconds */
32
startTime: number | null;
33
/** Duration of the animation, in seconds */
34
duration: number;
35
/** Stops the animation at its current state */
36
stop(): void;
37
/** Plays the animation */
38
play(): void;
39
/** Pauses the animation */
40
pause(): void;
41
/** Completes the animation and applies the final state */
42
complete(): void;
43
/** Cancels the animation and applies the initial state */
44
cancel(): void;
45
/** Promise that resolves when animation completes */
46
finished: Promise<any>;
47
/** Promise-like then method for chaining */
48
then(onResolve: () => void, onReject?: () => void): Promise<void>;
49
}
50
51
interface AnimationOptions {
52
/** Animation duration in seconds */
53
duration?: number;
54
/** Delay before animation starts in seconds */
55
delay?: number;
56
/** Animation easing function */
57
ease?: Easing;
58
/** Animation type */
59
type?: "spring" | "keyframes" | "tween";
60
/** Number of times to repeat */
61
repeat?: number;
62
/** How to repeat the animation */
63
repeatType?: "loop" | "reverse" | "mirror";
64
/** Delay between repeats in seconds */
65
repeatDelay?: number;
66
/** Direction of animation */
67
direction?: "normal" | "reverse" | "alternate" | "alternate-reverse";
68
/** Spring-specific options */
69
stiffness?: number;
70
damping?: number;
71
mass?: number;
72
bounce?: number;
73
}
74
75
type DOMKeyframesDefinition = {
76
[K in keyof CSSStyleDeclaration]?: ValueKeyframesDefinition;
77
} & {
78
x?: ValueKeyframesDefinition;
79
y?: ValueKeyframesDefinition;
80
z?: ValueKeyframesDefinition;
81
rotate?: ValueKeyframesDefinition;
82
scale?: ValueKeyframesDefinition;
83
skew?: ValueKeyframesDefinition;
84
pathLength?: ValueKeyframesDefinition;
85
pathOffset?: ValueKeyframesDefinition;
86
[key: `--${string}`]: ValueKeyframesDefinition;
87
};
88
89
type ValueKeyframesDefinition =
90
| string
91
| number
92
| Array<string | number | null>;
93
```
94
95
**Usage Examples:**
96
97
```typescript
98
import { animate } from "motion";
99
100
// Simple property animation
101
animate("#box", { x: 100, y: 50 }, { duration: 1 });
102
103
// Multiple keyframes
104
animate(".card", {
105
scale: [1, 1.2, 1],
106
rotate: [0, 180, 360]
107
}, { duration: 2, ease: "easeInOut" });
108
109
// Spring animation
110
animate("#element", { x: 200 }, {
111
type: "spring",
112
stiffness: 300,
113
damping: 20
114
});
115
116
// Complex keyframe object
117
animate("#complex", {
118
x: [0, 100, 200],
119
backgroundColor: ["#ff0000", "#00ff00", "#0000ff"],
120
borderRadius: ["0px", "50px", "0px"]
121
}, { duration: 3 });
122
```
123
124
### Animate Mini
125
126
Lightweight animation function using the Web Animations API for simple animations with minimal bundle size.
127
128
```typescript { .api }
129
/**
130
* Lightweight WAAPI-based animation
131
* @param target - CSS selector or Element to animate
132
* @param keyframes - WAAPI-compatible keyframe object
133
* @param options - WAAPI animation options
134
* @returns Web Animation API Animation instance
135
*/
136
function animateMini(
137
target: string | Element,
138
keyframes: Keyframe[] | PropertyIndexedKeyframes,
139
options?: KeyframeAnimationOptions
140
): Animation;
141
```
142
143
### Animate Sequence
144
145
Creates sequential animations that play one after another or with timing offsets.
146
147
```typescript { .api }
148
/**
149
* Create a sequence of animations
150
* @param sequence - Array of animation definitions
151
* @returns Promise that resolves when sequence completes
152
*/
153
function animateSequence(
154
sequence: AnimationSequence[]
155
): Promise<void>;
156
157
interface AnimationSequence {
158
target: string | Element | Element[];
159
keyframes: Keyframes;
160
options?: AnimationOptions & { at?: number | string };
161
}
162
```
163
164
**Usage Examples:**
165
166
```typescript
167
import { animateSequence } from "motion";
168
169
// Sequential animations
170
await animateSequence([
171
{ target: "#first", keyframes: { x: 100 }, options: { duration: 1 } },
172
{ target: "#second", keyframes: { y: 100 }, options: { duration: 1 } },
173
{ target: "#third", keyframes: { scale: 1.5 }, options: { duration: 1 } },
174
]);
175
176
// Overlapping animations with timing
177
await animateSequence([
178
{ target: "#a", keyframes: { x: 100 }, options: { duration: 2 } },
179
{ target: "#b", keyframes: { y: 100 }, options: { duration: 1, at: 0.5 } },
180
{ target: "#c", keyframes: { rotate: 360 }, options: { duration: 1, at: "-0.5" } },
181
]);
182
```
183
184
### Scroll Animation
185
186
Creates scroll-driven animations that respond to page or element scroll position.
187
188
```typescript { .api }
189
/**
190
* Create scroll-driven animations
191
* @param onScroll - Callback function or animation controls
192
* @param options - Scroll animation options
193
* @returns Function to stop scroll listener
194
*/
195
function scroll(
196
onScroll: OnScroll | AnimationPlaybackControls,
197
options?: ScrollOptions
198
): VoidFunction;
199
200
type OnScroll = (progress: number) => void | ((progress: number, info: ScrollInfo) => void);
201
202
interface ScrollInfo {
203
time: number;
204
x: AxisScrollInfo;
205
y: AxisScrollInfo;
206
}
207
208
interface AxisScrollInfo {
209
current: number;
210
offset: number[];
211
progress: number;
212
scrollLength: number;
213
velocity: number;
214
targetOffset: number;
215
targetLength: number;
216
containerLength: number;
217
}
218
219
interface ScrollOptions {
220
/** Source element for scroll events */
221
source?: HTMLElement;
222
/** Container element for scroll tracking */
223
container?: Element;
224
/** Target element to track scroll position */
225
target?: Element;
226
/** Axis to track ("x" or "y", defaults to "y") */
227
axis?: "x" | "y";
228
/** Scroll offset boundaries */
229
offset?: ScrollOffset;
230
}
231
232
type ScrollOffset = Array<Edge | Intersection | ProgressIntersection>;
233
type Edge = string | number;
234
type Intersection = `${Edge} ${Edge}`;
235
type ProgressIntersection = [number, number];
236
```
237
238
**Usage Examples:**
239
240
```typescript
241
import { scroll, animate } from "motion";
242
243
// Basic scroll animation
244
const stopScrolling = scroll(({ y }) => {
245
animate("#parallax", {
246
y: y.current * 0.5,
247
opacity: 1 - y.progress
248
});
249
});
250
251
// Element-specific scroll tracking
252
scroll(({ yProgress }) => {
253
animate("#progress-bar", {
254
scaleX: yProgress.current
255
});
256
}, {
257
target: document.querySelector("#scroll-container"),
258
offset: ["start end", "end start"]
259
});
260
```
261
262
### Scroll Info
263
264
Utility function for getting current scroll information without setting up a scroll listener.
265
266
```typescript { .api }
267
/**
268
* Get current scroll information
269
* @param element - Element to get scroll info for (defaults to window)
270
* @returns Current scroll position and progress
271
*/
272
function scrollInfo(element?: Element): ScrollInfoSnapshot;
273
274
interface ScrollInfoSnapshot {
275
/** Current horizontal scroll position */
276
x: number;
277
/** Current vertical scroll position */
278
y: number;
279
/** Horizontal scroll progress (0-1) */
280
xProgress: number;
281
/** Vertical scroll progress (0-1) */
282
yProgress: number;
283
}
284
```
285
286
**Usage Examples:**
287
288
```typescript
289
import { scrollInfo } from "motion";
290
291
// Get current window scroll info
292
const currentScroll = scrollInfo();
293
console.log("Scroll position:", currentScroll.x, currentScroll.y);
294
console.log("Scroll progress:", currentScroll.xProgress, currentScroll.yProgress);
295
296
// Get scroll info for specific element
297
const containerScroll = scrollInfo(document.querySelector("#container"));
298
```
299
300
### InView Animation
301
302
Triggers animations when elements enter or leave the viewport using Intersection Observer.
303
304
```typescript { .api }
305
/**
306
* Trigger animation when element enters viewport
307
* @param element - CSS selector or Element to observe
308
* @param onStart - Callback when element enters view
309
* @param options - Intersection observer options
310
* @returns Function to stop observing
311
*/
312
function inView(
313
elementOrSelector: ElementOrSelector,
314
onStart: (element: Element, entry: IntersectionObserverEntry) => void | ViewChangeHandler,
315
options?: InViewOptions
316
): VoidFunction;
317
318
type ViewChangeHandler = (entry: IntersectionObserverEntry) => void;
319
320
interface InViewOptions {
321
/** Root element for intersection (defaults to viewport) */
322
root?: Element | Document;
323
/** Root margin for intersection calculations */
324
margin?: MarginType;
325
/** Threshold for triggering intersection */
326
amount?: "some" | "all" | number;
327
}
328
329
type MarginType =
330
| `${number}${"px" | "%"}`
331
| `${number}${"px" | "%"} ${number}${"px" | "%"}`
332
| `${number}${"px" | "%"} ${number}${"px" | "%"} ${number}${"px" | "%"}`
333
| `${number}${"px" | "%"} ${number}${"px" | "%"} ${number}${"px" | "%"} ${number}${"px" | "%"}`;
334
```
335
336
**Usage Examples:**
337
338
```typescript
339
import { inView, animate } from "motion";
340
341
// Animate when element enters view
342
const stopObserving = inView("#fadeIn", (entry) => {
343
animate(entry.target,
344
{ opacity: 1, y: 0 },
345
{ duration: 0.6 }
346
);
347
});
348
349
// Multiple threshold points
350
inView(".card", (entry) => {
351
if (entry.isIntersecting) {
352
animate(entry.target, { scale: 1, opacity: 1 });
353
} else {
354
animate(entry.target, { scale: 0.8, opacity: 0.5 });
355
}
356
}, { amount: 0.5 });
357
```
358
359
### Scoped Animation
360
361
Creates animation functions scoped to specific elements or contexts for better performance and organization.
362
363
```typescript { .api }
364
/**
365
* Create a scoped animation function
366
* @param scope - Root element or selector for scoping
367
* @returns Scoped animate function
368
*/
369
function createScopedAnimate(
370
scope: string | Element
371
): (target: string, keyframes: Keyframes, options?: AnimationOptions) => AnimationControls;
372
```
373
374
**Usage Examples:**
375
376
```typescript
377
import { createScopedAnimate } from "motion";
378
379
// Create scoped animator for a component
380
const animateInModal = createScopedAnimate("#modal");
381
382
// All animations are scoped to the modal
383
animateInModal(".title", { y: 0, opacity: 1 });
384
animateInModal(".content", { y: 20, opacity: 1 }, { delay: 0.1 });
385
animateInModal(".button", { scale: 1 }, { delay: 0.2 });
386
```
387
388
## Value Utilities
389
390
### Color Values
391
392
Color manipulation utilities for animating between different color formats.
393
394
```typescript { .api }
395
/**
396
* Create RGB color value
397
* @param r - Red component (0-255)
398
* @param g - Green component (0-255)
399
* @param b - Blue component (0-255)
400
* @returns RGB color string
401
*/
402
function rgb(r: number, g: number, b: number): string;
403
404
/**
405
* Create RGBA color value
406
* @param r - Red component (0-255)
407
* @param g - Green component (0-255)
408
* @param b - Blue component (0-255)
409
* @param a - Alpha component (0-1)
410
* @returns RGBA color string
411
*/
412
function rgba(r: number, g: number, b: number, a: number): string;
413
414
/**
415
* Create HSL color value
416
* @param h - Hue (0-360)
417
* @param s - Saturation percentage (0-100)
418
* @param l - Lightness percentage (0-100)
419
* @returns HSL color string
420
*/
421
function hsl(h: number, s: number, l: number): string;
422
423
/**
424
* Convert hex color to RGB object
425
* @param hex - Hex color string
426
* @returns RGB color object
427
*/
428
function hex(hex: string): { r: number; g: number; b: number };
429
```
430
431
### Interpolation
432
433
Value interpolation utilities for creating smooth transitions between values.
434
435
```typescript { .api }
436
/**
437
* Interpolate between two values
438
* @param from - Start value
439
* @param to - End value
440
* @param progress - Progress between values (0-1)
441
* @returns Interpolated value
442
*/
443
function mix(from: number, to: number, progress: number): number;
444
445
/**
446
* Create interpolation function from input/output ranges
447
* @param inputRange - Array of input values
448
* @param outputRange - Array of corresponding output values
449
* @param options - Interpolation options
450
* @returns Interpolation function
451
*/
452
function interpolate(
453
inputRange: number[],
454
outputRange: (number | string)[],
455
options?: InterpolateOptions
456
): (input: number) => number | string;
457
458
interface InterpolateOptions {
459
/** Clamp output to range */
460
clamp?: boolean;
461
/** Easing function to apply */
462
ease?: Easing;
463
}
464
```
465
466
## Debug Utilities
467
468
### Performance Statistics
469
470
Debug utility for recording animation performance statistics.
471
472
```typescript { .api }
473
/**
474
* Record performance statistics for animations
475
* @param enabled - Whether to enable statistics recording
476
* @returns Performance statistics object
477
*/
478
function recordStats(enabled?: boolean): PerformanceStats;
479
480
interface PerformanceStats {
481
/** Start recording statistics */
482
start(): void;
483
/** Stop recording statistics */
484
stop(): void;
485
/** Get current statistics */
486
getStats(): AnimationStats;
487
/** Clear recorded statistics */
488
clear(): void;
489
}
490
491
interface AnimationStats {
492
/** Total animations created */
493
totalAnimations: number;
494
/** Currently active animations */
495
activeAnimations: number;
496
/** Average frame rate */
497
averageFPS: number;
498
/** Dropped frames count */
499
droppedFrames: number;
500
/** Memory usage in MB */
501
memoryUsage: number;
502
}
503
```
504
505
**Usage Examples:**
506
507
```typescript
508
import { recordStats } from "motion/debug";
509
510
// Start recording performance stats
511
const stats = recordStats(true);
512
stats.start();
513
514
// Run some animations...
515
animate("#element1", { x: 100 });
516
animate("#element2", { scale: 1.5 });
517
518
// Check performance
519
const currentStats = stats.getStats();
520
console.log("FPS:", currentStats.averageFPS);
521
console.log("Active animations:", currentStats.activeAnimations);
522
523
// Stop recording
524
stats.stop();
525
```