前端开发
需要框架无关的 DOM/CSS/SVG/JS 对象时间线…
在 Vanilla JS 或任意前端框架中需要轻量时间线、stagger、SVG 路径动画、关键帧编排时使用 Anime.js。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
需要框架无关的 DOM/CSS/SVG/通用
解决思路
- 用 `anime({ ... })` 创建基础动画:传入对象,设置 `targets` 为目标,设置 `translateX: 250`、`rotate: '1turn'`、`duration: 800`、`easing: 'easeInOutQuad'` 等属性。
- 指定 `targets` 可用 CSS 选择器 `'.box'`;用 `document.querySelectorAll('.box')` 返回 DOM 元素;用元素数组 `[el1, el2, el3]`;或用 JavaScript 对象 `const obj = { x: 0 }` 并设置 `targets: obj`。
- 动画 CSS 属性时直接传入属性名:`translateX: 250`、`scale: 2`、`opacity: 0.5`、`backgroundColor: '#FFF'`。
- 动画 CSS transform 时使用独立 transform 属性:`translateX: 250`、`rotate: '1turn'`、`scale: 2`,不要动画 `transform: 'rotate()'` 字符串。
- 动画 SVG 属性时设置 `d: 'M10 80 Q 77.5 10, 145 80'` 做路径变形;设置 `fill: '#FF0000'`;设置 `strokeDashoffset: [anime.setDashoffset, 0]` 做线条绘制。
- 动画 JavaScript 对象时设置 `targets: obj` 和 `value: 100`,可加 `round: 1`,在 `update: () => console.log(obj.value)` 回调中读取变化值。
- 用 `anime.timeline({ duration: 750, easing: 'easeOutExpo' })` 创建时间线,再用 `.add({ targets: '.box1', translateX: 250 })` 逐个添加动画。
- 时间线定位用相对偏移:第二个 `.add(..., '-=500')` 表示比前一个动画结束提前 500ms 开始;`.add(..., '+=200')` 表示比前一个动画结束后 200ms 开始。
- 做 stagger 顺序揭示:设置 `translateY: [100, 0]`、`opacity: [0, 1]`、`delay: anime.stagger(100)`、`easing: 'easeOutQuad'`、`duration: 600`。
- 做从中心 stagger:设置 `scale: [0, 1]`,`delay: anime.stagger(50, { grid: [14, 5], from: 'center', axis: 'x' })`;`from` 还可用 `'first'`、`'last'`、索引、`[x, y]`;`axis` 还可用 `'y'` 或 `null`。
- 做 SVG 线条绘制:设置 `targets: 'path'`,`strokeDashoffset: [anime.setDashoffset, 0]`,`easing: 'easeInOutQuad'`,`duration: 2000`,`delay: (el, i) => i * 250`。
- 做 SVG morphing:设置 `targets: '#morphing-path'`,`d: [{ value: 'M10 80 Q 77.5 10, 145 80' }, { value: 'M10 80 Q 77.5 150, 145 80' }]`,`duration: 2000`,`easing: 'easeInOutQuad'`,`loop: true`,`direction: 'alternate'`。
- 编排时间线序列:创建 `const tl = anime.timeline({ easing: 'easeOutExpo', duration: 750 })`,依次 `.add({ targets: '.title', translateY: [-50, 0], opacity: [0, 1] })`、`.add({ targets: '.subtitle', translateY: [-30, 0], opacity: [0, 1] }, '-=500')`、`.add({ targets: '.button', scale: [0, 1], opacity: [0, 1] }, '-=300')`。
- 做关键帧动画:设置 `keyframes: [{ translateX: 100 }, { translateY: 100 }, { translateX: 0 }, { translateY: 0 }]`,`duration: 4000`,`easing: 'easeInOutQuad'`,`loop: true`。
- 做滚动触发动画:创建 `const animation = anime({ targets: '.scroll-element', translateY: [100, 0], opacity: [0, 1], easing: 'easeOutQuad', autoplay: false })`;监听 `scroll`,计算 `const scrollPercent = window.scrollY / (document.body.scrollHeight - window.innerHeight)`,调用 `animation.seek(animation.duration * scrollPercent)`。
- 在 React 中集成:用 `useRef` 保存元素引用,在 `useEffect` 中执行 `const animation = anime({ targets: ref.current, translateX: 250, duration: 800, easing: 'easeInOutQuad' })`,并返回 `() => animation.pause()` 清理;元素上绑定 `ref={ref}`。
- 在 Vue 中集成:在 `mounted()` 中调用 `anime({ targets: this.$el, translateX: 250, duration: 800 })`。
- 做路径跟随动画:用 `const path = anime.path('#motion-path')` 获取路径,再动画 `translateX: path('x')`、`translateY: path('y')`、`rotate: path('angle')`,设置 `easing: 'linear'`、`duration: 2000`、`loop: true`。
- 用 spring easing:设置 `easing: 'spring(1, 80, 10, 0)'`(依次为 mass、stiffness、damping、velocity),`duration: 2000`。
- 用 steps easing:设置 `easing: 'steps(5)'`,`duration: 1000`。
- 用自定义贝塞尔:设置 `easing: 'cubicBezier(.5, .05, .1, .3)'`,`duration: 1000`。
- 控制方向和循环:设置 `direction: 'alternate'`(可为 `'normal'`、`'reverse'`、`'alternate'`),设置 `loop: true` 或循环次数,配合 `easing: 'easeInOutQuad'`。
- 控制播放:创建动画时设置 `autoplay: false`,然后调用 `animation.play()`、`animation.pause()`、`animation.restart()`、`animation.reverse()`、`animation.seek(500)`。
- 性能优化:优先动画 `translateX`、`opacity` 等 GPU 加速属性;避免动画 `left: '250px'`、`width: '500px'` 这类触发布局的属性。
- 批量相似动画:用一个 `anime({ targets: '.multiple-elements', translateX: 250 })`;避免 `elements.forEach(el => anime({ targets: el, translateX: 250 }))`。
- 复杂动画使用 `will-change`:在 CSS 中给 `.animated-element` 设置 `will-change: transform, opacity;`。
- 滚动动画禁用 autoplay:创建动画时设置 `autoplay: false`,手动控制播放。
- 避免单位丢失:需要单位时写 `width: '200px'`,不要写 `width: 200`。
- 避免直接动画 CSS transform 属性:不要写 `transform: 'translateX(250px)'`;改用独立 transform 属性 `translateX: 250`。
- 处理动画清理:在 `useEffect` 中保存 `const anim = anime({ targets: ref.current, translateX: 250 })`,返回 `() => anim.pause()`,避免组件卸载后动画继续。
- 避免动画过多元素:不要对 1000+ 元素执行 `anime({ targets: '.many-items', translateX: 250 })`;大量元素改用 CSS animations 或虚拟化减少元素数量。
- 修正时间线计时:不要用 `.add({ targets: '.el2' }, '500')` 作为绝对时间;用相对操作符 `'-=500'` 或 `'+=200'`。
- 避免过度使用 loop:不要对无限循环旋转使用 `loop: true`;可改用 CSS `@keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }`。
- 使用附带脚本:调用 `animation_generator.py` 生成 Anime.js 动画样板(8 种类型),调用 `timeline_builder.py` 构建复杂时间线序列。
- 查阅附带参考:阅读 `api_reference.md` 获取完整 Anime.js API,阅读 `stagger_guide.md` 了解 stagger 工具和模式,阅读 `timeline_guide.md` 深入了解 timeline 排序。
- 使用附带资产:使用 `starter_animejs/`(Vanilla JS + Vite 模板与示例),查看 `examples/` 中的真实模式(SVG morphing、stagger grids、timelines)。
- 选择实现方式时:SVG 重、简单项目、在意包体积用 Anime.js;需要复杂滚动驱动、高级时间线、专业级控制用 GSAP;需要 React 特定声明式动画与手势集成用 Framer Motion。
- 需要物理弹簧动画或简单 3D 效果时,可参考相关技能 `react-spring-physics` 或 `lightweight-3d-effects`。
- 相关技能列表:`gsap-scrolltrigger` 提供更强大时间线和滚动集成;`motion-framer` 提供 React 特定声明式动画;`react-spring-physics` 提供基于物理的弹簧动画;`lightweight-3d-effects` 提供简单 3D 效果(Zdog、Vanta.js)。
适用边界 · 注意事项
- 需要复杂滚动驱动体验、高级时间线和专业级控制时,应使用 GSAP(如 gsap-scrolltrigger),而不是 Anime.js。
- 需要 React 特定声明式动画、手势集成时,应使用 Framer Motion,而不是 Anime.js。
- 需要对 1000+ 元素做动画或无限循环旋转时,优先使用 CSS 动画、虚拟化或专用方案,而不是 Anime.js。