animejs

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Anime.js — Skill Reference

Anime.js — 技能参考文档

Lightweight, modular, high-performance JavaScript animation engine. Current version: 4.0.0 | Official docs: https://animejs.com/documentation

轻量级、模块化、高性能的JavaScript动画引擎。 当前版本:4.0.0 | 官方文档:https://animejs.com/documentation

Activation Contract

激活场景

Use this skill when:
  • Building web animations (CSS properties, transforms, colors) in vanilla JS or any framework
  • Creating animation sequences with timelines
  • Implementing scroll-triggered animations
  • Animating SVG elements (morphing, drawing, motion paths)
  • Text animations (split, scramble effects)
  • Interactive animations (draggable, animatable)
Works with: Vanilla JS, React, Vue, Svelte, Next.js, Nuxt, or any DOM-based project.
Do NOT use this skill for:
  • Complex physics simulations (use Matter.js or similar)
  • Canvas/WebGL animations (use Three.js or Pixi.js)
  • Video/audio sync (use native Web APIs)

当你需要以下场景时使用本技能:
  • 在原生JS或任意框架中构建Web动画(CSS属性、变换、颜色)
  • 创建带时间线的动画序列
  • 实现滚动触发式动画
  • 为SVG元素添加动画(变形、描边、运动路径)
  • 文本动画(拆分、打乱效果)
  • 交互式动画(可拖拽、可动画)
兼容框架:Vanilla JS、React、Vue、Svelte、Next.js、Nuxt或任何基于DOM的项目。
请勿在以下场景使用本技能:
  • 复杂物理模拟(使用Matter.js或类似库)
  • Canvas/WebGL动画(使用Three.js或Pixi.js)
  • 视频/音频同步(使用原生Web API)

Decision Gates

决策指引

NeedUse
Simple one-shot animation
animate()
— Section 1
Timers and time control
createTimer()
— Section 2
Orchestrate multiple animations
createTimeline()
— Section 3
Real-time updates (mouse, scroll)
createAnimatable()
— Section 4
Drag-and-drop with physics
createDraggable()
— Section 5
Layout changes (FLIP technique)
createLayout()
— Section 6
Responsive animations
createScope()
— Section 7
Scroll-triggered animations
onScroll()
— Section 8
SVG morphing
morphTo
— Section 9
SVG line drawing
createDrawable
— Section 9
SVG path following
createMotionPath
— Section 9
Text character/word animation
splitText()
— Section 10
Text scramble effect
scrambleText()
— Section 10
Staggered animations
stagger()
— Section 11
Physics springs
createSpring()
— Section 12
High-performance transforms
waapi
— Section 14
Global engine configuration
engine
— Section 15

需求使用方法
简单单次动画
animate()
— 第1节
计时器与时间控制
createTimer()
— 第2节
编排多个动画
createTimeline()
— 第3节
实时更新(鼠标、滚动)
createAnimatable()
— 第4节
带物理效果的拖拽
createDraggable()
— 第5节
布局变化(FLIP技术)
createLayout()
— 第6节
响应式动画
createScope()
— 第7节
滚动触发动画
onScroll()
— 第8节
SVG变形
morphTo
— 第9节
SVG描边动画
createDrawable
— 第9节
SVG路径跟随
createMotionPath
— 第9节
文本字符/单词动画
splitText()
— 第10节
文本打乱效果
scrambleText()
— 第10节
交错动画
stagger()
— 第11节
物理弹簧效果
createSpring()
— 第12节
高性能变换
waapi
— 第14节
全局引擎配置
engine
— 第15节

Hard Rules

硬性规则

  1. Import only what you need — Use modular imports to keep bundle size small (~24KB total)
  2. Use transforms over positioning — Transform properties (x, y, scale, rotate) are GPU-accelerated
  3. Prefer timelines over nested callbacks
    createTimeline()
    is more readable than callback chains
  4. Use WAAPI for transforms/opacity only — Use JS engine for colors, scroll sync, and callbacks
  5. Clean up after yourself — Call
    revert()
    or
    cancel()
    on animations when components unmount
  6. Avoid animating layout properties — Animate
    transform
    and
    opacity
    , not
    width
    /
    height
    directly

  1. 仅导入所需模块 — 使用模块化导入以减小包体积(总大小约24KB)
  2. 优先使用变换而非定位 — 变换属性(x、y、scale、rotate)由GPU加速
  3. 优先使用时间线而非嵌套回调
    createTimeline()
    比回调链更具可读性
  4. 仅对变换/透明度使用WAAPI — 颜色、滚动同步和回调使用JS引擎
  5. 及时清理资源 — 组件卸载时调用动画的
    revert()
    cancel()
    方法
  6. 避免为布局属性添加动画 — 为
    transform
    opacity
    添加动画,而非直接动画
    width
    /
    height

Output Contract

输出约定

When this skill is invoked, return:
  • Relevant code snippets for the requested animation pattern
  • Module imports needed for the feature
  • Performance considerations if applicable
  • Cleanup recommendations

当调用本技能时,返回:
  • 对应动画模式的相关代码片段
  • 功能所需的模块导入语句
  • 性能注意事项(如适用)
  • 清理建议

Installation

安装

bash
npm install animejs
js
// ES Modules (bundler: Vite, esbuild, etc.)
import { animate, createTimeline, stagger } from 'animejs';

// CommonJS
const { animate } = require('animejs');

// CDN — ES Module
import { animate } from 'https://esm.sh/animejs';
// or JsDelivr
import { animate } from 'https://cdn.jsdelivr.net/npm/animejs/+esm';

// CDN — UMD (script tag)
// <script src="https://cdn.jsdelivr.net/npm/animejs/dist/bundles/anime.umd.min.js"></script>
// const { animate } = anime;
bash
npm install animejs
js
// ES Modules(打包工具:Vite、esbuild等)
import { animate, createTimeline, stagger } from 'animejs';

// CommonJS
const { animate } = require('animejs');

// CDN — ES Module
import { animate } from 'https://esm.sh/animejs';
// 或JsDelivr
import { animate } from 'https://cdn.jsdelivr.net/npm/animejs/+esm';

// CDN — UMD(script标签)
// <script src="https://cdn.jsdelivr.net/npm/animejs/dist/bundles/anime.umd.min.js"></script>
// const { animate } = anime;

Available distribution files

可用的分发文件

FileType
dist/modules/index.js
ES modules entry point
dist/modules/index.cjs
CommonJS entry point
dist/bundles/anime.esm.min.js
Minified ES bundle
dist/bundles/anime.umd.min.js
Minified UMD bundle
文件类型
dist/modules/index.js
ES模块入口
dist/modules/index.cjs
CommonJS入口
dist/bundles/anime.esm.min.js
压缩后的ES包
dist/bundles/anime.umd.min.js
压缩后的UMD包

Bundle size (modular)

模块化包体积

ModuleSize
Timer5.60 KB
Animation+5.20 KB
Timeline+0.55 KB
Animatable+0.40 KB
Draggable+6.41 KB
Scroll+4.30 KB
Scope+0.22 KB
SVG0.35 KB
Stagger+0.48 KB
Spring0.52 KB
WAAPI3.50 KB
Total~24.50 KB

模块大小
Timer5.60 KB
Animation+5.20 KB
Timeline+0.55 KB
Animatable+0.40 KB
Draggable+6.41 KB
Scroll+4.30 KB
Scope+0.22 KB
SVG0.35 KB
Stagger+0.48 KB
Spring0.52 KB
WAAPI3.50 KB
总计~24.50 KB

Module imports

模块导入

Only import what you need to keep the bundle small:
js
import {
  animate,           // Main animation function
  createTimer,       // Timer without animated properties
  createTimeline,    // Animation sequencer
  createAnimatable,  // Real-time animatable properties
  createDraggable,   // Draggable elements
  createScope,       // Responsive scope
  createLayout,      // Automatic layout animations
  onScroll,          // Scroll Observer
  stagger,           // Staggering utility
  createSpring,      // Physics spring
  waapi,             // Enhanced Web Animation API
  utils,             // Math and DOM utilities

  // SVG
  morphTo,
  createDrawable,
  createMotionPath,

  // Text
  splitText,
  scrambleText,

  // Engine
  engine,
} from 'animejs';

