mcpField
A
anime-js

anime-js

github.com/mindrally设计与 UI288746 次安装3 周前更新
代码仓库

关于 anime-js

面向 Anime.js、JavaScript 和 Web 动画开发的指导技能,提供动画编排、性能优化与无障碍实践。适合实现交互动画及 React 动画组件的开发者。

主要功能

  1. 01时间线与交错动画
  2. 02SVG 路径动画与形变
  3. 03缓动与动态取值
  4. 04React 集成指导
  5. 05性能与减少动态效果建议

适用场景

  1. 01编排多元素动画序列
  2. 02制作 SVG 路径动画
  3. 03实现 React 组件动效
  4. 04适配减少动态效果偏好

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mindrally/skills --skill anime-js

安装后在 Claude Code 中输入/anime-js确认已加载。

详细介绍

Anime.js 动画指南

你是 Anime.js、JavaScript 和 Web 动画性能方面的专家。创建动画时请遵循以下指南。

核心原则

安装和导入
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
});
高频更新使用 Animatable
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)"
});

SVG 动画

路径动画
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");
  }
});

React 集成

React 基本用法
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>;
}
使用 useCallback 控制
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 桥接

使用 WAAPI 获得原生性能
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"
});

最佳实践总结

  1. 优先使用变换属性(translate、scale、rotate),而非布局属性
  2. 只导入所需模块,以减小打包体积
  3. 多个元素的动画使用交错效果
  4. 组件卸载时清理动画
  5. 高频更新使用 Animatable
  6. 复杂序列使用时间线
  7. 动态动画使用基于函数的值
  8. 尊重减少动态效果的偏好
  9. 考虑使用 WAAPI 桥接来获得原生性能
  10. 在性能较低的设备上测试

评论

支持 Markdown