animejs by freshtechbro/claudedesignskills
npx skills add https://github.com/freshtechbro/claudedesignskills --skill animejs轻量级 JavaScript 动画库,具备强大的时间轴和交错功能,适用于网页动画。
Anime.js(发音为 "Anime JS")是一个多功能的动画引擎,可与 DOM 元素、CSS 属性、SVG 属性和 JavaScript 对象配合使用。与特定于 React 的库不同,Anime.js 可与原生 JavaScript 和任何框架一起使用。
何时使用此技能:
核心功能:
anime() 函数用于创建动画:
import anime from 'animejs'
anime({
targets: '.element',
translateX: 250,
rotate: '1turn',
duration: 800,
easing: 'easeInOutQuad'
})
指定动画目标对象的多种方式:
// CSS 选择器
anime({ targets: '.box' })
// DOM 元素
anime({ targets: document.querySelectorAll('.box') })
// 元素数组
anime({ targets: [el1, el2, el3] })
// JavaScript 对象
const obj = { x: 0 }
anime({ targets: obj, x: 100 })
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
CSS 属性:
anime({
targets: '.element',
translateX: 250,
scale: 2,
opacity: 0.5,
backgroundColor: '#FFF'
})
CSS 变换(单独属性):
anime({
targets: '.element',
translateX: 250, // 单独的变换属性
rotate: '1turn', // 不是 'transform: rotate()'
scale: 2
})
SVG 属性:
anime({
targets: 'path',
d: 'M10 80 Q 77.5 10, 145 80', // 路径变形
fill: '#FF0000',
strokeDashoffset: [anime.setDashoffset, 0] // 线条绘制
})
JavaScript 对象:
const obj = { value: 0 }
anime({
targets: obj,
value: 100,
round: 1,
update: () => console.log(obj.value)
})
创建具有精确控制的复杂序列:
const timeline = anime.timeline({
duration: 750,
easing: 'easeOutExpo'
})
timeline
.add({
targets: '.box1',
translateX: 250
})
.add({
targets: '.box2',
translateX: 250
}, '-=500') // 在前一个动画结束前 500 毫秒开始
.add({
targets: '.box3',
translateX: 250
}, '+=200') // 在前一个动画结束后 200 毫秒开始
anime({
targets: '.stagger-element',
translateY: [100, 0],
opacity: [0, 1],
delay: anime.stagger(100), // 延迟增加 100 毫秒
easing: 'easeOutQuad',
duration: 600
})
anime({
targets: '.grid-item',
scale: [0, 1],
delay: anime.stagger(50, {
grid: [14, 5],
from: 'center', // 也可以是:'first'、'last'、index、[x, y]
axis: 'x' // 也可以是:'y'、null
}),
easing: 'easeOutQuad'
})
anime({
targets: 'path',
strokeDashoffset: [anime.setDashoffset, 0],
easing: 'easeInOutQuad',
duration: 2000,
delay: (el, i) => i * 250
})
anime({
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
})
tl.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')
anime({
targets: '.element',
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
})
window.addEventListener('scroll', () => {
const scrollPercent = window.scrollY / (document.body.scrollHeight - window.innerHeight)
animation.seek(animation.duration * scrollPercent)
})
import { useEffect, useRef } from 'react'
import anime from 'animejs'
function AnimatedComponent() {
const ref = useRef(null)
useEffect(() => {
const animation = anime({
targets: ref.current,
translateX: 250,
duration: 800,
easing: 'easeInOutQuad'
})
return () => animation.pause()
}, [])
return <div ref={ref}>Animated</div>
}
export default {
mounted() {
anime({
targets: this.$el,
translateX: 250,
duration: 800
})
}
}
const path = anime.path('#motion-path')
anime({
targets: '.element',
translateX: path('x'),
translateY: path('y'),
rotate: path('angle'),
easing: 'linear',
duration: 2000,
loop: true
})
anime({
targets: '.element',
translateX: 250,
easing: 'spring(1, 80, 10, 0)', // mass, stiffness, damping, velocity
duration: 2000
})
anime({
targets: '.element',
translateX: 250,
easing: 'steps(5)',
duration: 1000
})
anime({
targets: '.element',
translateX: 250,
easing: 'cubicBezier(.5, .05, .1, .3)',
duration: 1000
})
anime({
targets: '.element',
translateX: 250,
direction: 'alternate', // 'normal', 'reverse', 'alternate'
loop: true, // 或迭代次数
easing: 'easeInOutQuad'
})
const animation = anime({
targets: '.element',
translateX: 250,
autoplay: false
})
animation.play()
animation.pause()
animation.restart()
animation.reverse()
animation.seek(500) // 跳转到 500 毫秒
// ✅ 良好:GPU 加速
anime({
targets: '.element',
translateX: 250,
opacity: 0.5
})
// ❌ 避免:触发布局
anime({
targets: '.element',
left: '250px',
width: '500px'
})
// ✅ 对多个目标使用单个动画
anime({
targets: '.multiple-elements',
translateX: 250
})
// ❌ 避免:多个独立的动画
elements.forEach(el => {
anime({ targets: el, translateX: 250 })
})
will-change.animated-element {
will-change: transform, opacity;
}
const animation = anime({
targets: '.element',
translateX: 250,
autoplay: false // 手动控制
})
// ❌ 错误:没有单位
anime({ targets: '.element', width: 200 })
// ✅ 正确:包含单位
anime({ targets: '.element', width: '200px' })
// ❌ 错误:无法动画化 transform 字符串
anime({ targets: '.element', transform: 'translateX(250px)' })
// ✅ 正确:单独的变换属性
anime({ targets: '.element', translateX: 250 })
// ❌ 错误:卸载后动画继续运行
useEffect(() => {
anime({ targets: ref.current, translateX: 250 })
}, [])
// ✅ 正确:清理时暂停
useEffect(() => {
const anim = anime({ targets: ref.current, translateX: 250 })
return () => anim.pause()
}, [])
// ❌ 避免:动画化 1000+ 个元素
anime({ targets: '.many-items', translateX: 250 }) // 1000+ 个元素
// ✅ 更好:对大型集合使用 CSS 动画
// 或者通过虚拟化减少元素数量
// ❌ 错误:缺少偏移运算符
.add({ targets: '.el2' }, '500') // 被视为绝对时间
// ✅ 正确:使用相对运算符
.add({ targets: '.el2' }, '-=500') // 相对于前一个
.add({ targets: '.el3' }, '+=200') // 相对于前一个
// ❌ 避免:无限循环消耗电池
anime({
targets: '.element',
rotate: '1turn',
loop: true,
duration: 1000
})
// ✅ 更好:对无限循环使用 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 - 交错实用工具和模式timeline_guide.md - 时间轴序列深入探讨starter_animejs/ - 包含示例的原生 JS + Vite 模板examples/ - 实际应用模式(SVG 变形、交错网格、时间轴)Anime.js 与 GSAP:对于 SVG 密集型动画、更简单的项目,或者当包大小很重要时,使用 Anime.js。对于复杂的滚动驱动体验、高级时间轴和专业级控制,使用 GSAP。
Anime.js 与 Framer Motion:对于与框架无关的项目或在 React 之外工作时,使用 Anime.js。对于具有手势集成的 React 特定声明式动画,使用 Framer Motion。
每周安装次数
77
代码仓库
GitHub 星标数
11
首次出现
2026年2月27日
安全审计
安装于
opencode76
claude-code74
github-copilot74
codex74
amp74
cline74
Lightweight JavaScript animation library with powerful timeline and stagger capabilities for web animations.
Anime.js (pronounced "Anime JS") is a versatile animation engine that works with DOM elements, CSS properties, SVG attributes, and JavaScript objects. Unlike React-specific libraries, Anime.js works with vanilla JavaScript and any framework.
When to use this skill:
Core features:
The anime() function creates animations:
import anime from 'animejs'
anime({
targets: '.element',
translateX: 250,
rotate: '1turn',
duration: 800,
easing: 'easeInOutQuad'
})
Multiple ways to specify animation targets:
// CSS selector
anime({ targets: '.box' })
// DOM elements
anime({ targets: document.querySelectorAll('.box') })
// Array of elements
anime({ targets: [el1, el2, el3] })
// JavaScript object
const obj = { x: 0 }
anime({ targets: obj, x: 100 })
CSS Properties:
anime({
targets: '.element',
translateX: 250,
scale: 2,
opacity: 0.5,
backgroundColor: '#FFF'
})
CSS Transforms (Individual):
anime({
targets: '.element',
translateX: 250, // Individual transform
rotate: '1turn', // Not 'transform: rotate()'
scale: 2
})
SVG Attributes:
anime({
targets: 'path',
d: 'M10 80 Q 77.5 10, 145 80', // Path morphing
fill: '#FF0000',
strokeDashoffset: [anime.setDashoffset, 0] // Line drawing
})
JavaScript Objects:
const obj = { value: 0 }
anime({
targets: obj,
value: 100,
round: 1,
update: () => console.log(obj.value)
})
Create complex sequences with precise control:
const timeline = anime.timeline({
duration: 750,
easing: 'easeOutExpo'
})
timeline
.add({
targets: '.box1',
translateX: 250
})
.add({
targets: '.box2',
translateX: 250
}, '-=500') // Start 500ms before previous animation ends
.add({
targets: '.box3',
translateX: 250
}, '+=200') // Start 200ms after previous animation ends
anime({
targets: '.stagger-element',
translateY: [100, 0],
opacity: [0, 1],
delay: anime.stagger(100), // Increase delay by 100ms
easing: 'easeOutQuad',
duration: 600
})
anime({
targets: '.grid-item',
scale: [0, 1],
delay: anime.stagger(50, {
grid: [14, 5],
from: 'center', // Also: 'first', 'last', index, [x, y]
axis: 'x' // Also: 'y', null
}),
easing: 'easeOutQuad'
})
anime({
targets: 'path',
strokeDashoffset: [anime.setDashoffset, 0],
easing: 'easeInOutQuad',
duration: 2000,
delay: (el, i) => i * 250
})
anime({
targets: '#morphing-path',
d: [
{ value: 'M10 80 Q 77.5 10, 145 80' }, // Start shape
{ value: 'M10 80 Q 77.5 150, 145 80' } // End shape
],
duration: 2000,
easing: 'easeInOutQuad',
loop: true,
direction: 'alternate'
})
const tl = anime.timeline({
easing: 'easeOutExpo',
duration: 750
})
tl.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')
anime({
targets: '.element',
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
})
window.addEventListener('scroll', () => {
const scrollPercent = window.scrollY / (document.body.scrollHeight - window.innerHeight)
animation.seek(animation.duration * scrollPercent)
})
import { useEffect, useRef } from 'react'
import anime from 'animejs'
function AnimatedComponent() {
const ref = useRef(null)
useEffect(() => {
const animation = anime({
targets: ref.current,
translateX: 250,
duration: 800,
easing: 'easeInOutQuad'
})
return () => animation.pause()
}, [])
return <div ref={ref}>Animated</div>
}
export default {
mounted() {
anime({
targets: this.$el,
translateX: 250,
duration: 800
})
}
}
const path = anime.path('#motion-path')
anime({
targets: '.element',
translateX: path('x'),
translateY: path('y'),
rotate: path('angle'),
easing: 'linear',
duration: 2000,
loop: true
})
anime({
targets: '.element',
translateX: 250,
easing: 'spring(1, 80, 10, 0)', // mass, stiffness, damping, velocity
duration: 2000
})
anime({
targets: '.element',
translateX: 250,
easing: 'steps(5)',
duration: 1000
})
anime({
targets: '.element',
translateX: 250,
easing: 'cubicBezier(.5, .05, .1, .3)',
duration: 1000
})
anime({
targets: '.element',
translateX: 250,
direction: 'alternate', // 'normal', 'reverse', 'alternate'
loop: true, // or number of iterations
easing: 'easeInOutQuad'
})
const animation = anime({
targets: '.element',
translateX: 250,
autoplay: false
})
animation.play()
animation.pause()
animation.restart()
animation.reverse()
animation.seek(500) // Seek to 500ms
// ✅ Good: GPU-accelerated
anime({
targets: '.element',
translateX: 250,
opacity: 0.5
})
// ❌ Avoid: Triggers layout
anime({
targets: '.element',
left: '250px',
width: '500px'
})
// ✅ Single animation for multiple targets
anime({
targets: '.multiple-elements',
translateX: 250
})
// ❌ Avoid: Multiple separate animations
elements.forEach(el => {
anime({ targets: el, translateX: 250 })
})
will-change for Complex Animations.animated-element {
will-change: transform, opacity;
}
const animation = anime({
targets: '.element',
translateX: 250,
autoplay: false // Control manually
})
// ❌ Wrong: No unit
anime({ targets: '.element', width: 200 })
// ✅ Correct: Include unit
anime({ targets: '.element', width: '200px' })
// ❌ Wrong: Can't animate transform string
anime({ targets: '.element', transform: 'translateX(250px)' })
// ✅ Correct: Individual transform properties
anime({ targets: '.element', translateX: 250 })
// ❌ Wrong: Animation continues after unmount
useEffect(() => {
anime({ targets: ref.current, translateX: 250 })
}, [])
// ✅ Correct: Pause on cleanup
useEffect(() => {
const anim = anime({ targets: ref.current, translateX: 250 })
return () => anim.pause()
}, [])
// ❌ Avoid: Animating 1000+ elements
anime({ targets: '.many-items', translateX: 250 }) // 1000+ elements
// ✅ Better: Use CSS animations for large sets
// Or reduce element count with virtualization
// ❌ Wrong: Missing offset operator
.add({ targets: '.el2' }, '500') // Treated as absolute time
// ✅ Correct: Use relative operators
.add({ targets: '.el2' }, '-=500') // Relative to previous
.add({ targets: '.el3' }, '+=200') // Relative to previous
// ❌ Avoid: Infinite loops drain battery
anime({
targets: '.element',
rotate: '1turn',
loop: true,
duration: 1000
})
// ✅ Better: Use CSS animations for infinite loops
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
animation_generator.py - Generate Anime.js animation boilerplate (8 types)timeline_builder.py - Build complex timeline sequencesapi_reference.md - Complete Anime.js API documentationstagger_guide.md - Stagger utilities and patternstimeline_guide.md - Timeline sequencing deep divestarter_animejs/ - Vanilla JS + Vite template with examplesexamples/ - Real-world patterns (SVG morphing, stagger grids, timelines)Anime.js vs GSAP : Use Anime.js for SVG-heavy animations, simpler projects, or when bundle size matters. Use GSAP for complex scroll-driven experiences, advanced timelines, and professional-grade control.
Anime.js vs Framer Motion : Use Anime.js for framework-agnostic projects or when working outside React. Use Framer Motion for React-specific declarative animations with gesture integration.
Weekly Installs
77
Repository
GitHub Stars
11
First Seen
Feb 27, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode76
claude-code74
github-copilot74
codex74
amp74
cline74
React视图过渡API使用指南:实现原生浏览器动画与状态管理
5,700 周安装
Novel Writer 新手指南:七步方法论教你从零开始写小说
122 周安装
GitNexus 指南:代码智能与影响分析工具,快速理解、调试与重构代码库
121 周安装
媒体改编技能:系统化分析转化方法,将现有作品转化为科幻设定 | 创意内容开发指南
120 周安装
Tamagui Monorepo 跨平台开发指南:React Native、Next.js、Expo、TypeScript 全栈解决方案
122 周安装
Motion动画库指南:高性能JavaScript/TypeScript网页动效开发与性能优化
123 周安装
Node.js开发专家指南:TypeScript、Payload CMS、Next.js与Vue.js全栈实战
122 周安装