仅导入所需模块以减小包体积:
js
import {
  animate,           // 主动画函数
  createTimer,       // 无动画属性的计时器
  createTimeline,    // 动画序列编排器
  createAnimatable,  // 实时可动画属性
  createDraggable,   // 可拖拽元素
  createScope,       // 响应式作用域
  createLayout,      // 自动布局动画
  onScroll,          // 滚动观察者
  stagger,           // 交错动画工具
  createSpring,      // 物理弹簧效果
  waapi,             // 增强版Web动画API
  utils,             // 数学与DOM工具

  // SVG相关
  morphTo,
  createDrawable,
  createMotionPath,

  // 文本相关
  splitText,
  scrambleText,

  // 引擎
  engine,
} from 'animejs';

1. animate() — Main animation function

1. animate() — 主动画函数

js
animate(targets, parameters);
js
animate(targets, parameters);

Targets

目标元素

js
// CSS Selector
animate('.box', { x: 100 });

// DOM Element
animate(document.querySelector('.box'), { x: 100 });

// NodeList / Array of elements
animate(document.querySelectorAll('.box'), { x: 100 });

// JavaScript Object
const obj = { value: 0 };
animate(obj, { value: 100, onUpdate: () => console.log(obj.value) });

// Mixed array
animate(['.box', myElement, myObject], { opacity: 0 });
js
// CSS选择器
animate('.box', { x: 100 });

// DOM元素
animate(document.querySelector('.box'), { x: 100 });

// NodeList / 元素数组
animate(document.querySelectorAll('.box'), { x: 100 });

// JavaScript对象
const obj = { value: 0 };
animate(obj, { value: 100, onUpdate: () => console.log(obj.value) });

// 混合数组
animate(['.box', myElement, myObject], { opacity: 0 });

Animatable properties

可动画属性

js
// CSS Properties
animate('.el', {
  width: '200px',
  backgroundColor: '#ff0000',
  opacity: 0.5,
  borderRadius: '50%',
});

// CSS Transforms (individual, no conflicts)
animate('.el', {
  x: 100,          // translateX
  y: 50,           // translateY
  z: 0,            // translateZ
  rotate: 90,      // rotateZ (degrees by default)
  rotateX: 45,
  rotateY: 45,
  scale: 1.5,
  scaleX: 2,
  scaleY: 0.5,
  skew: 15,
  skewX: 10,
  skewY: 10,
});

// CSS Variables
animate('.el', { '--my-color': '#ff0000' });

// HTML Attributes
animate('input[type=range]', { value: 50 });

// SVG Attributes
animate('circle', { r: 50, cx: 100, cy: 100 });

// JS Object properties
const data = { count: 0 };
animate(data, { count: 100 });
js
// CSS属性
animate('.el', {
  width: '200px',
  backgroundColor: '#ff0000',
  opacity: 0.5,
  borderRadius: '50%',
});

// CSS变换(独立设置,无冲突)
animate('.el', {
  x: 100,          // translateX
  y: 50,           // translateY
  z: 0,            // translateZ
  rotate: 90,      // rotateZ(默认单位为度)
  rotateX: 45,
  rotateY: 45,
  scale: 1.5,
  scaleX: 2,
  scaleY: 0.5,
  skew: 15,
  skewX: 10,
  skewY: 10,
});

// CSS变量
animate('.el', { '--my-color': '#ff0000' });

// HTML属性
animate('input[type=range]', { value: 50 });

// SVG属性
animate('circle', { r: 50, cx: 100, cy: 100 });

// JS对象属性
const data = { count: 0 };
animate(data, { count: 100 });

Tween value types

补间值类型

js
// Numerical
animate('.el', { x: 100 });

// With unit (automatic conversion)
animate('.el', { width: '50%' });  // converts from px
animate('.el', { x: '10rem' });

// Relative (JS only)
animate('.el', { x: '+=50' });   // add 50
animate('.el', { x: '-=50' });   // subtract 50
animate('.el', { x: '*=2' });    // multiply by 2

// Color
animate('.el', { backgroundColor: 'rgb(255, 0, 0)' });
animate('.el', { backgroundColor: '#ff0000' });
animate('.el', { backgroundColor: 'hsl(0, 100%, 50%)' });

// Color function (WAAPI)
animate('.el', { color: 'oklch(70% 0.2 120)' });

// CSS variable as value
animate('.el', { x: 'var(--offset)' });

// Function-based (per element)
animate('.el', {
  x: (el, index, total) => index * 50,
  delay: (el, index) => index * 100,
});
js
// 数值
animate('.el', { x: 100 });

// 带单位(自动转换)
animate('.el', { width: '50%' });  // 从px转换
animate('.el', { x: '10rem' });

// 相对值(仅JS)
animate('.el', { x: '+=50' });   // 增加50
animate('.el', { x: '-=50' });   // 减少50
animate('.el', { x: '*=2' });    // 乘以2

// 颜色
animate('.el', { backgroundColor: 'rgb(255, 0, 0)' });
animate('.el', { backgroundColor: '#ff0000' });
animate('.el', { backgroundColor: 'hsl(0, 100%, 50%)' });

// 颜色函数(WAAPI)
animate('.el', { color: 'oklch(70% 0.2 120)' });

// CSS变量作为值
animate('.el', { x: 'var(--offset)' });

// 基于函数的取值(按元素)
animate('.el', {
  x: (el, index, total) => index * 50,
  delay: (el, index) => index * 100,
});

Tween parameters (per property)

补间参数(按属性)

js
animate('.el', {
  x: {
    to: 200,
    from: 0,          // forced initial value
    delay: 200,
    duration: 800,
    ease: 'inOutExpo',
    composition: 'add',  // 'replace' | 'add' | 'blend'
    modifier: v => Math.round(v),
  },
});
js
animate('.el', {
  x: {
    to: 200,
    from: 0,          // 强制初始值
    delay: 200,
    duration: 800,
    ease: 'inOutExpo',
    composition: 'add',  // 'replace' | 'add' | 'blend'
    modifier: v => Math.round(v),
  },
});

Keyframes

关键帧

js
// Tween values keyframes (array of values)
animate('.el', {
  x: [0, 50, 100, 50, 0],
});

// Tween parameters keyframes
animate('.el', {
  x: [
    { to: 100, duration: 500, ease: 'outExpo' },
    { to: 0,   duration: 500, ease: 'inExpo'  },
  ],
});

// Duration-based keyframes (JS only)
animate('.el', {
  keyframes: [
    { x: 100, duration: 400 },
    { y: 50,  duration: 300 },
    { rotate: 90, duration: 500 },
  ],
});

// Percentage-based keyframes (JS only)
animate('.el', {
  keyframes: {
    '0%':   { x: 0,   opacity: 1 },
    '50%':  { x: 100, opacity: 0.5 },
    '100%': { x: 200, opacity: 1 },
  },
});
js
// 补间值关键帧(值数组)
animate('.el', {
  x: [0, 50, 100, 50, 0],
});

// 补间参数关键帧
animate('.el', {
  x: [
    { to: 100, duration: 500, ease: 'outExpo' },
    { to: 0,   duration: 500, ease: 'inExpo'  },
  ],
});

// 基于时长的关键帧(仅JS)
animate('.el', {
  keyframes: [
    { x: 100, duration: 400 },
    { y: 50,  duration: 300 },
    { rotate: 90, duration: 500 },
  ],
});

// 基于百分比的关键帧(仅JS)
animate('.el', {
  keyframes: {
    '0%':   { x: 0,   opacity: 1 },
    '50%':  { x: 100, opacity: 0.5 },
    '100%': { x: 200, opacity: 1 },
  },
});

Playback settings

播放设置

