Communitygithub.com

Lob0Garou/opus-visual-motion-engine

嚴謹的動態圖形管線:程式碼渲染影片/UI、確定性 seek(t)、自動化渲染 QA、MP4 匯出 — 適用於純文字模型。

opus-visual-motion-engine 是什麼?

Opus Visual Motion Engine 是一個嚴謹的動態圖形管線,專為在 AI 代理(如 Claude Code、Cursor 或 Codex)中生成視覺交付物而設計。它強制執行一個結構化的工作流程:先規劃,再從模板建立,接著渲染、自動化 QA,最後修正與匯出。其核心品質來自於渲染前後的檢查關卡,而非設計者的品味。此技能支援多種平台(影片、動態圖形、網頁 UI、圖表),並透過使用 vanilla JavaScript、GSAP 或 Three.js 等堆疊,確保確定性時間與可重複性。關鍵功能包括自動化持續整合檢查(如重現性、文字碰撞、最小字型大小、可及性)、音訊同步工具以及迭代式的審查循環,即使對純文字模型而言,也能以漸進的方式產生具有目的性設計的輸出,而非通用的人工智慧生成內容。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add Lob0Garou/opus-visual-motion-engine

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Opus Visual Motion Engine

一個嚴謹的視覺交付物管線:規劃 → 從模板建立 → 渲染 → QA → 修正 → 匯出。品質來自渲染前後應用的檢查關卡,而非設計者的品味。請依序執行步驟。即使任務「看起來很簡單」,也不得跳過任何步驟。

以下路徑是相對於此技能的目錄(你所獲得的 skill_resources 基底)。稱之為 $SKILL。

0. 先閱讀(無條件)

在撰寫任何程式碼之前,請閱讀與交付物相符的參考資料。這些資料在相關主題上具有權威性:

交付物閱讀
影片、動態圖形、解說影片、產品影片references/video-generation.md、references/motion-design.md、references/javascript-animation.md
動態字體 / 字型主導作品上述影片組 + references/typography.md
著陸頁、儀表板、Mockup、UIreferences/visual-design.md、references/typography.md
圖表、示意圖、資料視覺化references/visual-design.md §4
構圖 / 鏡頭決定references/cinematography.md
時間與緩動references/animation-primitives.md
需同步的音樂或人聲SKILL.md §10 + references/video-generation.md §6

