anime-js
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAnime.js Animation Guidelines
Anime.js动画指南
You are an expert in Anime.js, JavaScript, and web animation performance. Follow these guidelines when creating animations.
您是Anime.js、JavaScript和Web动画性能方面的专家。创建动画时请遵循以下指南。
Core Principles
核心原则
Installation and Import
安装与导入
bash
npm install animejsjavascript
// Full import
import anime from "animejs";
// Modular import for smaller bundle size
import { animate, timeline, stagger } from "animejs";bash
npm install animejsjavascript
// 完整导入
import anime from "animejs";
// 模块化导入以减小包体积
import { animate, timeline, stagger } from "animejs";Basic Animation
基础动画
javascript
anime({
targets: ".element",
translateX: 250,
rotate: "1turn",
duration: 800,
easing: "easeInOutQuad"
});javascript
anime({
targets: ".element",
translateX: 250,
rotate: "1turn",
duration: 800,
easing: "easeInOutQuad"
});Performance Optimization
性能优化
Frame Rate Control
帧率控制
javascript
// 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
}
});javascript
// 为低端设备调整全局帧率
anime.suspendWhenDocumentHidden = true;
// 为特定动画控制FPS
anime({
targets: ".element",
translateX: 250,
update: function(anim) {
// 如有需要,自定义限制帧率
}
});Use Transforms Over Layout Properties
使用变换属性而非布局属性
javascript
// 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
});javascript
// 推荐 - 使用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 // 避免
});Use Animatable for High-Frequency Updates
使用Animatable处理高频更新
javascript
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;
});javascript
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;
});Timeline Animations
时间轴动画
Basic Timeline
基础时间轴
javascript
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");javascript
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") // 重叠500ms
.add({
targets: ".footer",
translateY: [30, 0],
opacity: [0, 1]
}, "-=500");Timeline Controls
时间轴控制
javascript
const tl = anime.timeline({
autoplay: false
});
// Control methods
tl.play();
tl.pause();
tl.restart();
tl.reverse();
tl.seek(1000); // Go to 1 secondjavascript
const tl = anime.timeline({
autoplay: false
});
// 控制方法
tl.play();
tl.pause();
tl.restart();
tl.reverse();
tl.seek(1000); // 跳转到1秒处Stagger Animations
交错动画
Basic Stagger
基础交错效果
javascript
anime({
targets: ".grid-item",
translateY: [50, 0],
opacity: [0, 1],
delay: anime.stagger(100) // 100ms delay between each
});javascript
anime({
targets: ".grid-item",
translateY: [50, 0],
opacity: [0, 1],
delay: anime.stagger(100) // 每个元素间隔100ms
});Advanced Stagger Options
高级交错选项
javascript
// 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" })
});javascript
// 从中心开始交错
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" })
});Easing Functions
缓动函数
Built-in Easings
内置缓动效果
javascript
// 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
});javascript
// 常见缓动效果
anime({
targets: ".element",
translateX: 250,
easing: "easeOutExpo" // 快启慢停
// easing: "easeInOutQuad" // 两端平滑
// easing: "easeOutElastic(1, .5)" // 弹性效果
// easing: "easeOutBounce" // 弹跳效果
// easing: "spring(1, 80, 10, 0)" // 物理模拟
});Custom Easing
自定义缓动
javascript
anime({
targets: ".element",
translateX: 250,
easing: "cubicBezier(0.25, 0.1, 0.25, 1)"
});javascript
anime({
targets: ".element",
translateX: 250,
easing: "cubicBezier(0.25, 0.1, 0.25, 1)"
});SVG Animation
SVG动画
Path Animation
路径动画
javascript
const path = anime.path(".motion-path");
anime({
targets: ".element",
translateX: path("x"),
translateY: path("y"),
rotate: path("angle"),
easing: "linear",
duration: 2000,
loop: true
});javascript
const path = anime.path(".motion-path");
anime({
targets: ".element",
translateX: path("x"),
translateY: path("y"),
rotate: path("angle"),
easing: "linear",
duration: 2000,
loop: true
});Line Drawing
描边动画
javascript
anime({
targets: "path",
strokeDashoffset: [anime.setDashoffset, 0],
easing: "easeInOutSine",
duration: 1500,
delay: anime.stagger(250)
});javascript
anime({
targets: "path",
strokeDashoffset: [anime.setDashoffset, 0],
easing: "easeInOutSine",
duration: 1500,
delay: anime.stagger(250)
});Morphing
形态变换
javascript
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"
});javascript
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"
});Function-Based Values
基于函数的属性值
Dynamic Values
动态属性值
javascript
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;
}
});javascript
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;
}
});Callbacks and Events
回调与事件
Animation Events
动画事件
javascript
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");
}
});javascript
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");
}
});Looping
循环动画
javascript
anime({
targets: ".element",
translateX: 250,
direction: "alternate",
loop: true,
loopComplete: function(anim) {
console.log("Loop completed");
}
});javascript
anime({
targets: ".element",
translateX: 250,
direction: "alternate",
loop: true,
loopComplete: function(anim) {
console.log("Loop completed");
}
});React Integration
React集成
Basic React Usage
React基础用法
tsx
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>;
}tsx
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}>Animated</div>;
}With useCallback for Controls
结合useCallback实现控制
tsx
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>
</>
);
}tsx
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>
</>
);
}Web Animations API Bridge
Web Animations API桥接
Using WAAPI for Native Performance
使用WAAPI获取原生性能
javascript
import { wapiAnimate } from "animejs";
// Uses browser's native Web Animations API
wapiAnimate(".element", {
translateX: 250,
duration: 800
});javascript
import { wapiAnimate } from "animejs";
// 使用浏览器原生Web Animations API
wapiAnimate(".element", {
translateX: 250,
duration: 800
});Accessibility
可访问性
Respect Reduced Motion
尊重减少动画偏好
javascript
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
anime({
targets: ".element",
translateX: 250,
duration: prefersReducedMotion ? 0 : 800,
easing: prefersReducedMotion ? "linear" : "easeOutExpo"
});javascript
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
anime({
targets: ".element",
translateX: 250,
duration: prefersReducedMotion ? 0 : 800,
easing: prefersReducedMotion ? "linear" : "easeOutExpo"
});Best Practices Summary
最佳实践总结
- Use transforms (translate, scale, rotate) over layout properties
- Import only needed modules for smaller bundle size
- Use stagger for multiple element animations
- Clean up animations on component unmount
- Use Animatable for high-frequency updates
- Leverage timeline for complex sequences
- Use function-based values for dynamic animations
- Respect reduced motion preferences
- Consider WAAPI bridge for native performance
- Test on lower-powered devices
- 使用变换属性(translate、scale、rotate)而非布局属性
- 仅导入所需模块以减小包体积
- 对多元素动画使用交错效果
- 在组件卸载时清理动画
- 使用Animatable处理高频更新
- 利用时间轴实现复杂序列动画
- 使用基于函数的属性值创建动态动画
- 尊重减少动画的用户偏好
- 考虑使用WAAPI桥接以获取原生性能
- 在低性能设备上进行测试