js
animate('.el', {
  x: 100,
  delay: 500,             // delay before starting (ms)
  duration: 1000,         // duration (ms)
  loop: true,             // true = infinite, number = repetitions
  loopDelay: 200,         // pause between loops (JS only)
  alternate: true,        // reverses direction on each loop
  reversed: false,        // plays in reverse
  autoplay: true,         // starts automatically
  frameRate: 60,          // max FPS (JS only)
  playbackRate: 1,        // speed (0.5 = half speed)
  playbackEase: 'linear', // global easing for the animation (JS only)
  persist: false,         // keeps styles after completion (WAAPI only)
});
js
animate('.el', {
  x: 100,
  delay: 500,             // 开始前延迟(毫秒)
  duration: 1000,         // 时长(毫秒)
  loop: true,             // true=无限循环,数字=重复次数
  loopDelay: 200,         // 循环间隔(仅JS)
  alternate: true,        // 每次循环反向播放
  reversed: false,        // 反向播放
  autoplay: true,         // 自动开始
  frameRate: 60,          // 最大帧率(仅JS)
  playbackRate: 1,        // 播放速度(0.5=半速)
  playbackEase: 'linear', // 动画全局缓动(仅JS)
  persist: false,         // 完成后保留样式(仅WAAPI)
});

Callbacks

回调函数

js
animate('.el', {
  x: 100,
  onBegin:        (anim) => console.log('started'),       // JS only
  onComplete:     (anim) => console.log('complete'),
  onBeforeUpdate: (anim) => {},                           // JS only
  onUpdate:       (anim) => console.log(anim.progress),  // JS only
  onRender:       (anim) => {},                           // JS only
  onLoop:         (anim) => {},                           // JS only
  onPause:        (anim) => {},                           // JS only
}).then((anim) => console.log('promise resolved'));
js
animate('.el', {
  x: 100,
  onBegin:        (anim) => console.log('已启动'),       // 仅JS
  onComplete:     (anim) => console.log('已完成'),
  onBeforeUpdate: (anim) => {},                           // 仅JS
  onUpdate:       (anim) => console.log(anim.progress),  // 仅JS
  onRender:       (anim) => {},                           // 仅JS
  onLoop:         (anim) => {},                           // 仅JS
  onPause:        (anim) => {},                           // 仅JS
}).then((anim) => console.log('Promise已解决'));

Animation methods

动画方法

js
const anim = animate('.el', { x: 100, autoplay: false });

anim.play();           // play
anim.pause();          // pause
anim.resume();         // resume
anim.reverse();        // reverse direction
anim.restart();        // restart from the beginning
anim.alternate();      // alternate direction
anim.complete();       // jump to end
anim.cancel();         // cancel without reverting
anim.revert();         // cancel and restore original values
anim.reset();          // reset to initial state (JS only)
anim.seek(500);        // jump to time in ms
anim.stretch(2000);    // stretch total duration (JS only)
anim.refresh();        // recompute values (JS only)
js
const anim = animate('.el', { x: 100, autoplay: false });

anim.play();           // 播放
anim.pause();          // 暂停
anim.resume();         // 恢复
anim.reverse();        // 反向
anim.restart();        // 重启
anim.alternate();      // 切换方向
anim.complete();       // 跳至结束
anim.cancel();         // 取消且不还原
anim.revert();         // 取消并还原初始值
anim.reset();          // 重置为初始状态(仅JS)
anim.seek(500);        // 跳至指定时间(毫秒)
anim.stretch(2000);    // 拉伸总时长(仅JS)
anim.refresh();        // 重新计算值(仅JS)

Animation properties

动画属性

js
anim.duration    // total duration (ms)
anim.currentTime // current time (ms)
anim.progress    // progress 0-1
anim.paused      // boolean
anim.began       // boolean
anim.completed   // boolean
anim.reversed    // boolean
anim.targets     // array of targets

js
anim.duration    // 总时长(毫秒)
anim.currentTime // 当前时间(毫秒)
anim.progress    // 进度0-1
anim.paused      // 布尔值
anim.began       // 布尔值
anim.completed   // 布尔值
anim.reversed    // 布尔值
anim.targets     // 目标元素数组

2. createTimer() — Timer

2. createTimer() — 计时器

Pure timer without animated properties, useful for orchestrating timing logic.
js
import { createTimer } from 'animejs';

const timer = createTimer({
  duration: 2000,
  loop: true,
  onUpdate: (t) => console.log(t.currentTime),
  onComplete: (t) => console.log('done'),
});
Supports the same playback settings, callbacks, and methods as
animate()
.

纯计时器,无动画属性,适用于编排时间逻辑。
js
import { createTimer } from 'animejs';

const timer = createTimer({
  duration: 2000,
  loop: true,
  onUpdate: (t) => console.log(t.currentTime),
  onComplete: (t) => console.log('完成'),
});
支持与
animate()
相同的播放设置回调函数方法

3. createTimeline() — Timeline

3. createTimeline() — 时间线

Orchestrates animation sequences with precise time control.
js
import { createTimeline } from 'animejs';

const tl = createTimeline({
  loop: true,
  defaults: { duration: 500, ease: 'outExpo' }, // defaults for all animations
});

// Add animations (chained in sequence by default)
tl.add('.box',    { x: 100 })
  .add('.circle', { y: 100 })
  .add('.text',   { opacity: 0 });
精确控制动画序列的编排。
js
import { createTimeline } from 'animejs';

const tl = createTimeline({
  loop: true,
  defaults: { duration: 500, ease: 'outExpo' }, // 所有动画的默认设置
});

// 添加动画(默认按顺序链式执行)
tl.add('.box',    { x: 100 })
  .add('.circle', { y: 100 })
  .add('.text',   { opacity: 0 });

Time positions

时间位置

js
tl.add('.el', { x: 100 })              // after the previous
  .add('.el', { y: 50 }, 500)          // absolute: at 500ms from start
  .add('.el', { scale: 2 }, '+=200')   // relative: 200ms AFTER the previous ends
  .add('.el', { rotate: 90 }, '-=100') // relative: 100ms BEFORE the previous ends
  .add('.el', { opacity: 0 }, '<')     // at the same time as the previous
  .add('.el', { opacity: 1 }, '<100')  // 100ms after the start of the previous
  .label('myLabel')                    // label at current time
  .add('.el', { x: 0 }, 'myLabel');    // position by label
js
tl.add('.el', { x: 100 })              // 在上一个动画之后
  .add('.el', { y: 50 }, 500)          // 绝对时间:从开始起500毫秒处
  .add('.el', { scale: 2 }, '+=200')   // 相对时间:上一个动画结束后200毫秒
  .add('.el', { rotate: 90 }, '-=100') // 相对时间:上一个动画结束前100毫秒
  .add('.el', { opacity: 0 }, '<')     // 与上一个动画同时开始
  .add('.el', { opacity: 1 }, '<100')  // 上一个动画开始后100毫秒
  .label('myLabel')                    // 在当前时间添加标签
  .add('.el', { x: 0 }, 'myLabel');    // 按标签位置添加

Timeline methods

时间线方法

js
tl.add(targets, params, position)  // add animation
  .set(targets, params, position)  // set values instantly
  .sync(animation, position)       // sync external animation
  .call(fn, position)              // call function at a specific time
  .label('name', position)         // add label
  .remove(targets)                 // remove animations for targets
  .init()                          // initialize without playing

// Playback (same as animate)
tl.play() .pause() .resume() .reverse()
  .restart() .alternate() .complete()
  .cancel() .revert() .reset()
  .seek(ms) .stretch(ms) .refresh()

js
tl.add(targets, params, position)  // 添加动画
  .set(targets, params, position)  // 立即设置值
  .sync(animation, position)       // 同步外部动画
  .call(fn, position)              // 在指定时间调用函数
  .label('name', position)         // 添加标签
  .remove(targets)                 // 移除目标元素的动画
  .init()                          // 初始化但不播放

// 播放控制(与animate()相同)
tl.play() .pause() .resume() .reverse()
  .restart() .alternate() .complete()
  .cancel() .revert() .reset()
  .seek(ms) .stretch(ms) .refresh()

4. createAnimatable() — Animatable

4. createAnimatable() — 可动画对象

