系統定位與儲存庫結構
Bang Motion(bangtutorial/bang-motion)是一套供程式開發 Agent 使用的動態圖形(Motion Graphics)技能與 Claude Code 外掛。輸入為產品主題、品牌色彩與字體來源、旁白音訊或參考節奏;輸出為單一可雙擊開啟的 index.html,開啟後自動播放並循環,無須執行 npm install 或啟動本機伺服器即可觀看。
此技能以瀏覽器作為渲染引擎,結合 HTML、內嵌 CSS、SVG 濾鏡,以及透過 HTTPS CDN 載入的 GSAP 與 Three.js。使用者若需交付影片檔,可再透過隨附的 Puppeteer 腳本逐格輸出 PNG 並以 ffmpeg 合成 MP4,或在連接 Higgsfield MCP 橋接器時直接於 Adobe After Effects 建立圖層。
| 目錄或檔案 | 核對數量 | 用途 |
|---|---|---|
SKILL.md | 1 個主規格檔 | 定義 4 項核心法則、8 項結構禁令、10 種風格方向、編號 0 至 7 的工作流與 39 項交稿檢查清單 |
.claude-plugin/ | 2 個設定檔 | plugin.json 與 marketplace.json,供 Claude Code 外掛市集安裝 |
assets/ | 7 個 HTML 骨架 | starter-opener.html 與 6 種解說影片(Explainer)起始架構 |
references/ | 8 份技術參考文件 | 涵蓋反簡報規則、19 種開場概念、舞台架構、動態技法、卡通舞台與 AE MCP 橋接 |
scripts/ | 5 支工具與 3 支 AE 腳本 | 包含 snap.mjs、export-frames.mjs、serve.py、vo-pauses.html、kepala-ekspresi.py 與 scripts/ae/bridge/ |
安裝與驗證
- 未完成:
已安裝支援
SKILL.md的 Agent 工具(Claude Code、Codex、Cursor、Windsurf、Antigravity、Cline 或 Aider)。 - 未完成:
已準備支援 WebGL 與 ES Module 的現代桌面瀏覽器,且播放時具備網路連線以載入 CDN 函式庫與字體。
- 未完成:
選用:安裝 Node.js 與
puppeteer,供scripts/snap.mjs關鍵秒數截圖驗收與scripts/export-frames.mjs逐格匯出使用。 - 未完成:
選用:安裝
ffmpeg以將 PNG 序列編碼為 MP4,安裝 Python 3 以執行scripts/serve.py無快取開發伺服器或角色表情腳本。
在 Claude Code 內可直接透過外掛市集指令安裝:
/plugin marketplace add bangtutorial/bang-motion
/plugin install bang-motion@bang-motion若使用手動技能目錄或 Codex,將儲存庫複製至對應路徑。以下路徑擇一,外掛與手動安裝也擇一,避免同名技能重複;Claude Code 單一專案可改放 .claude/skills/bang-motion:
git clone https://github.com/bangtutorial/bang-motion.git ~/.claude/skills/bang-motion
git clone https://github.com/bangtutorial/bang-motion.git ~/.codex/skills/bang-motion在 Cursor、Windsurf、Antigravity、Cline 或 Aider 中,將儲存庫複製至工作區後,於專案規則或技能設定指向 SKILL.md。若需使用視覺截圖驗收與 MP4 匯出,將 Puppeteer 安裝在腳本所屬的技能根目錄,讓 Node.js 能從腳本路徑解析套件。以下以 Claude Code 的手動安裝位置為例;使用其他位置時請調整 --prefix:
npm install --prefix ~/.claude/skills/bang-motion puppeteer
ffmpeg -version舞台架構與反簡報規格
Bang Motion 以固定解析度舞台加上單一時間軸解決網頁動畫常見的排版漂移與掉格問題。#stage 固定為 1920×1080 像素,僅透過 Math.min(innerWidth / 1920, innerHeight / 1080) 進行整體縮放,確保不同螢幕尺寸與匯出錄製時的相對座標一致。
攝影機層 #world 同時包覆 WebGL <canvas>、漸層覆蓋層 .bgfx 與所有文字及介面 DOM 節點 #dom;光斑 .leak、暗角 .vignette 與顆粒 .grain 則置於 #world 之外,維持鏡頭前景效果。當攝影機推進或平移時,3D 背景與文字會同步位移,避免只有文字縮放的投影片感。
| 規格項目 | 強制約束 | 工程目的 |
|---|---|---|
禁用 <section> 淡入切換 | 禁止以多個全版 <section> 搭配 opacity 或 autoAlpha 輪流顯示 | 避免退化為自動播放的投影片(Slide Deck) |
| 單一時間真理來源 | 所有 DOM 與 Three.js 狀態皆為 tl.time() 的確定性函數;渲染迴圈禁用 Math.random()、Date.now() 與 pos += v * dt 累加 | 支援任意秒數拖曳(Scrub)與零掉格逐格匯出,每次重跑皆輸出相同像素畫面 |
| 絕對秒數定位 | GSAP 時間軸統一寫絕對秒數(如 8.10),不依賴連鎖相對偏移 | 直接對應分鏡表秒數,調整單一場景時不會牽動後續段落 |
| 文字層級與最小字級 | 單一畫面最多 2 個文字層級;1080p 舞台上字級不得低於 30px(內文 >= 44px、標籤 >= 34px、來源註記 >= 30px) | 確保行動裝置觀看時清晰可讀,防止資訊塞滿畫面 |
| 文字袋對比度 | 文字下方區域亮度須 <= 25%(深色底)或 >= 80%(淺色底),袋內背景元素透明度 <= 0.35;發光(Bloom)僅用於物件而非標題字 | 避免發光粒子或中灰背景吃掉標題筆畫 |
window.OPENER 匯出契約 | 頁面必須暴露 { W, H, ready, seek(t) }(含影片圖層時另含 seekFrame(t) 與 clipsReady()),且 ?clean=1 須隱藏控制列並暫停自動播放 | 讓 snap.mjs 與 export-frames.mjs 能精確鎖定時間點擷取畫面 |
SKILL.md 第 3 法則要求寫程式前先提交風格簡報(Style Brief)與分鏡秒數表(Rundown)供使用者核准。風格簡報須自品牌標誌或產品介面提取主色,並挑選具辨識度的展示字體(排除 Inter、Roboto、Poppins、Montserrat 與 Arial,產品原生 UI 概念除外)。結構則自 10 種風格方向與 references/opener-konsep.md 的 19 種開場概念選取,不得保留 starter-opener.html 的灰色佔位外觀或照搬參考影片的配色與文案。
模板與工具介面
開場與宣傳
assets/starter-opener.html
產品開場與動態字體骨架
提供 1920×1080 舞台、#world 攝影機、狀態驅動 Three.js 場景與 8 種文字進場工具。預設灰色與系統字僅為佔位符,啟動後須立即替換為品牌 token。
解說影片
assets/starter-explainer*.html
6 種解說影片起始架構
依主題選用連續動作、卡通拼貼、視覺新聞、白底型錄、復古素描或卡通舞台骨架;動筆前須先以單一問題確認風格、比例(預設 16:9)、時長與旁白來源。
旁白對齊
scripts/vo-pauses.html
瀏覽器端旁白停頓偵測
免安裝 ffmpeg 的 Web Audio 工具。雙擊開啟並載入音訊後,依預設 -30 dB 門檻、0.45 秒最短停頓與 0.8 秒段落邊界輸出 SEG、PARA 與 DUR 時間陣列。
畫面驗收
scripts/snap.mjs
關鍵秒數截圖檢查
透過 Puppeteer 以 file:// 開啟 index.html?clean=1,呼叫 OPENER.seek(t) 擷取 6 至 20 個關鍵時間點 PNG,供 Agent 檢查裁切、重疊與轉場時序。
影片匯出
scripts/export-frames.mjs
逐格無掉格 PNG 渲染
依 FPS(預設 60)與 SCALE(預設 1)逐格定位時間軸並等待兩次 requestAnimationFrame 後存成 f00000.png 序列,再交由 ffmpeg 壓製為 H.264 MP4。
AE 橋接
references/ae-bridge-higgsfield.md
After Effects 直接建構流程
當 After Effects 開啟且連接 Higgsfield ae_* MCP 工具時,以小型 Lottie 建立合成骨架、搭配 aset-svg.py 與 rig-tokoh.py 建立 2× PNG 資產與原生關節角色。
依主題與素材型態選擇對應的 6 組解說影片骨架:
| 骨架檔案 | 風格定位 | 內建舞台與字體配置 |
|---|---|---|
starter-explainer.html | 連續動作(向量) | 持續流動的世界場景、常駐主角(出現逾 60% 時長)、地圖視角與甩鏡(Whip)轉場 |
starter-explainer-kartun.html | 卡通拼貼 | 奶油紙張底紋加顆粒與污漬、插畫剪影、Bricolage 搭配 Caveat 字體、色塊膠囊標記 |
starter-explainer-jurnalisme.html | 視覺新聞 | 深黑顆粒背景、真實照片加來源標籤、Barlow Condensed 搭配 Plex Mono、黃紅螢光筆標註 |
starter-explainer-katalog.html | 白底型錄 | 淡網格白底、去背照片剪影、Archivo Black 搭配 Caveat 與 Inter、黃色重點標記 |
starter-explainer-sketsa.html | 復古素描 | CSS 深褐紙張紋理、multiply 混合模式雕版剪影、Playfair 搭配 Garamond 與 Cinzel |
starter-explainer-panggung.html | 卡通舞台 | 每場獨立舞台與攝影機(縮放 1.08–1.95)、J() 手動關節代理變形、character() 角色與 96px 橫移轉場 |
操作原則
先鎖定風格簡報與分鏡秒數表再寫程式碼
修改時間軸程式碼的耗時高於調整文字分鏡。動筆前必須列出品牌色碼與來源、展示字體、背景運動語言、代表性動作,以及 25 至 40 秒的「秒數|場景|文案|視覺」分鏡表,獲使用者確認後才複製起始骨架。
區分關鍵秒數驗收與全片逐格匯出
60 秒 60 fps 影片共有 3,600 張圖,全片渲染耗時且無法取代構圖檢查。每次修改後僅用 snap.mjs 拍攝 6 至 20 個場景起點與文字進場秒數,組合成縮圖表檢查文字裁切與對比;只有使用者明確要求 MP4 時才執行 export-frames.mjs。
以 clip() 綁定實拍或錄影素材圖層
直接放置帶 autoplay 與 loop 的 <video> 會讓影片脫離主時間軸並阻礙逐格匯出。v1.18.0 起實拍或螢幕錄影須透過 clip(el, { at, in, out, rate, hold }) 掛載為受控圖層,並以 snap.mjs 驗證含影片秒數的畫面。
開發期用無快取伺服器,交付期合併為單一檔案
多檔開發時 python -m http.server 會讓瀏覽器快取舊的 ES Module;應改跑 python3 scripts/serve.py(預設連接埠 5178,強制送出 Cache-Control: no-store)。最終交付時須將 CSS 與 <script type="module"> 全數內嵌回單一 index.html,避免 file:// 下觸發 CORS 阻擋。
操作範例
完成單檔 index.html 後,先在專案目錄執行無伺服器關鍵秒數截圖驗收,確認構圖與時序後再啟動無快取伺服器並匯出 1920×1080、60 fps 的 MP4 檔案。
在包含
index.html的專案目錄執行snap.mjs,傳入輸出資料夾與欲檢查的秒數(預設自動開啟目前目錄的file:///.../index.html?clean=1)。檢視
shots/下的 PNG 截圖,確認標題未與背景粒子重疊、無殘留灰色佔位樣式,且攝影機位移完成後文字才進入停駐狀態。需要輸出 MP4 時,於背景或另一終端機視窗啟動
serve.py(預設http://127.0.0.1:5178),再執行export-frames.mjs與ffmpeg。
$ node ~/.claude/skills/bang-motion/scripts/snap.mjs shots 0.5 3.5 8 14.5 22 28
0.5 3.5 8 14.5 22 28
selesai
$ ls shots
t0_50.png t3_50.png t8_00.png t14_50.png t22_00.png t28_00.png
$ python3 ~/.claude/skills/bang-motion/scripts/serve.py 5178 &
serving on http://127.0.0.1:5178 (no-store)
$ FPS=60 OUT=frames SCALE=1 node ~/.claude/skills/bang-motion/scripts/export-frames.mjs
1800 frame @ 60 fps (30s) -> frames/
selesai — 1800 frame di frames/
$ ffmpeg -framerate 60 -i frames/f%05d.png -c:v libx264 -pix_fmt yuv420p -crf 16 opener.mp4若專案為旁白驅動的解說影片,先在瀏覽器開啟 scripts/vo-pauses.html 載入錄好的 .wav 或 .mp3,將輸出的 const SEG=[...]; const PARA=[...]; const DUR=...; 貼入時間軸設定,使每個場景的起始時間 t0 對齊旁白段落起點。
限制與注意事項
| 邊界情境 | 已知限制 | 官方處理方式 |
|---|---|---|
| SVG 動態模糊濾鏡遭裁切 | SVG <filter> 預設邊界盒會切斷高速移動文字的模糊拖尾 | 手動加寬濾鏡的 x、y、width 與 height 範圍 |
| 扁平 3D 物件繞 Y 軸整圈旋轉 | 旋轉至 90 度側面時會退化成一條細線 | 改用有限角度擺動(Wobble),避免完整 360 度翻轉 |
卡通舞台使用 GSAP transformOrigin 轉動關節 | 群組含 translate 時混用 GSAP rotation 與 x/y 會造成關節錯位 | 依 kartun-panggung.md 改用 J() 手動代理變形(Proxy Transform) |
| After Effects Higgsfield MCP 橋接限制 | ae_reorder_layers 呼叫會回傳找不到圖層;新增的 CAM 空物件預設位於 (960, 540);橋接器無法存檔或渲染影片 | 依由後往前的堆疊順序建立圖層;綁定父子關係前先將 CAM 的錨點與位置歸零至 [0, 0];完工後提醒使用者手動按 Ctrl+S 並以 Render Queue 或 aerender.exe 輸出 MP4 |
後續操作
設計產品開場或宣傳片前,先閱讀
references/opener-konsep.md,從 19 種結構概念中挑選 3 個候選方案並記錄結構指紋(場景數、每場主物件、開場與收尾方式),避免不同產品產出相同骨架。製作角色解說動畫時,對照
references/kartun-panggung.md與scripts/kepala-ekspresi.py,檢查每場是否維持>= 1.08攝影機縮放與至少 10 個動態元素。匯出無聲或僅含旁白的 MP4 後,如需加入開放授權真實音效、多模態音畫同步生成與響度/同步率量化檢查,可串接 Openverse、MMAudio 與 Earshot 音效處理流程。