範例作品位於 examples/*.md。閱讀最接近需求的那個。

1. 先規劃再寫程式碼(請寫出來)

在建立 HTML 之前,先將計劃寫在你的回覆中(或寫在輸出旁的 PLAN.md 裡)。僅存在於腦中的計劃不算數。

UI / 頁面

  1. 主要訊息:一句話。觀看者必須在 3 秒內理解什麼?
  2. 命名方向:一個名稱、4–6 個已命名的十六進位色彩 token 並帶有指定含義、帶有角色的字型、形式處理方式。從主題的產業、材質與慣用語衍生而來。玩具店與金融科技儀表板絕不會共享一個方向。
  3. 層級:用 PRIMARY / SECONDARY / TERTIARY 標記每個區塊。只有 PRIMARY 能獲得那一個大膽的動態效果。
  4. 章節推進:每個章節一行,說明其任務以及如何交接給下一個章節。
  5. 渲染前計算:文字寬度 ≈ chars × 0.55 × font-size(無襯線)或 × 0.5(襯線);盒子寬度 = max(title_chars × 8, subtitle_chars × 7) + 24(在 14px 時);行容納數量 = Σ寬度 + 間距 ≤ 容器。追蹤每個連接器是否穿過每個盒子。如果穿過,則規劃一條 L 形路徑。

影片 / 動態圖形

  1. 核心訊息:一句話。如果需要兩句話,那就是兩支影片。
  2. 節拍:3–7 個。每個節拍回答「觀看者現在知道了什麼?」
  3. 每個節拍的場景卡:開始/結束(秒)、構圖、鏡頭、字型大小、基本圖形(2–4 個)、退出。使用 references/motion-design.md §2 中的模板。
  4. 標誌性時刻:命名出機制被「展示」出來的那唯一一個影格,而非被「標籤化」(例如,雜訊被濾波成信號)。如果故事只能靠其字幕才能運作,請重新設計該節拍。
  5. 全域時間線:絕對時間戳記。一個場景的 EXIT 在下一個場景佔用該空間之前完成。將 DURATION 設定為真正的結束時間(預設 10–20 秒;僅在有旁白時為 30–45 秒)。

沒有場景卡的場景不應出現在影片中。

2. 從模板建立(影片)

將 assets/composition-template.html 複製到交付物旁,並填寫 EDIT 區塊。請勿改寫 ENGINE 區塊。這些區塊已提供:

  • 一個 1920×1080 的 #stage(可為 1080×1920 或 1080×1080 更改 STAGE_W/H),可適應任何視窗;
  • window.DURATION、window.seek(t)、window.render(t)、window.SCENES:用於截圖/匯出的合約(QA 會從 SCENES 擷取每個場景);
  • at()、ease.*、lerp、mulberry32(基於種子的 PRNG),以及用於場景可見性和 EXIT 的 layer();
  • 音訊輔助函式 audioAt(t, "rms"| "low")、since(t, list)、hit(t, list, dur),它們會讀取 window.AUDIO(§10),若無則回傳 0;
  • 一個預覽播放器(空白鍵、←/→、Home/End),在截圖和偏好減少動畫下會自動關閉;
  • 所需的 3 層色彩 token(明亮層、受 prefers-color-scheme 保護的暗層、[data-theme] 層)。

對於頁面,請按照 §6 撰寫一般的單一檔案 HTML。

3. 確定性時間(影片)

  • render(t) 是唯一的狀態驅動者。每個位置、透明度、大小、數字和 dashoffset 都根據以秒為單位的 t 計算得出。seek(x) 會渲染出完全相同的影格,無論之前渲染了什麼。
  • t 以秒為單位。將 t 限制在 [0, DURATION] 內,切勿限制在 [0, 1]:將秒數限制在 0..1 會導致整個時間線靜止不動。
  • 禁止使用: setTimeout、setInterval、CSS 動畫/轉場作為時間線、未設定種子的 Math.random()、狀態中的 Date.now()。requestAnimationFrame 僅能用於推進播放時鐘並呼叫 render(clock)。模板已實作此功能。
  • 隨機性:在構建時從 mulberry32(seed) 生成,切勿在 render 內部生成。
  • SVG 繪製效果需要這三個屬性:pathLength="1"、stroke-dasharray="1" 及 stroke-dashoffset 從 1 到 0。若無 dasharray,線條會從影格 0 開始就完全顯示。
  • inline-block 文字跨度會吞掉尾隨空格。將間距放在 margin-right 中。

4. 動態語法

五種移動,每種各司其職。如果一個動態不屬於以下任何一種,請刪除它。

  • ENTER:每個頁面或場景中一個編排好的序列,按閱讀順序,同層級的元素間隔 60–120 毫秒。每個區塊都做淡入是 AI 的典型特徵。
  • EMPHASIS:一次一個元素:縮放膨脹(≤1.2)、發光或具有含義的顏色變化。
  • TRANSITION:狀態改變。變化的部分移動;其他所有東西保持靜止。0.2–0.6 秒。
  • CAMERA:舞台層級的縮放/平移,每個場景最多一次,0.8–1.2 秒,切勿在閱讀文字期間發生。
  • EXIT:0.3–0.5 秒,完全完成。沒有元素在場景邊界處處於中間狀態,除非是一個刻意的連續性錨點,它保持完全相同或進行變形(同一個物件改變狀態,這是最強的可用轉場)。

轉場傳達意義:硬切 = 類別改變,變形 = 同一事物改變狀態,平移 = 遍歷。切勿到處都使用預設的交叉淡入淡出。時間與緩動請見 references/animation-primitives.md。一起移動的相鄰元素應獲得不同的持續時間或偏移。

5. 堆疊決策

情況堆疊
頁面微動畫transform/opacity 上的 CSS 轉場,0.2–0.6 秒;在 @media (prefers-reduced-motion: no-preference) 內,循環 ≤2 秒
影片 / 動態圖形 / 動態字體模板 + 原生 render(t)(預設)
>6 條交錯軌道或 SVG 變形編排GSAP UMD 固定版本,單一暫停的主時間線,seek(t) → tl.seek(t)
圖表內嵌 SVG(預設)或 Chart.js UMD 搭配 animation:false,使用十六進位顏色(Canvas 無法讀取 CSS 變數)
生成式藝術p5.js 搭配 randomSeed/noiseSeed
3D,僅當 3D 是訊息本身時Three.js UMD 固定版本;鏡頭在 render(t) 中編寫腳本

使用能達成結果的最簡單堆疊。外部腳本必須是來自 cdnjs.cloudflare.com 或 cdn.jsdelivr.net 的明確固定版本。其他所有東西皆內嵌。每個字型都需有一個真正的後備堆疊。

6. 技術底線(無可協商)

  1. 單一 .html 檔案,CSS 和 JS 內嵌,小於 16 MB,圖片/資料做為 data: URI。
  2. 顏色做為 :root token;深色層在 @media (prefers-color-scheme: dark) 下,由 :root:not([data-theme="light"]) 保護,並在 :root[data-theme="dark"] 下重複;明確設定 body 背景色。
  3. meta viewport 搭配 viewport-fit=cover;env(safe-area-inset-*) 內邊距;html/body 使用 height:100%,絕不使用 100vh;寬區塊在其自己的 overflow-x:auto 內捲動;網格使用 minmax(0,1fr)。
  4. 顯示的計算後數字需經過 Math.round、toFixed 或 Intl.NumberFormat。計數器必須精準落在最終數值上。
  5. 可及性:對比度 ≥4.5:1(≥24px 文字為 ≥3:1),可見的焦點,尊重 prefers-reduced-motion(模板顯示最終結束影格)。
  6. 可讀字型:在 1080p 影片影格中,文字不小於 20px (H/54)。在行動頁面上,主體文字不小於 14px。
  7. 瀏覽器儲存空間絕不能用於保存時間線狀態。如有任何使用儲存空間的情況,需將其包裹在 try/catch 中。

7. 避免通用的人工智慧設計

在需求留有餘地之處,切勿將這些預設值作為選項(qa.mjs 會自動標記其中幾項):

典型特徵修正方式
奶油色 #F4F1EA 搭配襯線展示字型 + 陶土色 #D97757 強調色從主題自身的材料中提取色板
接近黑色 + 一種刺眼的強調色,無論主題為何都使用僅在方向能以書面方式證明其合理性時才允許
相同的圓角卡片,到處都是同一種圓角半徑,相同的柔和陰影按層級設定圓角半徑 token;卡片僅用於有限度的物件
作為裝飾的漸層、紫色漸層、玻璃擬態平面填色;最多一個漸層,僅用於表示連續的物理屬性
全大寫標題、中間點元資料字串、連結上的「→」使用句首大寫;刪除重複內容的標籤
預設使用 Inter / 系統字型為此主題選擇字型,並帶有後備堆疊
標題中一個單詞被強調僅當強調色是一個語義 token,且在作品中其他地方用於相同含義時才允許(例如,珊瑚色 = 雜訊)
通用的英雄區:標題 + 副標題 + CTA + 截圖以主題世界中最具特色的事物開場
所有東西都置中,每個區塊都是相同的網格節奏每個區塊使用對齊系統;變化節奏
所有東西同時動起來,到處都是 300ms時間地圖 + 交錯(§4)

將大膽用於一個地方,然後移除一個配件。

8. 渲染 + QA(交付前強制執行)

執行自動化 QA。它會無頭渲染檔案並生成證據與判定。需要 Node ≥18。在技能的全新副本中首次執行需要在 $SKILL/scripts 中執行 npm install(如果 scripts/node_modules 已存在則跳過)。

node "$SKILL/scripts/qa.mjs" path/to/deliverable.html

在 Windows 的 DSH 中,使用相同的命令透過 pwsh 工具執行它。選項:--step 0.25(為快速場景提供更精細的網格)、--out <dir>、--mode page|video。

影片模式(當存在 DURATION + seek 時自動啟用)會每隔一個步驟擷取一個影格並檢查:禁止的 API、亂序重訪的確定性、凍結的時間線、空白段落、近乎空白的跨度、未結束的結束影格、文字碰撞、文字疊在其他圖形上、裁剪、對比度、最小字型大小、從未繪製的 dashoffset 線條、減少動畫模式下的循環、控制台/頁面錯誤以及模板特徵。 頁面模式會渲染桌面 1440、行動 390 及暗色配置,並檢查相同的佈局規則以及行動水平溢出。

輸出位於 qa-<name>/:report.md(判定與發現)、report.json(每個影格的墨水覆蓋率與變化)、contact-sheet.png(所有影格在一張圖片上)、moments.png(取自 window.SCENES 的每個場景的進入點、中點和結束點)、key_000..100.png 和 frames/。

  • 明確傳遞標誌性時刻和任何同步點:--at 5.4,9.1。
  • 刻意的圖層疊加(故意堆疊的動態字體、覆蓋在影片上的標題)應放在帶有 data-qa-allow-overlap 屬性的元素內。這會跳過僅對該子樹的文字碰撞與文字疊圖形檢查。切勿用它來規避意外的碰撞。
  • font WARN 表示首選字型家族未載入,文字正使用後備字型。在判斷佈局之前修正此問題,因為所有寬度都是錯的。

退出代碼 0 = 沒有 FAIL。FAIL 是阻塞性的。 每個 WARN 都必須被修正,或在你的審查中用一句話說明理由。

9. 審查循環

  1. 如果你的模型可以讀取圖片: 開啟 contact-sheet.png,然後是任何看起來有問題的 key_*.png。判斷像素,而非你的意圖。
  2. 如果你的模型是純文字: 使用 report.md 加上 report.json 中的每個影格表格。coverage < 0.015 表示該影格內容空白。一個場景的 diff 為 0 表示沒有任何東西在移動。diff 的峰值標示著一次切換。交叉比對每個場景卡的時間戳記與這些數字。
  3. 用具體的觀察結果回答每個問題,而不是打勾:
    • 構圖:在每個關鍵影格中,視線首先落在哪裡?那是要傳達的訊息嗎?
    • 層級:PRIMARY 是否清晰可辨?每個影格中是否恰好只有一個重要的移動元素?
    • 機制:標誌性時刻是否在移除字幕的情況下「展示」了概念?
    • 連貫性:所有交接是否乾淨,沒有元素處於邊界的中間狀態,且錨點相同或正在變形?
    • 時間:是否有偏移,沒有預設持續時間,且閱讀時間 ≥ 每 8 個字 1.2 秒?
    • 字體排版 / 對比度 / 密度:依照計劃的大小,每個影格內 ≤5 個競爭元素,在暗色模式下可讀?
    • 敘事:觀看者能否在觀看一次後重複核心訊息?
  4. 修正 → 重新執行 qa.mjs → 重新審查。重複直到 QA 通過且審查中沒有任何未解決的項目。
  5. 最後一個問題,誠實回答:「這看起來是有意設計的,還是僅僅是生成的?」 如果答案是「生成的」:指出什麼是通用的,修改計劃(§1),然後重建。第一次渲染幾乎從不是最終交付物。預計需要 2–3 次生成。

10. 音訊同步(當有音樂或人聲時)

切勿靠耳朵猜測時間。將音訊轉換為資料,讓 render(t) 讀取它:

node "$SKILL/scripts/audio-data.mjs" music.mp3 --inject composition.html   # 將 window.AUDIO 寫入 HTML
  • AUDIO.beats(以估計節奏均勻間隔的網格)、AUDIO.onsets(打擊、音符、音節),以及每個影格的 AUDIO.rms / AUDIO.low(0..1;low 是 <150 Hz 的鼓點/低音樂段)。
  • 使用模板輔助函式驅動動態:hit(t, AUDIO.beats, 0.2) 用於節拍脈衝(EMPHASIS)、audioAt(t, "low") 用於對鼓點反應的縮放、since(t, AUDIO.onsets) 用於逐次打擊的揭示。將場景切換放在節拍上:從 AUDIO.beats 挑選場景開始點。
  • 同步透過構建在影格層級精準:一個脈衝落在其節拍時間點或之後的第一個影格上(≤1 影格,30 fps 時 ≤33 毫秒)。如果音訊開始時間晚於 t=0,請傳遞 --offset <s>。
  • 在任何人在聆聽之前就會檢查音量大小。修剪過的樣本會導致退出碼 1。樣本峰值高於 −1 dBFS 會發出警告,因為 AAC 編碼會將其削波。會報告 LUFS 低於 −18 或高於 −12 的音量(平台會將其標準化到大約 −14)。
  • --bpm 可覆蓋

相關技能