Imperatively animate properties in real time (ideal for mouse interactions, smooth scroll, etc.).
js
import { createAnimatable } from 'animejs';

const box = createAnimatable('.box', {
  x: { duration: 500, ease: 'outSpring' },
  y: { duration: 500, ease: 'outSpring' },
  scale: { duration: 300 },
  // unit: 'px',       // default unit
  // modifier: v => v, // global modifier
});

// Setter: animates to the new value
box.x(200);
box.y(100);
box.scale(1.5);

// Getter: returns current value
console.log(box.x()); // null if not yet set

// Revert
box.revert();

实时命令式动画属性(适用于鼠标交互、平滑滚动等场景)。
js
import { createAnimatable } from 'animejs';

const box = createAnimatable('.box', {
  x: { duration: 500, ease: 'outSpring' },
  y: { duration: 500, ease: 'outSpring' },
  scale: { duration: 300 },
  // unit: 'px',       // 默认单位
  // modifier: v => v, // 全局修饰器
});

// 设置器:动画到新值
box.x(200);
box.y(100);
box.scale(1.5);

// 获取器:返回当前值
console.log(box.x()); // 未设置时返回null

// 还原
box.revert();

5. createDraggable() — Draggable

5. createDraggable() — 可拖拽对象

Makes elements draggable with spring physics and snapping.
js
import { createDraggable, createSpring } from 'animejs';

const draggable = createDraggable('.card', {
  // Axis constraints
  x: true,        // allow drag on X
  y: false,       // lock Y axis
  // x: { mapTo: anotherElement }, // map position to another element

  // Container and bounds
  container: '.wrapper',    // selector, element, 'window', or 'parent'
  containerPadding: 20,     // inner padding of the container
  containerFriction: 0.8,   // friction when dragged outside the container

  // Snap
  snap: 50,                 // number, array, or function
  // snap: [0, 100, 200, 300],
  // snap: (val) => Math.round(val / 50) * 50,

  // Release physics
  releaseEase: createSpring({ stiffness: 200, damping: 15 }),
  releaseMass: 1,
  releaseStiffness: 200,
  releaseDamping: 15,
  releaseContainerFriction: 0.85,

  // Velocity
  velocityMultiplier: 1,
  minVelocity: 0,
  maxVelocity: Infinity,
  dragSpeed: 1,
  dragThreshold: 0,   // min pixels to start dragging

  // Auto-scroll
  scrollThreshold: 20,
  scrollSpeed: 10,

  // Cursor
  cursor: 'grab',         // CSS cursor on hover
  trigger: '.handle',     // element that triggers the drag

  // Callbacks
  onGrab:        (d) => {},
  onDrag:        (d) => {},
  onUpdate:      (d) => {},
  onRelease:     (d) => {},
  onSnap:        (d) => {},
  onSettle:      (d) => {},
  onResize:      (d) => {},
  onAfterResize: (d) => {},
});

// Methods
draggable.enable();
draggable.disable();
draggable.setX(100);
draggable.setY(50);
draggable.animateInView();
draggable.scrollInView();
draggable.stop();
draggable.reset();
draggable.revert();
draggable.refresh();

为元素添加拖拽功能,支持弹簧物理和吸附效果。
js
import { createDraggable, createSpring } from 'animejs';

const draggable = createDraggable('.card', {
  // 轴约束
  x: true,        // 允许X轴拖拽
  y: false,       // 锁定Y轴
  // x: { mapTo: anotherElement }, // 将位置映射到另一个元素

  // 容器与边界
  container: '.wrapper',    // 选择器、元素、'window'或'parent'
  containerPadding: 20,     // 容器内边距
  containerFriction: 0.8,   // 拖拽出容器时的摩擦力

  // 吸附
  snap: 50,                 // 数字、数组或函数
  // snap: [0, 100, 200, 300],
  // snap: (val) => Math.round(val / 50) * 50,

  // 释放物理效果
  releaseEase: createSpring({ stiffness: 200, damping: 15 }),
  releaseMass: 1,
  releaseStiffness: 200,
  releaseDamping: 15,
  releaseContainerFriction: 0.85,

  // 速度
  velocityMultiplier: 1,
  minVelocity: 0,
  maxVelocity: Infinity,
  dragSpeed: 1,
  dragThreshold: 0,   // 触发拖拽的最小像素

  // 自动滚动
  scrollThreshold: 20,
  scrollSpeed: 10,

  // 光标
  cursor: 'grab',         //  hover时的CSS光标
  trigger: '.handle',     // 触发拖拽的元素

  // 回调函数
  onGrab:        (d) => {},
  onDrag:        (d) => {},
  onUpdate:      (d) => {},
  onRelease:     (d) => {},
  onSnap:        (d) => {},
  onSettle:      (d) => {},
  onResize:      (d) => {},
  onAfterResize: (d) => {},
});

// 方法
draggable.enable();
draggable.disable();
draggable.setX(100);
draggable.setY(50);
draggable.animateInView();
draggable.scrollInView();
draggable.stop();
draggable.reset();
draggable.revert();
draggable.refresh();

6. createLayout() — Layout Animations

6. createLayout() — 布局动画

Automatically animates layout changes using the FLIP technique (First, Last, Invert, Play).
js
import { createLayout } from 'animejs';

const layout = createLayout('.container', {
  children: true,    // animate container children
  duration: 600,
  ease: 'outExpo',
  properties: ['width', 'height', 'transform', 'opacity'],

  // Enter/exit states
  enterFrom: { opacity: 0, scale: 0.5 },
  leaveTo:   { opacity: 0, scale: 0.5 },
  swapAt:    0.5,  // swap point (0-1)
});

// Typical usage
layout.record();         // capture current positions
// ... make DOM changes ...
layout.animate();        // animate from previous position to new one

// Or combined:
layout.update(() => {
  // DOM changes here
});

layout.revert();         // revert animation
使用FLIP技术(First, Last, Invert, Play)自动为布局变化添加动画。
js
import { createLayout } from 'animejs';

const layout = createLayout('.container', {
  children: true,    // 为容器子元素添加动画
  duration: 600,
  ease: 'outExpo',
  properties: ['width', 'height', 'transform', 'opacity'],

  // 进入/退出状态
  enterFrom: { opacity: 0, scale: 0.5 },
  leaveTo:   { opacity: 0, scale: 0.5 },
  swapAt:    0.5,  // 交换点(0-1)
});

// 典型用法
layout.record();         // 记录当前位置
// ... 进行DOM变更 ...
layout.animate();        // 从之前的位置动画到新位置

// 或合并使用:
layout.update(() => {
  // 此处进行DOM变更
});

layout.revert();         // 还原动画

Using data-layout-id

使用data-layout-id

html
<!-- Elements with the same layout-id are tracked across containers -->
<div data-layout-id="card-1" class="container-a">Card</div>
<!-- After moving to the other container: -->
<div data-layout-id="card-1" class="container-b">Card</div>
html
<!-- 拥有相同layout-id的元素会在容器间被追踪 -->
<div data-layout-id="card-1" class="container-a">卡片</div>
<!-- 移动到另一个容器后: -->
<div data-layout-id="card-1" class="container-b">卡片</div>

Layout use cases

布局动画适用场景

js
// CSS display property animation
// DOM reorder animation
// Enter / Exit animations
// Modal dialog animations
// Swap parent animations (element moves between parent containers)

js
// CSS display属性动画
// DOM重排动画
// 进入/退出动画
// 模态框动画
// 跨父容器动画(元素在父容器间移动)

7. createScope() — Scope

7. createScope() — 作用域

Groups animations with shared defaults and media query support for responsive animations.
js
import { createScope } from 'animejs';

const scope = createScope({
  root: '.my-component',          // root element (selector context)
  defaults: { duration: 600, ease: 'outExpo' },
  mediaQueries: {
    mobile:   '(max-width: 768px)',
    portrait: '(orientation: portrait)',
    dark:     '(prefers-color-scheme: dark)',
  },
});

