or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation-controls.mddom-animation.mdgestures.mdindex.mdlayout-animations.mdreact-components.mdvalue-system.md

dom-animation.mddocs/

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

```