Communitygithub.com

yuzhang-ai/web-animation-skill

设计和构建感觉精致而非模板化的交互式网页动画。当用户请求网站或Web应用中的动效时使用——页面加载或首屏序列、滚动驱动或滚动触发的效果、视差、固定或水平滚动区块、平滑滚动、文字揭示与分割文本、悬停与按压微交互、页面或路由过渡(View Transitions API)、模态框/弹出框/下拉菜单的进入-退出、布局与共享元素动画、SVG线条绘制与变形、动画图表、Lottie或Rive播放、Canvas或WebGL/Three.js场景,或“让它感觉更流畅/更高级/得奖级”。涵盖GSAP(ScrollTrigger、SplitText、Flip)、Motion(原Framer Motion和Motion One)、Anime.js v4、CSS过渡/@keyframes/@starting-style/滚动驱动动画、View Transitions、Lottie、Rive、D3、Flubber、Konva和Three.js/React Three Fiber。不适用于视频渲染(请使用Remotion)。

web-animation-skill 是什么?

该技能是一个全面的网页动效设计指南,帮助开发者和AI代理用户为网站或Web应用创建专业、精致的交互式动画。它采用设计优先的思维,强调每种动效都应有明确的功能目标(反馈、定位、吸引注意力或叙事),并引导用户根据项目已有库选择最轻量的工具。技能中包含了从简单CSS过渡到复杂GSAP ScrollTrigger、Motion React、Three.js等17种动效方案的决策表,每项方案都有专门的规则文件。它还定义了六项不可妥协的原则(如动画transform和opacity、尊重prefers-reduced-motion、清理动画等),并强调要在真实浏览器中验证效果。全栈支持,覆盖React、Vue、Svelte、Next.js App Router及纯HTML项目。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/yuzhang-ai/web-animation-skill/tree/HEAD

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

网页动效

好的网页动效首先是设计决策,其次才是库调用。请按以下工作流顺序操作;仅在需要某个步骤时才加载对应的规则文件。

工作流

1. 在做出选择前先阅读项目

  • 检查 package.json。如果已经安装了动效库,请使用它。 不要为了单一效果而添加第二个库。
  • 注意所用框架(React / Next.js App Router / Vue / Svelte / 纯HTML),并确认组件是否在服务端渲染(在Next.js中客户端动效需要 "use client")。
  • 检查CSS变量或主题文件中是否存在已有的动效令牌(时长、缓动函数),并复用它们。

2. 确定动效的目的

每个动效都需要一个任务。为每个元素选择一个:

任务示例典型时长预算
反馈 — 确认一个操作按钮按下、切换、复制到剪贴板100–200ms
定位 — 显示某物从何而来或去了何处模态框从其触发元素打开、列表项重新排序、路由变化200–400ms
吸引注意 — 指向一个事物单个首屏序列、新通知400–1200ms,一次
叙事 — 讲述与滚动相关的故事固定的产品导览、擦洗的时间线与滚动距离绑定

如果一个元素没有任务,就不要对它做动画。一个精心编排的瞬间胜过每个区块都做一个淡入效果。阅读 rules/motion-design.md 以了解时长、缓动、编排和“高级感”检查清单。

3. 选择能完成任务的最轻量工具

优先考虑平台,然后才是库:

需求使用规则文件
悬停、聚焦、按压、简单循环CSS 过渡 / @keyframescss-keyframes.md
对话框、弹出框、下拉菜单的进入和退出CSS @starting-style + transition-behavior: allow-discretecss-keyframes.md
页面/路由过渡、状态间的共享元素变形View Transitions APIview-transitions.md
简单的滚动关联展现、进度条、视差CSS animation-timeline: view() / scroll()scroll-animations.md
固定区块、擦洗的多步骤时间线、水平滚动GSAP + ScrollTriggergsap.md
分割文本/行遮罩标题展现GSAP SplitTextgsap.md
React 进入/退出、布局和共享布局动画、手势Motion for React (motion/react)framer-motion.md
无框架的命令式动画、弹簧Motion (motion)motion-one.md
不使用GSAP的SVG线条绘制和变形Anime.js v4 (svg.createDrawable, svg.morphTo)animejs.md
不相关形状之间的复杂路径变形Flubber (或 GSAP MorphSVG)flubber.md
After Effects 动画播放Lottie (dotLottie)lottie.md
交互式、状态驱动的插画动画Riverive.md
动画图表D3 过渡d3.md
大量交互式 2D 形状(编辑器、图表)Konvakonva.md
3D、粒子、着色器Three.js / React Three Fiberthree-js.md

当选择不明确时,请阅读 rules/choosing-library.md。

4. 遵循不可协商的原则进行构建

以下原则适用于每个动画,无论使用哪个库:

  1. 动画 transform 和 opacity。 避免动画 width、height、top、left、margin;使用 scale/translate、FLIP(GSAP Flip、Motion layout)或 View Transitions 来处理布局变化。参见 rules/performance.md。
  2. 尊重 prefers-reduced-motion。 将移动替换为淡入或瞬间变化;切勿直接删除内容的入场动画导致其保持不可见。滚动擦洗效果应变为静态。
  3. 切勿在 JS 运行前隐藏内容。 在 JS 中(或通过 .js 类)设置初始隐藏状态,以便在脚本失败时内容仍然可见。在使用 SSR 时,通过在首次绘制前应用初始样式,避免先可见后隐藏的内容闪烁。
  4. 清理动画。 在组件卸载时还原或销毁动画(使用 useGSAP、createScope().revert()、gsap.context),并在路由变化时销毁 ScrollTrigger。
  5. 保持交互响应性。 任何用户触发的动画都应可中断:第二次点击不能排队等待第一次完成。切勿为等待动画完成而阻止输入。
  6. 不要将焦点动效带走。 移动的元素必须保持可见的 :focus-visible 状态,动画化对话框也必须正确移动焦点。

5. 在真实浏览器中验证

不要仅仅通过阅读代码就报告动画已完成。运行它并检查:

  • 动画已播放,最终状态与设计一致(截取动画中和静止状态截图)。
  • 没有控制台错误,动画开始时没有布局偏移。
  • 模拟 prefers-reduced-motion: reduce 并确认缩减版本正常工作且内容可见。
  • 调整到移动宽度:固定区块和分割文本仍然有效(在调整大小时重新分割)。
  • 滚动驱动效果在向上和向下滚动时都正常工作,并且在页面中间重新加载后也正常。
  • 性能面板:动画期间没有长帧,没有因为动画属性导致的布局/绘制尖峰。

最小起始点

// GSAP + ScrollTrigger (npm i gsap)
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);

gsap.from(".card", {
  y: 40, opacity: 0, duration: 0.8, ease: "expo.out", stagger: 0.08,
  scrollTrigger: { trigger: ".cards", start: "top 80%" },
});
// Motion for React (npm i motion)
import { motion, AnimatePresence } from "motion/react";

<AnimatePresence>
  {open && (
    <motion.div
      key="panel"
      initial={{ opacity: 0, y: 8 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: 8 }}
      transition={{ type: "spring", duration: 0.35, bounce: 0 }}
    />
  )}
</AnimatePresence>
/* 纯平台滚动展现:Chrome 115+, Safari 26+, Firefox 159+ */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .reveal {
      animation: reveal linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 30%;
    }
  }
}
@keyframes reveal { from { opacity: 0; translate: 0 2rem; } }

规则文件

这些技术的可工作示例位于 demos/ 目录中。

相关技能