// add() re-runs whenever a media query changes
scope.add(({ matches, root }) => {
  const isMobile = matches.mobile;

  createTimeline()
    .add('.box', {
      x: isMobile ? 0 : 200,
      y: isMobile ? 100 : 0,
    });

  // Optionally return a cleanup function
  return () => {};
});

// addOnce() runs only once (does not re-run on media query change)
scope.addOnce(() => {
  animate('.logo', { opacity: 1, delay: 500 });
});

scope.revert();   // cleans up all animations in the scope
scope.refresh();  // re-runs all constructors
scope.keepTime(); // preserves time when refreshing

将动画分组,共享默认设置并支持媒体查询,实现响应式动画。
js
import { createScope } from 'animejs';

const scope = createScope({
  root: '.my-component',          // 根元素(选择器上下文)
  defaults: { duration: 600, ease: 'outExpo' },
  mediaQueries: {
    mobile:   '(max-width: 768px)',
    portrait: '(orientation: portrait)',
    dark:     '(prefers-color-scheme: dark)',
  },
});

// add()会在媒体查询变化时重新执行
scope.add(({ matches, root }) => {
  const isMobile = matches.mobile;

  createTimeline()
    .add('.box', {
      x: isMobile ? 0 : 200,
      y: isMobile ? 100 : 0,
    });

  // 可选返回清理函数
  return () => {};
});

// addOnce()仅执行一次(媒体查询变化时不重新执行)
scope.addOnce(() => {
  animate('.logo', { opacity: 1, delay: 500 });
});

scope.revert();   // 清理作用域内的所有动画
scope.refresh();  // 重新执行所有构造函数
scope.keepTime(); // 刷新时保留时间

8. onScroll() — Scroll Observer

8. onScroll() — 滚动观察者

Synchronizes and triggers animations based on scroll position.
js
import { animate, onScroll } from 'animejs';

// As the autoplay value of an animation
animate('.el', {
  x: 200,
  autoplay: onScroll(),
});

// Full configuration
animate('.section', {
  opacity: [0, 1],
  autoplay: onScroll({
    container: window,        // scroll container
    target: '.section',       // observed element (defaults to animation target)
    axis: 'y',                // 'x' | 'y'
    debug: false,             // shows visual markers

    // Thresholds: when the element enters/leaves
    // Shorthand: 'top bottom' = when top of element hits bottom of viewport
    enter: 'bottom top',      // enters when scrolling down
    leave: 'top bottom',      // leaves when scrolling

    // Numeric values (0-1 relative to viewport)
    enter: 0.5,               // at the viewport midpoint
    // Relative values
    enter: '50% 100%',        // 50% of the element at 100% of the container

    repeat: true,             // repeats the animation each time

    // Synchronisation modes
    sync: true,               // syncs progress with scroll
    sync: 'play',             // calls play() on enter
    sync: 'restart',          // calls restart() on enter
    sync: 'resume',           // calls resume() on enter

    // Callbacks
    onEnter:         (obs) => {},
    onEnterForward:  (obs) => {},
    onEnterBackward: (obs) => {},
    onLeave:         (obs) => {},
    onLeaveForward:  (obs) => {},
    onLeaveBackward: (obs) => {},
    onUpdate:        (obs) => {},
    onSyncComplete:  (obs) => {},
    onResize:        (obs) => {},
  }),
});
根据滚动位置同步并触发动画。
js
import { animate, onScroll } from 'animejs';

// 作为动画的autoplay值
animate('.el', {
  x: 200,
  autoplay: onScroll(),
});

// 完整配置
animate('.section', {
  opacity: [0, 1],
  autoplay: onScroll({
    container: window,        // 滚动容器
    target: '.section',       // 观察元素(默认是动画目标)
    axis: 'y',                // 'x' | 'y'
    debug: false,             // 显示视觉标记

    // 阈值:元素进入/离开的条件
    // 简写:'top bottom' = 元素顶部碰到视口底部时
    enter: 'bottom top',      // 向下滚动时进入
    leave: 'top bottom',      // 滚动时离开

    // 数值(0-1,相对于视口)
    enter: 0.5,               // 在视口中点
    // 相对值
    enter: '50% 100%',        // 元素50%进入容器100%位置

    repeat: true,             // 每次进入都重复动画

    // 同步模式
    sync: true,               // 进度与滚动同步
    sync: 'play',             // 进入时调用play()
    sync: 'restart',          // 进入时调用restart()
    sync: 'resume',           // 进入时调用resume()

    // 回调函数
    onEnter:         (obs) => {},
    onEnterForward:  (obs) => {},
    onEnterBackward: (obs) => {},
    onLeave:         (obs) => {},
    onLeaveForward:  (obs) => {},
    onLeaveBackward: (obs) => {},
    onUpdate:        (obs) => {},
    onSyncComplete:  (obs) => {},
    onResize:        (obs) => {},
  }),
});

ScrollObserver methods

ScrollObserver方法

js
const obs = onScroll({ target: '.el' });
obs.link(anim);    // link an animation
obs.refresh();     // recompute thresholds
obs.revert();      // destroy the observer

js
const obs = onScroll({ target: '.el' });
obs.link(anim);    // 关联动画
obs.refresh();     // 重新计算阈值
obs.revert();      // 销毁观察者

9. SVG — Utilities

9. SVG — 工具

js
import { animate, morphTo, createDrawable, createMotionPath } from 'animejs';

// morphTo — SVG shape morphing
animate('#shape-a', {
  d: morphTo('#shape-b'),         // morph to another element's path
  duration: 1000,
  ease: 'inOutQuad',
});

// createDrawable — SVG line drawing animation
const drawable = createDrawable('path');
animate(drawable, {
  draw: '0 1',       // from start to end of stroke
  // draw: ['0 0', '0 1', '1 1'],  // keyframes
  duration: 1500,
  ease: 'inOutSine',
});
// draw: [start, end] where start and end are 0-1

// createMotionPath — Follow an SVG path
animate('.car', {
  ...createMotionPath('.road'),   // spreads x, y, rotate properties
  duration: 3000,
  ease: 'linear',
});

js
import { animate, morphTo, createDrawable, createMotionPath } from 'animejs';

// morphTo — SVG形状变形
animate('#shape-a', {
  d: morphTo('#shape-b'),         // 变形为另一个元素的路径
  duration: 1000,
  ease: 'inOutQuad',
});

// createDrawable — SVG描边动画
const drawable = createDrawable('path');
animate(drawable, {
  draw: '0 1',       // 从描边起点到终点
  // draw: ['0 0', '0 1', '1 1'],  // 关键帧
  duration: 1500,
  ease: 'inOutSine',
});
// draw: [start, end] 其中start和end为0-1

// createMotionPath — 跟随SVG路径
animate('.car', {
  ...createMotionPath('.road'),   // 展开x、y、rotate属性
  duration: 3000,
  ease: 'linear',
});

10. Text — Text utilities

10. Text — 文本工具

splitText()

splitText()

Splits text into lines, words, and/or characters to animate them individually.
js
import { splitText, animate, stagger } from 'animejs';

const splitter = splitText('.heading', {
  lines: true,
  words: true,
  chars: true,
  includeSpaces: false,
  debug: false,
  accessible: true, // aria-hidden on spans, aria-label on parent
});

// Animate characters
animate(splitter.chars, {
  opacity: [0, 1],
  y: [20, 0],
  delay: stagger(30),
  duration: 600,
  ease: 'outExpo',
});

// Animate words
animate(splitter.words, {
  scale: [0.8, 1],
  delay: stagger(50),
});

// Available properties
splitter.lines   // array of line elements
splitter.words   // array of word elements
splitter.chars   // array of character elements

// Methods
splitter.addEffect((el) => {
  // custom effect logic
});
splitter.refresh();  // recompute after resize
splitter.revert();   // restore original HTML
将文本拆分为行、单词和/或字符,以便单独为其添加动画。
js
import { splitText, animate, stagger } from 'animejs';

const splitter = splitText('.heading', {
  lines: true,
  words: true,
  chars: true,
  includeSpaces: false,
  debug: false,
  accessible: true, // 为span添加aria-hidden,为父元素添加aria-label
});

