教學:diffusionstudio/lottie — 用編碼代理生成 Lottie 動畫
1. 專案定位
diffusionstudio/lottie(專案內部代號 Text-to-Lottie)解決的問題是:讓 Claude Code、Codex 這類「支援 Agent Skills 的編碼代理」直接產出可用於生產環境的 Lottie (動畫格式; 又稱 Bodymovin JSON) 動畫檔,而不是讓人工在 After Effects 裡逐幀調整。
它不是一個「Lottie 播放器 library」,而是兩件事的組合:
- 一份 Agent Skill(
skills/text-to-lottie/):把「怎麼寫出有質感的動畫 JSON」這件事,變成代理可以讀取、依任務路由的結構化知識(設計語彙、動效語彙、13 種場景 recipe)。 - 一個 本地播放器 App:用
CanvasKit (Skia 官方 WASM 版本)的 Skottie 模組即時渲染代理寫出的 JSON,讓人和代理都能在瀏覽器裡逐幀檢查結果。
適合的情境:需要 icon/loader 動畫、SVG logo 動畫、下三分之一字幕條(lower third)、資料視覺化動效、產品宣傳片段等「短動畫」需求,且希望用自然語言描述、由代理迭代產出,而非手工關鍵影格。
不適合的情境:長篇影片剪輯、複雜的 3D 動畫、需要精細手動控制每一幀的專業動態設計案(那類案子仍建議用 After Effects + Bodymovin 外掛)。
2. 安裝指南
有兩種使用路徑,取決於你是「只想裝技能到既有專案」還是「要跑官方播放器」。
路徑 A:只安裝 Agent Skill(推薦,最小侵入)
1npx skills add diffusionstudio/lottie
安裝後直接對你的編碼代理(Claude Code / Codex)下自然語言指令即可,例如:
Create a Lottie animation from the SVG path in https://github.com/JaceThings/SF-Hello/blob/main/SVG/hello-en.svg. Reveal the path with an animation that follows the natural path direction. Apply a premium apple themed gradient to the path. Use ease-in-out timing, a transparent background, and preserve the original SVG geometry.
路徑 B:拉官方播放器專案(獨立跑動畫預覽)
1npx degit diffusionstudio/lottie my-animation
2cd my-animation
3npm install
4npm run dev
npm install 會觸發 postinstall(scripts/copy-canvaskit.mjs),把 canvaskit-wasm 套件內的 .wasm 二進位檔複製進 public/,讓 Vite 能以靜態資源提供。開發伺服器預設監聽 3030 port,但 不要假設固定值——若該 port 被佔用,Vite 會自動換下一個可用 port 並印在終端機上(Local: http://localhost:<port>/),务必以印出的實際 port 為準。
前置需求:Node.js(package.json 未鎖死版本,建議 LTS)、Bun(repo 用 bun.lock,但 npm install 亦相容 package.json 宣告的依賴)。
3. 核心架構解析
整個系統分三層:Agent Skill(知識層)、Vite Dev Server(橋接層)、SolidJS Player(渲染層)。代理不會直接操作瀏覽器,而是透過檔案系統與一組 HTTP 端點跟播放器溝通。
flowchart TB
agent["編碼代理
Claude Code / Codex"]
skill["Agent Skill
SKILL.md + 13 篇 references"]
fs["public/projects/<project>/<scene-N>/
lottie.json + controls.json"]
vite["vite-plugins/scenes.ts
/__context /__scenes /__scenes/lottie"]
player["SolidJS Player
CanvasKit + Skottie"]
browser["瀏覽器畫面
逐幀檢查 ?frame=N"]
agent -->|"1. 路由讀取"| skill
skill -->|"2. 產生規則"| agent
agent -->|"3. 寫入/覆寫"| fs
fs -->|"4. 檔案監看 chokidar"| vite
vite -->|"5. WS scene:source 事件"| player
player -->|"6. 渲染"| browser
agent -->|"7. GET /__context 查詢播放狀態"| vite
運作流程說明:
- 代理依
SKILL.md的路由表,只讀取跟任務相符的 recipe(例如 logo 動畫只讀recipe-logo.md+design-taste.md+motion-taste.md),不會整包載入 13 份文件。 - 代理決定目標 scene 路徑(
public/projects/<project>/<scene-N>/lottie.json),並在覆寫前重新讀取現有檔案——因為使用者可能已經透過 UI 調整過controls.json的插槽值並回寫。 vite-plugins/scenes.ts用chokidar(Vite 內建檔案監看)盯著public/projects/:結構性變化(新增/刪除 scene)觸發scenes:update,內容變化(改lottie.json)觸發scene:source,兩者分開處理避免每次自動存檔都整棵樹重掃。- 該檔案有一個關鍵的「回音過濾」設計:
selfWritesMap 記錄外掛自己最後寫入的位元組內容,播放器 UI 透過/__scenes/lottie端點回寫的存檔會被視為「自己的回音」而忽略,只有代理直接改檔案才會觸發即時重新載入。 - 代理可用
GET /__context取得目前播放中的 project/scene、播放狀態、當前幀數(伺服器端用「上次回報時間 + 已播放秒數 × fps」推算,而非串流每一幀),也可加上?frame=N網址參數精確定格檢查。
第二層是「代理如何選擇要寫哪些內容」的知識路由邏輯:
flowchart LR
prompt["使用者自然語言 prompt"]
route{"SKILL.md
路由表比對"}
r1["recipe-logo.md"]
r2["recipe-typography.md"]
r3["recipe-svg-animation.md
+ svg-compatibility.md"]
r4["recipe-data-stats.md"]
common["design-taste.md
motion-taste.md"]
write["寫入 lottie.json
+ controls.json"]
prompt --> route
route -->|"logo/icon"| r1
route -->|"文字/標題"| r2
route -->|"SVG 輸入"| r3
route -->|"圖表/數據"| r4
r1 --> common
r2 --> common
r3 --> common
r4 --> common
common --> write
4. 主要功能詳細用法
4.1 產生新動畫
對代理下指令時,把「素材」「動效語彙」「攝影機語言」講清楚,品質差異很大(詳見第 8 章 FAQ / 進階技巧)。代理會:
- 依
SKILL.md路由表挑對應 recipe; - 解析目標 scene(沒有指定就新建一個安全的新 scene,不會誤蓋掉別人正在編輯的內容);
- 寫出符合 Bodymovin 規格的
lottie.json(必含v、fr、ip、op、w、h、nm、assets、layers頂層欄位)。
4.2 即時預覽與逐幀除錯
播放器網址格式為 /<project>/<scene>,例如 /main-project/scene-1。網址可加 ?frame=N 強制定格在第 N 幀,方便代理或人工檢查特定時間點的渲染結果是否符合預期(尤其是文字排版、路徑動畫的收尾幀)。
4.3 Slots / Controls 可調參數
slots 定義動畫裡可被外部覆寫的值(顏色、文字、位置等),controls.json 則是這些插槽給人看的標籤與可調範圍。src/lib/lottie.ts 的 applySlotValues() 展示了寫入邏輯:文字類插槽要同時寫「slot 定義」和「綁定該 slot 的文字圖層」兩處,其餘型別(數值、顏色、vec2)只需寫 slots[id].p.k。
4.4 匯入既有 Lottie 檔
src/lib/import.ts 的 parseLottieFile() 支援拖入純 .json 動畫,也支援 .lottie(dotLottie 壓縮格式,本質是內含 animations/*.json 的 zip)。匯入後用 createSceneFromDoc() 呼叫 /__scenes/scene 建立新 scene,再呼叫 /__scenes/lottie 寫入內容。
4.5 匯出整個 Project
src/lib/export.ts 的 exportProjectZip() 會把一個 project 底下所有 scene 的 lottie.json(放進 animations/)、圖片(images/)、字型(fonts/)打包成一個 zip 供下載——注意它讀的是「已存檔」的伺服器端來源,不是記憶體裡 Skottie 當下的即時狀態,所以匯出前要確保編輯已回存。
5. 應用場景
- App/網站的 UI 微互動:按鈕點擊回饋、狀態切換(成功/失敗/警告)、載入動畫(loader/spinner)。
- 品牌 Logo 動畫:從既有 SVG 生成 Logo reveal 動畫,可直接匯出跨平台(Web / iOS / Android / Flutter)使用。
- 行銷素材:產品發布宣傳片段、社群貼文用的短動畫、下三分之一字幕條。
- 資料視覺化動效:KPI 數字滾動、圖表繪製動畫、儀表板數據呈現。
- 技術簡報/文件插圖:流程圖走線動畫、架構圖 callout 動畫(本篇教學使用的 Mermaid 架構圖若要動態化,也可以用這套流程生成對應的技術圖動效)。
- 快速原型迭代:設計師/PM 用自然語言描述動效需求,工程師不用手動刻 keyframe,代理直接產出可玩、可調參數的成品供討論。
6. 資安掃描報告
掃描範圍:src/、scripts/、vite-plugins/(.git 排除),比對危險模式(eval、exec、os.system、subprocess、shell=True、網路請求、pickle、動態 input、明文 secret/token/password/api_key 等)。
| 項目 | 結果 | 說明 |
|---|---|---|
| 動態程式碼執行(eval/exec) | 🟢 | 全倉庫未發現 eval()、exec()、Function() 動態執行模式 |
| Shell / 子行程呼叫 | 🟢 | 未發現 subprocess、os.system、shell=True 等模式 |
| 明文密鑰/憑證 | 🟢 | 未發現 secret/token/password/api_key 硬編碼字串 |
| 危險反序列化 | 🟢 | 未使用 pickle 或等效的不安全反序列化 |
| 檔案系統寫入範圍 | 🟡 | vite-plugins/scenes.ts 的 /__scenes/* 端點可寫入/刪除 public/projects/ 下的檔案,但每個路徑操作前都用 path.resolve + startsWith(projectsDir + path.sep) 做路徑穿越(path traversal)防護,屬於合理的本地開發伺服器設計 |
| 對外網路請求 | 🟢 | 掃描命中的 http/node:http 均為型別匯入或 SVG XML 命名空間宣告,非實際對外連線程式碼 |
| 依賴來源 | 🟢 | 依賴均為知名套件(Solid、Vite、CanvasKit、fflate 等),未見不明來源套件 |
結論:🟢 整體風險低。此專案是「本地開發用的 Vite dev server + 前端播放器」,沒有對外服務、沒有雲端 API 呼叫、沒有動態執行使用者輸入。唯一需要留意的是 /__scenes/* 系列端點預設只在 npm run dev(本地開發模式)啟用,不應該把這個 dev server 直接暴露到公網——因為它允許任意建立/刪除 public/projects/ 下的檔案,這在正式環境中並非設計用途,但作為本地工具風險可接受。
7. FAQ
Q1:一定要用 Claude Code 或 Codex 才能用這個技能嗎?
不一定,SKILL.md 明確設計成「可攜(portable)跨 Agent Skills 用戶端」,避免寫死特定平台指令,理論上任何支援 Agent Skills 規格的代理都能使用。
Q2:動畫預設有沒有背景?
依場景類型而定:Logo、icon、loader、疊加層(overlay)、下三分之一字幕條、SVG 衍生素材,預設是透明背景;獨立的全畫面合成(full-frame standalone composition)則預設要有 bgColor 插槽的可見背景圖層。
Q3:可以疊改已存在的 scene 嗎?
main-project/scene-1 只有在它還是「未被動過的預設占位」時才可以覆寫,其他情況一律建新的 scene,避免誤蓋掉正在使用中的動畫。
Q4:生成的 JSON 品質怎麼驗證?
不是靠肉眼看完就結案,SKILL.md 的 Workflow 明確要求「驗證 JSON 格式、跑或沿用 dev server、用 ?frame=N 檢查特定幀、修完渲染/設計/動效問題才算完成」。
Q5:字型渲染有什麼要注意的?
.ttf/.otf/.ttc 檔要放在 scene 資料夾內,CanvasKit 會把每個字型 blob 餵給自訂 SkFontMgr,並用字型檔內嵌的 family name(而非檔名)比對 fonts.list[].fFamily 來解析文字圖層——這也是近期(2026-07 初)多筆 commit 集中修正 font-loading 的原因。
8. 進階技巧
依 README 的「Prompt guide」,寫 prompt 時把以下五點講清楚,成品品質差異明顯:
- 給素材,不要空講:提供真實 SVG、實際數據或截圖,效果遠好於純文字描述。
- 用動效設計術語:
ease-in、ease-out、ease-in-out這類詞彙比「快一點」「慢慢來」精準得多。 - 像攝影師一樣思考:明確描述鏡頭推拉(push)、平移(pan)、縮放(zoom)等運鏡語言,而不只是物件本身的動作。
- 明確要求要暴露哪些 controls:預設只會暴露背景色控制,若要讓文字、位置、顏色等也能被外部調整,要在 prompt 裡明講。
- 指定 FPS 與時長:需要特定影格率或總幀數時直接寫進 prompt,避免代理用預設值。
另一個進階用法:善用 references/chapterization-transition-grammar.md——當你的需求是「多段落」「條列功能」「時間軸」「前後對比」「多語言變體」「章節式」等長內容時,這份文件教代理怎麼做轉場語法,而不是每段各自為政地硬切。
9. 整合進其他工作流
- 搭配本模板的
codex-imageLayer(Layer 24):codex-image目前用於把 Mermaid 圖轉成 editorial 風格靜態 PNG;若未來需要「會動的架構圖」,可以評估用 Text-to-Lottie 產生對應的技術圖動效(recipe-diagram-technical.md),兩者互補而非取代。 - 搭配
kami(Layer 11)簡報/落地頁排版:Text-to-Lottie 產出的 Logo/Loader 動畫可匯出成 Web 格式,嵌入kami產出的 landing page 中增加互動感。 - 匯出跨平台交付:
exportProjectZip()產出的 zip 內含animations/*.json,可直接對接 README 列出的 Web / React Native / iOS / Android / Flutter 整合範例,不需要額外轉檔步驟。
10. 重點摘要 Checklist
- 已理解:本專案 = Agent Skill(知識層)+ SolidJS/CanvasKit 播放器(渲染層),不是 Lottie library
- 安裝路徑已選定:
npx skills add diffusionstudio/lottie(只裝技能)或npx degit+npm install && npm run dev(跑完整播放器) - 已確認 dev server 實際 port(不要假設 3030)
- Prompt 已包含:素材來源、動效術語、運鏡描述、需要的 controls、FPS/時長
- 產出的
lottie.json已用?frame=N逐幀檢查關鍵影格 - 若需要可調參數,已確認
controls.json有對應插槽定義 - 資安確認:dev server 僅限本地使用,未暴露到公網
- 匯出前已確認編輯已回存(
exportProjectZip讀取的是伺服器端已存檔內容)
11. 進一步閱讀
- 官方 repo:https://github.com/diffusionstudio/lottie
- 官網:https://diffusion.studio
- Discord 社群:連結見 repo README 徽章
skills/text-to-lottie/references/player-contract.md— 播放器契約完整規格(scene 路徑解析、target 優先權、agent-facing API)skills/text-to-lottie/references/lottie-spec-map.md— Bodymovin JSON 結構、關鍵影格、插槽、圖層對照表- Lottie 官方規格(Bodymovin)與
lottie-web:https://github.com/airbnb/lottie-web - CanvasKit / Skottie 官方文件(Skia 專案):了解 WASM 渲染引擎底層行為時參考
Comments