anime-js by mindrally/skills
npx skills add https://github.com/mindrally/skills --skill anime-js您是一位精通 Anime.js、JavaScript 和网页动画性能的专家。创建动画时请遵循以下指南。
npm install animejs
// 完整导入
import anime from "animejs";
// 模块化导入以减小打包体积
import { animate, timeline, stagger } from "animejs";
anime({
targets: ".element",
translateX: 250,
rotate: "1turn",
duration: 800,
easing: "easeInOutQuad"
});
// 为低端设备调整全局帧率
anime.suspendWhenDocumentHidden = true;
// 控制特定动画的 FPS
anime({
targets: ".element",
translateX: 250,
update: function(anim) {
// 如有需要,可自定义帧率限制
}
});
// 良好 - 使用 GPU 加速的变换
anime({
targets: ".element",
translateX: 100, // 良好
translateY: 50, // 良好
scale: 1.2, // 良好
rotate: 45, // 良好
opacity: 0.5 // 良好
});
// 避免 - 导致布局重计算
anime({
targets: ".element",
left: 100, // 避免
top: 50, // 避免
width: 200, // 避免
height: 150 // 避免
});
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
import { Animatable } from "animejs";
// 针对连续更新(鼠标跟踪等)进行优化
const animatable = new Animatable(".cursor", {
x: 0,
y: 0
});
document.addEventListener("mousemove", (e) => {
animatable.x = e.clientX;
animatable.y = e.clientY;
});
const tl = anime.timeline({
easing: "easeOutExpo",
duration: 750
});
tl.add({
targets: ".header",
translateY: [-50, 0],
opacity: [0, 1]
})
.add({
targets: ".content",
translateY: [30, 0],
opacity: [0, 1]
}, "-=500") // 重叠 500 毫秒
.add({
targets: ".footer",
translateY: [30, 0],
opacity: [0, 1]
}, "-=500");
const tl = anime.timeline({
autoplay: false
});
// 控制方法
tl.play();
tl.pause();
tl.restart();
tl.reverse();
tl.seek(1000); // 跳转到 1 秒处
anime({
targets: ".grid-item",
translateY: [50, 0],
opacity: [0, 1],
delay: anime.stagger(100) // 每个元素之间延迟 100 毫秒
});
// 从中心开始交错
anime({
targets: ".grid-item",
scale: [0, 1],
delay: anime.stagger(100, { from: "center" })
});
// 网格交错
anime({
targets: ".grid-item",
scale: [0, 1],
delay: anime.stagger(50, {
grid: [14, 5],
from: "center"
})
});
// 带缓动函数的交错
anime({
targets: ".item",
translateX: 250,
delay: anime.stagger(100, { easing: "easeOutQuad" })
});
// 常用缓动
anime({
targets: ".element",
translateX: 250,
easing: "easeOutExpo" // 快速开始,缓慢结束
// easing: "easeInOutQuad" // 两端平滑
// easing: "easeOutElastic(1, .5)" // 弹性效果
// easing: "easeOutBounce" // 弹跳效果
// easing: "spring(1, 80, 10, 0)" // 基于物理效果
});
anime({
targets: ".element",
translateX: 250,
easing: "cubicBezier(0.25, 0.1, 0.25, 1)"
});
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: "path",
strokeDashoffset: [anime.setDashoffset, 0],
easing: "easeInOutSine",
duration: 1500,
delay: anime.stagger(250)
});
anime({
targets: "path",
d: [
{ value: "M10 10 L90 10 L90 90 L10 90 Z" },
{ value: "M10 50 Q50 10 90 50 Q50 90 10 50 Z" }
],
easing: "easeInOutQuad",
duration: 1000,
loop: true,
direction: "alternate"
});
anime({
targets: ".element",
translateX: function(el, i) {
return i * 100; // 每个元素移动得更远
},
rotate: function(el, i, total) {
return (360 / total) * i; // 分布旋转角度
},
delay: function(el, i) {
return i * 50;
}
});
anime({
targets: ".element",
translateX: 250,
begin: function(anim) {
console.log("动画开始");
},
update: function(anim) {
console.log(Math.round(anim.progress) + "%");
},
complete: function(anim) {
console.log("动画完成");
}
});
anime({
targets: ".element",
translateX: 250,
direction: "alternate",
loop: true,
loopComplete: function(anim) {
console.log("循环完成");
}
});
import { useEffect, useRef } from "react";
import anime from "animejs";
function AnimatedComponent() {
const elementRef = useRef(null);
useEffect(() => {
const animation = anime({
targets: elementRef.current,
translateX: 250,
duration: 800
});
return () => {
animation.pause(); // 清理
};
}, []);
return <div ref={elementRef}>动画元素</div>;
}
function ControlledAnimation() {
const elementRef = useRef(null);
const animationRef = useRef(null);
const playAnimation = useCallback(() => {
animationRef.current = anime({
targets: elementRef.current,
translateX: [0, 250],
duration: 800
});
}, []);
useEffect(() => {
return () => {
animationRef.current?.pause();
};
}, []);
return (
<>
<div ref={elementRef}>动画元素</div>
<button onClick={playAnimation}>播放</button>
</>
);
}
import { wapiAnimate } from "animejs";
// 使用浏览器的原生 Web Animations API
wapiAnimate(".element", {
translateX: 250,
duration: 800
});
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
anime({
targets: ".element",
translateX: 250,
duration: prefersReducedMotion ? 0 : 800,
easing: prefersReducedMotion ? "linear" : "easeOutExpo"
});
每周安装量
98
代码仓库
GitHub 星标数
42
首次出现
2026年1月25日
安全审计
安装于
opencode82
gemini-cli81
codex77
github-copilot72
cursor71
claude-code71
You are an expert in Anime.js, JavaScript, and web animation performance. Follow these guidelines when creating animations.
npm install animejs
// Full import
import anime from "animejs";
// Modular import for smaller bundle size
import { animate, timeline, stagger } from "animejs";
anime({
targets: ".element",
translateX: 250,
rotate: "1turn",
duration: 800,
easing: "easeInOutQuad"
});
// Adjust global frame rate for lower-end devices
anime.suspendWhenDocumentHidden = true;
// Control FPS for specific animations
anime({
targets: ".element",
translateX: 250,
update: function(anim) {
// Custom frame rate limiting if needed
}
});
// Good - uses GPU-accelerated transforms
anime({
targets: ".element",
translateX: 100, // Good
translateY: 50, // Good
scale: 1.2, // Good
rotate: 45, // Good
opacity: 0.5 // Good
});
// Avoid - causes layout recalculation
anime({
targets: ".element",
left: 100, // Avoid
top: 50, // Avoid
width: 200, // Avoid
height: 150 // Avoid
});
import { Animatable } from "animejs";
// Optimized for continuous updates (mouse tracking, etc.)
const animatable = new Animatable(".cursor", {
x: 0,
y: 0
});
document.addEventListener("mousemove", (e) => {
animatable.x = e.clientX;
animatable.y = e.clientY;
});
const tl = anime.timeline({
easing: "easeOutExpo",
duration: 750
});
tl.add({
targets: ".header",
translateY: [-50, 0],
opacity: [0, 1]
})
.add({
targets: ".content",
translateY: [30, 0],
opacity: [0, 1]
}, "-=500") // Overlap by 500ms
.add({
targets: ".footer",
translateY: [30, 0],
opacity: [0, 1]
}, "-=500");
const tl = anime.timeline({
autoplay: false
});
// Control methods
tl.play();
tl.pause();
tl.restart();
tl.reverse();
tl.seek(1000); // Go to 1 second
anime({
targets: ".grid-item",
translateY: [50, 0],
opacity: [0, 1],
delay: anime.stagger(100) // 100ms delay between each
});
// Stagger from center
anime({
targets: ".grid-item",
scale: [0, 1],
delay: anime.stagger(100, { from: "center" })
});
// Grid stagger
anime({
targets: ".grid-item",
scale: [0, 1],
delay: anime.stagger(50, {
grid: [14, 5],
from: "center"
})
});
// Stagger with easing
anime({
targets: ".item",
translateX: 250,
delay: anime.stagger(100, { easing: "easeOutQuad" })
});
// Common easings
anime({
targets: ".element",
translateX: 250,
easing: "easeOutExpo" // Fast start, slow end
// easing: "easeInOutQuad" // Smooth both ends
// easing: "easeOutElastic(1, .5)" // Bouncy
// easing: "easeOutBounce" // Bounce effect
// easing: "spring(1, 80, 10, 0)" // Physics-based
});
anime({
targets: ".element",
translateX: 250,
easing: "cubicBezier(0.25, 0.1, 0.25, 1)"
});
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: "path",
strokeDashoffset: [anime.setDashoffset, 0],
easing: "easeInOutSine",
duration: 1500,
delay: anime.stagger(250)
});
anime({
targets: "path",
d: [
{ value: "M10 10 L90 10 L90 90 L10 90 Z" },
{ value: "M10 50 Q50 10 90 50 Q50 90 10 50 Z" }
],
easing: "easeInOutQuad",
duration: 1000,
loop: true,
direction: "alternate"
});
anime({
targets: ".element",
translateX: function(el, i) {
return i * 100; // Each element moves further
},
rotate: function(el, i, total) {
return (360 / total) * i; // Distribute rotation
},
delay: function(el, i) {
return i * 50;
}
});
anime({
targets: ".element",
translateX: 250,
begin: function(anim) {
console.log("Animation started");
},
update: function(anim) {
console.log(Math.round(anim.progress) + "%");
},
complete: function(anim) {
console.log("Animation completed");
}
});
anime({
targets: ".element",
translateX: 250,
direction: "alternate",
loop: true,
loopComplete: function(anim) {
console.log("Loop completed");
}
});
import { useEffect, useRef } from "react";
import anime from "animejs";
function AnimatedComponent() {
const elementRef = useRef(null);
useEffect(() => {
const animation = anime({
targets: elementRef.current,
translateX: 250,
duration: 800
});
return () => {
animation.pause(); // Cleanup
};
}, []);
return <div ref={elementRef}>Animated</div>;
}
function ControlledAnimation() {
const elementRef = useRef(null);
const animationRef = useRef(null);
const playAnimation = useCallback(() => {
animationRef.current = anime({
targets: elementRef.current,
translateX: [0, 250],
duration: 800
});
}, []);
useEffect(() => {
return () => {
animationRef.current?.pause();
};
}, []);
return (
<>
<div ref={elementRef}>Animated</div>
<button onClick={playAnimation}>Play</button>
</>
);
}
import { wapiAnimate } from "animejs";
// Uses browser's native Web Animations API
wapiAnimate(".element", {
translateX: 250,
duration: 800
});
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
anime({
targets: ".element",
translateX: 250,
duration: prefersReducedMotion ? 0 : 800,
easing: prefersReducedMotion ? "linear" : "easeOutExpo"
});
Weekly Installs
98
Repository
GitHub Stars
42
First Seen
Jan 25, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode82
gemini-cli81
codex77
github-copilot72
cursor71
claude-code71
React视图过渡API使用指南:实现原生浏览器动画与状态管理
5,700 周安装