// 为字符添加动画
animate(splitter.chars, {
  opacity: [0, 1],
  y: [20, 0],
  delay: stagger(30),
  duration: 600,
  ease: 'outExpo',
});

// 为单词添加动画
animate(splitter.words, {
  scale: [0.8, 1],
  delay: stagger(50),
});

// 可用属性
splitter.lines   // 行元素数组
splitter.words   // 单词元素数组
splitter.chars   // 字符元素数组

// 方法
splitter.addEffect((el) => {
  // 自定义效果逻辑
});
splitter.refresh();  // 调整后重新计算
splitter.revert();   // 恢复原始HTML

Split parameters

拆分参数

js
splitText('.el', {
  lines: { class: 'my-line', wrap: '.wrapper', clone: false },
  words: { class: 'my-word' },
  chars: { class: 'my-char' },
});
js
splitText('.el', {
  lines: { class: 'my-line', wrap: '.wrapper', clone: false },
  words: { class: 'my-word' },
  chars: { class: 'my-char' },
});

scrambleText() (NEW)

scrambleText()(新增)

Scramble effect that randomly shuffles characters while revealing the target text.
js
import { animate, scrambleText } from 'animejs';

animate('.heading', {
  ...scrambleText({
    text: 'New text',                    // destination text
    chars: 'abcdefghijklmnopqrstuvwxyz', // scramble character set
    override: false,                     // overwrite current text
    ease: 'linear',
    cursor: true,                        // show cursor at the end
    revealRate: 0.5,
    revealDelay: 0,
    settleRate: 0.5,
    settleDuration: 1000,
    delay: 0,
    duration: 1000,
    perturbation: 1,
    from: 'start',                       // 'start' | 'end' | 'center' | number
    reversed: false,
    seed: 0,
    onChange: (val, target) => {},
  }),
});

打乱效果:在显示目标文本时随机打乱字符。
js
import { animate, scrambleText } from 'animejs';

animate('.heading', {
  ...scrambleText({
    text: 'New text',                    // 目标文本
    chars: 'abcdefghijklmnopqrstuvwxyz', // 打乱字符集
    override: false,                     // 是否覆盖当前文本
    ease: 'linear',
    cursor: true,                        // 在末尾显示光标
    revealRate: 0.5,
    revealDelay: 0,
    settleRate: 0.5,
    settleDuration: 1000,
    delay: 0,
    duration: 1000,
    perturbation: 1,
    from: 'start',                       // 'start' | 'end' | 'center' | 数字
    reversed: false,
    seed: 0,
    onChange: (val, target) => {},
  }),
});

11. stagger() — Staggering

11. stagger() — 交错动画

Creates staggered delays or values across multiple elements.
js
import { animate, stagger } from 'animejs';

// Time staggering (delay per index)
animate('.dots', {
  y: -20,
  delay: stagger(100),                     // 0, 100, 200, 300...
  delay: stagger(100, { start: 200 }),     // 200, 300, 400...
  delay: stagger(100, { from: 'center' }), // from the center outward
  delay: stagger(100, { from: 2 }),        // from index 2
  delay: stagger(100, { reversed: true }), // reversed
  delay: stagger(100, { ease: 'inOutQuad' }), // with easing
});

// Value staggering (range between first and last element)
animate('.dots', {
  scale: stagger([0.5, 1.5]),       // from 0.5 to 1.5
  x: stagger(['-100px', '100px']),
});

// 2D Grid staggering
animate('.grid-item', {
  scale: stagger(0.1, {
    grid: [10, 10],       // columns x rows
    from: 'center',       // origin point
    axis: 'x',            // 'x' | 'y' | undefined (diagonal)
  }),
});

// Timeline staggering (time positions)
createTimeline()
  .add('.el', { y: -10 }, stagger(50));  // each element offset by +50ms

// Full parameters
stagger(value, {
  start: 0,         // start value or time
  from: 'first',    // 'first'|'center'|'last'|'edges'|index|[col,row]
  reversed: false,
  ease: 'linear',
  grid: [cols, rows],
  axis: 'x',        // 'x'|'y'
  modifier: (v) => v,
  use: 'delay',     // property to stagger
  total: undefined, // forced total element count
});

为多个元素创建交错延迟或值。
js
import { animate, stagger } from 'animejs';

// 时间交错(按索引延迟)
animate('.dots', {
  y: -20,
  delay: stagger(100),                     // 0, 100, 200, 300...
  delay: stagger(100, { start: 200 }),     // 200, 300, 400...
  delay: stagger(100, { from: 'center' }), // 从中心向外
  delay: stagger(100, { from: 2 }),        // 从索引2开始
  delay: stagger(100, { reversed: true }), // 反向
  delay: stagger(100, { ease: 'inOutQuad' }), // 带缓动
});

// 值交错(第一个到最后一个元素的范围)
animate('.dots', {
  scale: stagger([0.5, 1.5]),       // 从0.5到1.5
  x: stagger(['-100px', '100px']),
});

// 2D网格交错
animate('.grid-item', {
  scale: stagger(0.1, {
    grid: [10, 10],       // 列数 x 行数
    from: 'center',       // 起始点
    axis: 'x',            // 'x' | 'y' | undefined(对角线)
  }),
});

// 时间线交错(时间位置)
createTimeline()
  .add('.el', { y: -10 }, stagger(50));  // 每个元素偏移+50毫秒

// 完整参数
stagger(value, {
  start: 0,         // 起始值或时间
  from: 'first',    // 'first'|'center'|'last'|'edges'|索引|[列,行]
  reversed: false,
  ease: 'linear',
  grid: [cols, rows],
  axis: 'x',        // 'x'|'y'
  modifier: (v) => v,
  use: 'delay',     // 要交错的属性
  total: undefined, // 强制元素总数
});

12. Easings — Easing functions

12. Easings — 缓动函数

Built-in eases

内置缓动

js
// Syntax: 'type(exponent)'
'linear'
'ease'          // CSS alias

// In / Out / InOut — 3 forms:
'in(n)'         // inSine ~ in(1.675)
'out(n)'
'inOut(n)'

// Predefined aliases (shortcuts)
'inSine'    'outSine'    'inOutSine'
'inQuad'    'outQuad'    'inOutQuad'
'inCubic'   'outCubic'   'inOutCubic'
'inQuart'   'outQuart'   'inOutQuart'
'inQuint'   'outQuint'   'inOutQuint'
'inExpo'    'outExpo'    'inOutExpo'
'inCirc'    'outCirc'    'inOutCirc'
'inBack'    'outBack'    'inOutBack'
'inBounce'  'outBounce'  'inOutBounce'
'inElastic' 'outElastic' 'inOutElastic'
js
// 语法:'type(exponent)'
'linear'
'ease'          // CSS别名

// In / Out / InOut — 三种形式:
'in(n)'         // inSine ~ in(1.675)
'out(n)'
'inOut(n)'

// 预定义别名(快捷方式)
'inSine'    'outSine'    'inOutSine'
'inQuad'    'outQuad'    'inOutQuad'
'inCubic'   'outCubic'   'inOutCubic'
'inQuart'   'outQuart'   'inOutQuart'
'inQuint'   'outQuint'   'inOutQuint'
'inExpo'    'outExpo'    'inOutExpo'
'inCirc'    'outCirc'    'inOutCirc'
'inBack'    'outBack'    'inOutBack'
'inBounce'  'outBounce'  'inOutBounce'
'inElastic' 'outElastic' 'inOutElastic'

Cubic Bezier

三次贝塞尔曲线

js
// cubicBezier(x1, y1, x2, y2)
ease: 'cubicBezier(0.25, 0.1, 0.25, 1.0)'
// or using createCubicBezier:
import { createCubicBezier } from 'animejs';
ease: createCubicBezier(0.25, 0.1, 0.25, 1.0)
js
// cubicBezier(x1, y1, x2, y2)
ease: 'cubicBezier(0.25, 0.1, 0.25, 1.0)'
// 或使用createCubicBezier:
import { createCubicBezier } from 'animejs';
ease: createCubicBezier(0.25, 0.1, 0.25, 1.0)

