Communitygithub.com

yuzhang-ai/web-animation-skill

設計並建構具互動性的網頁動畫,使其感覺精緻而非模板化。當使用者要求在網站或網頁應用程式中加入動態效果時使用——例如頁面載入或主視覺序列、滾動驅動或觸發的效果、視差、固定或橫向滾動區域、平滑滾動、文字揭示與分割、滑鼠懸停與按壓的微互動、頁面或路由轉場(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 是什麼?

此技能提供了一套完整的網頁動畫設計與實作工作流程,專注於使動畫成為設計決策而非單純的函式庫呼叫。它首先引導使用者閱讀專案現狀(如 package.json 與框架),判斷是否已有動畫庫,並檢視現有的動畫標記(如 CSS 變數中的持續時間與緩動函數),以確保一致性並避免重複引入。接著,它根據動畫的「任務」(回饋、導航、吸引注意、敘事)來選擇合適的工具,從最輕量的 CSS 轉場與 @keyframes,到 GSAP + ScrollTrigger 的複雜時間軸,再到 Motion、Anime.js、Lottie、Rive、D3、Konva 或 Three.js 等專用庫,並提供詳細的規則文件協助決策。技能強調幾項不可妥協的原則:僅動畫化 transform 與 opacity 以保持效能、尊重 prefers-reduced-motion、避免在 JavaScript 執行前隱藏內容、清理動畫以防止記憶體洩漏、保持互動即時中斷、以及確保焦點管理正確。最後,它要求在真實瀏覽器中驗證,檢查結束狀態、錯誤、減少動畫模式、響應式行為、反向滾動與效能面板,確保動畫在所有情況下都正確且高效。此技能支援多種平台,包括 React/Next.js、Vue、Svelte 及純 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. 切勿在 JavaScript 執行前隱藏內容。 在 JavaScript 中(或透過 .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/。

相關技能