Linear (multi-point)

线性(多点)

js
// linear([p1, p2, p3, ...]) — values between 0 and 1
ease: 'linear(0, 0.5, 1)'
ease: 'linear(0, 0.2 25%, 0.8 75%, 1)'
js
// linear([p1, p2, p3, ...]) — 值在0和1之间
ease: 'linear(0, 0.5, 1)'
ease: 'linear(0, 0.2 25%, 0.8 75%, 1)'

Steps

阶梯函数

js
// steps(n, direction)
ease: 'steps(5)'
ease: 'steps(5, start)'  // 'start'|'end'|'both'|'none'
js
// steps(n, direction)
ease: 'steps(5)'
ease: 'steps(5, start)'  // 'start'|'end'|'both'|'none'

Irregular (Custom)

不规则(自定义)

js
import { createIrregular } from 'animejs';
ease: createIrregular(/* seed, amplitude, frequency */);
js
import { createIrregular } from 'animejs';
ease: createIrregular(/* seed, amplitude, frequency */);

Spring

弹簧

js
import { createSpring } from 'animejs';

ease: createSpring({
  mass:      1,      // object mass
  stiffness: 100,    // spring stiffness
  damping:   10,     // damping coefficient
  velocity:  0,      // initial velocity
});

// or shorthand string
ease: 'spring(mass, stiffness, damping, velocity)'
ease: 'spring(1, 100, 10, 0)'

// outSpring (damped, comes to rest)
ease: 'outSpring'
ease: 'outSpring(stiffness, damping)'

js
import { createSpring } from 'animejs';

ease: createSpring({
  mass:      1,      // 对象质量
  stiffness: 100,    // 弹簧刚度
  damping:   10,     // 阻尼系数
  velocity:  0,      // 初始速度
});

// 或简写字符串
ease: 'spring(mass, stiffness, damping, velocity)'
ease: 'spring(1, 100, 10, 0)'

// outSpring(阻尼,最终静止)
ease: 'outSpring'
ease: 'outSpring(stiffness, damping)'

13. Utilities

13. Utilities — 工具函数

js
import {
  $, get, set, cleanInlineStyles, remove, sync, keepTime,
  random, createSeededRandom, randomPick, shuffle,
  round, clamp, snap, wrap, mapRange, lerp, damp,
  roundPad, padStart, padEnd, degToRad, radToDeg,
  utils,
} from 'animejs';

// DOM
$('.selector')                // querySelectorAll -> array
get(target, 'x')              // get the current value of a property
set(target, { x: 100 })       // set value instantly
cleanInlineStyles(target)     // remove inline styles left by animations
remove(target)                // remove target from all active animations
sync(fn)                      // run fn on the next engine frame
keepTime(timer)               // preserve timer time on revert

// Numbers
random(0, 100)                // random number between min and max
random(0, 100, 2)             // with decimal places
createSeededRandom(seed)      // reproducible random generator -> fn()
randomPick([a, b, c])         // pick a random element from an array
shuffle([1, 2, 3, 4])         // shuffle array in place (mutates)

round(3.1415, 2)              // -> 3.14
clamp(value, min, max)        // clamp value to range
snap(value, increment)        // round to nearest increment
snap(value, [0,50,100])       // round to nearest value in array
wrap(value, min, max)         // wrap value within range (modulo)
mapRange(value, inMin, inMax, outMin, outMax)  // remap a value between ranges
lerp(a, b, t)                 // linear interpolation
damp(current, target, lambda, dt)  // smooth damp (frame-rate independent)

roundPad(value, decimals)     // round with trailing zeros: 1.5 -> "1.50"
padStart(str, length, char)   // pad left
padEnd(str, length, char)     // pad right

degToRad(180)                 // -> Math.PI
radToDeg(Math.PI)             // -> 180

// Chain-able utilities
utils(value)
  .round(2)
  .clamp(0, 100)
  .mapRange(0, 100, 0, 1)
  .get()  // get final value

js
import {
  $, get, set, cleanInlineStyles, remove, sync, keepTime,
  random, createSeededRandom, randomPick, shuffle,
  round, clamp, snap, wrap, mapRange, lerp, damp,
  roundPad, padStart, padEnd, degToRad, radToDeg,
  utils,
} from 'animejs';

// DOM相关
$('.selector')                // querySelectorAll -> 数组
get(target, 'x')              // 获取属性当前值
set(target, { x: 100 })       // 立即设置值
cleanInlineStyles(target)     // 移除动画留下的内联样式
remove(target)                // 从所有活跃动画中移除目标元素
sync(fn)                      // 在下一引擎帧运行fn
keepTime(timer)               // 还原时保留计时器时间

// 数字相关
random(0, 100)                // 0到100之间的随机数
random(0, 100, 2)             // 指定小数位数
createSeededRandom(seed)      // 可复现的随机生成器 -> fn()
randomPick([a, b, c])         // 从数组中随机选取元素
shuffle([1, 2, 3, 4])         // 原地打乱数组(会修改原数组)

round(3.1415, 2)              // -> 3.14
clamp(value, min, max)        // 将值限制在范围内
snap(value, increment)        // 四舍五入到指定增量
snap(value, [0,50,100])       // 四舍五入到数组中的最近值
wrap(value, min, max)         // 将值包裹在范围内(取模)
mapRange(value, inMin, inMax, outMin, outMax)  // 将值在两个范围间映射
lerp(a, b, t)                 // 线性插值
damp(current, target, lambda, dt)  // 平滑阻尼(帧率无关)

roundPad(value, decimals)     // 四舍五入并补零:1.5 -> "1.50"
padStart(str, length, char)   // 左侧补全
padEnd(str, length, char)     // 右侧补全

degToRad(180)                 // -> Math.PI
radToDeg(Math.PI)             // -> 180

// 链式工具函数
utils(value)
  .round(2)
  .clamp(0, 100)
  .mapRange(0, 100, 0, 1)
  .get()  // 获取最终值

14. WAAPI — Enhanced Web Animation API

14. WAAPI — 增强版Web动画API

Uses browser hardware acceleration for transforms and opacity.
js
import { waapi } from 'animejs';

// waapi.animate() — same API as animate() but uses WAAPI internally
waapi.animate('.box', {
  x: 200,
  opacity: 0,
  duration: 1000,
  ease: 'outExpo',
});

// Improvements over native WAAPI:
// - Sensible defaults
// - Multi-target support
// - Automatic units (no explicit 'px' needed)
// - Function-based values
// - Individual CSS transforms (x, y, rotate, scale...)
// - Per-property parameters
// - Spring and custom easings

// API differences vs native WAAPI:
// loop        -> iterations
// alternate   -> direction: 'alternate'
// ease        -> easing
// .then()     -> .finished

// Convert anime.js easing to WAAPI format
const easing = waapi.convertEase('outElastic(1, .5)');
// -> CustomEffect function for use in native WAAPI
使用浏览器硬件加速处理变换和透明度。
js
import { waapi } from 'animejs';

// waapi.animate() — 与animate()API相同,但内部使用WAAPI
waapi.animate('.box', {
  x: 200,
  opacity: 0,
  duration: 1000,
  ease: 'outExpo',
});

// 相比原生WAAPI的改进:
// - 合理的默认值
// - 多目标支持
// - 自动单位(无需显式'px')
// - 基于函数的取值
// - 独立CSS变换(x、y、rotate、scale...)
// 按属性设置参数
// - 弹簧和自定义缓动

// 与原生WAAPI的API差异:
// loop        -> iterations
// alternate   -> direction: 'alternate'
// ease        -> easing
// .then()     -> .finished

// 将anime.js缓动转换为WAAPI格式
const easing = waapi.convertEase('outElastic(1, .5)');
// -> 用于原生WAAPI的CustomEffect函数

When to use WAAPI vs JS engine

何时使用WAAPI vs JS引擎

Use WAAPI when...Use JS engine when...
Only transforms and opacityColor animations
Maximum performance mattersJS objects / custom properties
You don't need JS callbacksYou need precise onUpdate
GPU-accelerated propertiesLayout / scroll sync

使用WAAPI的场景使用JS引擎的场景
仅处理变换和透明度颜色动画
追求极致性能JS对象/自定义属性
不需要JS回调需要精确的onUpdate
GPU加速属性布局/滚动同步

15. Engine — Global engine

15. Engine — 全局引擎

js
import { engine } from 'animejs';

// Parameters (configure the global engine)
engine.timeUnit = 'ms';              // 'ms' | 's' — time unit (ms by default)
engine.speed = 1;                    // global speed multiplier
engine.fps = 60;                     // global max FPS
engine.precision = 4;                // decimal precision
engine.pauseOnDocumentHidden = true; // pause when the tab is hidden

// Methods
engine.update();   // manually advance the engine (manual mode)
engine.pause();    // pause all timers/animations
engine.resume();   // resume the engine

// Properties
engine.currentTime   // current engine time
engine.paused        // boolean

// Defaults — global default values
engine.defaults.duration = 400;
engine.defaults.ease = 'outQuad';
// ... any animation/playback parameter

js
import { engine } from 'animejs';

// 参数(配置全局引擎)
engine.timeUnit = 'ms';              // 'ms' | 's' — 时间单位(默认ms)
engine.speed = 1;                    // 全局速度乘数
engine.fps = 60;                     // 全局最大帧率
engine.precision = 4;                // 小数精度
engine.pauseOnDocumentHidden = true; // 标签页隐藏时暂停

// 方法
engine.update();   // 手动推进引擎(手动模式)
engine.pause();    // 暂停所有计时器/动画
engine.resume();   // 恢复引擎

// 属性
engine.currentTime   // 当前引擎时间
engine.paused        // 布尔值

// 默认值 — 全局默认参数
engine.defaults.duration = 400;
engine.defaults.ease = 'outQuad';
// ... 任何动画/播放参数

Common usage patterns

常见使用模式

Basic animation

基础动画

js
import { animate } from 'animejs';

animate('.box', {
  x: 250,
  duration: 800,
  ease: 'inOutExpo',
  loop: true,
  alternate: true,
});
js
import { animate } from 'animejs';

animate('.box', {
  x: 250,
  duration: 800,
  ease: 'inOutExpo',
  loop: true,
  alternate: true,
});

Timeline sequence

时间线序列

js
import { createTimeline, stagger } from 'animejs';

createTimeline({ loop: true })
  .add('.logo',  { opacity: [0,1], y: [-20,0], duration: 600 })
  .add('.title', { opacity: [0,1], x: [-30,0], delay: stagger(50) })
  .add('.cta',   { scale: [0.8,1], opacity: [0,1] }, '-=200');
js
import { createTimeline, stagger } from 'animejs';

createTimeline({ loop: true })
  .add('.logo',  { opacity: [0,1], y: [-20,0], duration: 600 })
  .add('.title', { opacity: [0,1], x: [-30,0], delay: stagger(50) })
  .add('.cta',   { scale: [0.8,1], opacity: [0,1] }, '-=200');

Scroll-synced animation

滚动同步动画

js
import { animate, onScroll } from 'animejs';

animate('.parallax', {
  y: ['-20%', '20%'],
  ease: 'linear',
  autoplay: onScroll({ sync: true }),
});
js
import { animate, onScroll } from 'animejs';

animate('.parallax', {
  y: ['-20%', '20%'],
  ease: 'linear',
  autoplay: onScroll({ sync: true }),
});

Text animation

文本动画

js
import { splitText, animate, stagger } from 'animejs';

const { chars } = splitText('.hero-title', { chars: true });

animate(chars, {
  opacity: [0, 1],
  y: [30, 0],
  rotateX: [-90, 0],
  delay: stagger(40, { from: 'center' }),
  duration: 700,
  ease: 'outBack',
});
js
import { splitText, animate, stagger } from 'animejs';

const { chars } = splitText('.hero-title', { chars: true });

animate(chars, {
  opacity: [0, 1],
  y: [30, 0],
  rotateX: [-90, 0],
  delay: stagger(40, { from: 'center' }),
  duration: 700,
  ease: 'outBack',
});

SVG line drawing on scroll

滚动触发SVG描边动画

js
import { animate, createDrawable, onScroll, stagger } from 'animejs';

animate(createDrawable('path'), {
  draw: ['0 0', '0 1'],
  delay: stagger(40),
  ease: 'inOut(3)',
  autoplay: onScroll({ sync: true }),
});
js
import { animate, createDrawable, onScroll, stagger } from 'animejs';

animate(createDrawable('path'), {
  draw: ['0 0', '0 1'],
  delay: stagger(40),
  ease: 'inOut(3)',
  autoplay: onScroll({ sync: true }),
});

Draggable with spring

带弹簧效果的拖拽

js
import { createDraggable, createSpring } from 'animejs';

createDraggable('.card', {
  container: '.board',
  snap: 100,
  releaseEase: createSpring({ stiffness: 200, damping: 20 }),
});
js
import { createDraggable, createSpring } from 'animejs';

createDraggable('.card', {
  container: '.board',
  snap: 100,
  releaseEase: createSpring({ stiffness: 200, damping: 20 }),
});

Responsive scope

响应式作用域

js
import { createScope, createTimeline, stagger } from 'animejs';

createScope({
  mediaQueries: { mobile: '(max-width: 768px)' },
}).add(({ matches }) => {
  createTimeline()
    .add('.nav-item', {
      x: matches.mobile ? ['-100%', 0] : [0, 0],
      y: matches.mobile ? 0 : [-20, 0],
      delay: stagger(60),
    });
});
js
import { createScope, createTimeline, stagger } from 'animejs';

createScope({
  mediaQueries: { mobile: '(max-width: 768px)' },
}).add(({ matches }) => {
  createTimeline()
    .add('.nav-item', {
      x: matches.mobile ? ['-100%', 0] : [0, 0],
      y: matches.mobile ? 0 : [-20, 0],
      delay: stagger(60),
    });
});

2D grid stagger

2D网格交错

js
import { animate, stagger } from 'animejs';

animate('.cell', {
  scale: [0, 1],
  delay: stagger(50, {
    grid: [10, 10],
    from: 'center',
  }),
  duration: 600,
  ease: 'outBack',
});
js
import { animate, stagger } from 'animejs';

animate('.cell', {
  scale: [0, 1],
  delay: stagger(50, {
    grid: [10, 10],
    from: 'center',
  }),
  duration: 600,
  ease: 'outBack',
});

Animatable for mouse tracking

鼠标追踪的可动画对象

js
import { createAnimatable } from 'animejs';

const blob = createAnimatable('.blob', {
  x: { duration: 800, ease: 'outExpo' },
  y: { duration: 800, ease: 'outExpo' },
});

document.addEventListener('mousemove', (e) => {
  blob.x(e.clientX - 50);
  blob.y(e.clientY - 50);
});

js
import { createAnimatable } from 'animejs';

const blob = createAnimatable('.blob', {
  x: { duration: 800, ease: 'outExpo' },
  y: { duration: 800, ease: 'outExpo' },
});

document.addEventListener('mousemove', (e) => {
  blob.x(e.clientX - 50);
  blob.y(e.clientY - 50);
});

Quick reference: tween composition

快速参考:补间合成

ValueBehaviour
'replace'
(default)
Replaces the current animation
'add'
Adds to the current value (accumulates)
'blend'
Smoothly blends with the current animation
js
// Blend composition for interactive transforms
animate('.el', {
  x: mouseX,
  composition: 'blend',
});
行为
'replace'
(默认)
替换当前动画
'add'
叠加到当前值(累积)
'blend'
与当前动画平滑混合
js
// 交互式变换使用混合合成
animate('.el', {
  x: mouseX,
  composition: 'blend',
});

See also

相关链接

  • react-19 — React animations with Anime.js
  • frontend-design — UI animations and micro-interactions
  • javascript — Using Anime.js with vanilla JavaScript

  • react-19 — 使用Anime.js实现React动画
  • frontend-design — UI动画与微交互
  • javascript — 在原生JavaScript中使用Anime.js

References

参考资源