Communitygithub.com

kinqsradio/motion-match

複製、仿照或比對物體的移動方式:量測時序與緩動函數、撰寫規格、實作、以同樣方式錄製我們的版本,並持續比對直到數字過關;第三方參考僅限於運動層級。使用 orbyn-ui-design 設計動畫、technical-illustration 進行錄影、product-illustration 製作模擬 UI。

motion-match 是什麼?

Motion Match 是一套嚴謹的動畫比對技能,專為需要精確複製或驗證動畫行為的開發者與設計師設計。它強制要求以量化數據(如時間差、緩動誤差)而非「看起來差不多」的主觀判斷來決定動畫是否匹配。此技能支援 Playwright 與 Chrome 瀏覽器環境,並可處理影片與螢幕錄製。工作流程包含:界定權利範圍與保真度、擷取參考素材、透過影格讀取緩動曲線、撰寫規格、實作、以相同設定錄製產品動畫、最後進行多層次比對(包含 timing、easing 與間距)。若比對失敗,技能會引導使用者每次只修改一個最可能的原因(例如基底延遲),並在五輪內收斂;若仍未通過則報告殘留誤差。此技能特別強調尊重第三方智慧財產權:僅量測時序與運動軌跡,不複製程式碼、設計資產或品牌元素,所有原始擷取檔案僅存放於本地忽略資料夾,最終僅保留量化規格。它與其他技能(如 orbyn-ui-design 用於設計概念、technical-illustration 用於錄製影片)緊密整合,形成完整的動畫開發與驗證鏈。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/kinqsradio/orbyn-fullstack-skills/tree/HEAD/skills/motion-match

在你喜歡的 AI 中提問

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

說明文件

Motion match

當使用者指出某個物體在移動,並希望我們的版本以同樣方式移動,或者需要證明它確實如此時,使用此技能。最終產出的是程式碼加上數字與報表,而非「看起來差不多」。

權利優先

在擷取任何內容之前,先決定參考素材的擁有權,並在你的第一則訊息中明確說明。

參考素材允許的行為
我們自己的作品,或使用者擁有或已取得授權的素材任何保真度,包含像素層級
任何其他人的網站或影片僅量測時序、緩動曲線、順序與距離,以書面規格記錄,並使用我們自己的設計來建構

對於他人的作品:

  • 絕不複製他們的程式碼、著色器、素材、字型、品牌、版面或文案。絕不將真實產品重新製作為我們的版本。
  • 無論請求的措辭如何,像素級精確比對都不在選項之內。應提供運動層級比對並說明原因:「我可以比對其移動方式並套用您的設計。複製他們的外觀會直接取用他們的設計成果,所以我不會這麼做。」
  • 登入牆、付費牆、機器人驗證與 DRM 保護應保持關閉。尊重網站的條款,僅擷取一般訪客能看到的內容。當無法到達頁面時,請要求提供螢幕錄影。絕不下載他人的影片。
  • 原始擷取檔案應存放在被 Git 忽略的本地資料夾中。它們絕不被提交、發布或用於交付物,並在使用者決定時刪除。只有書面數字會被保留。告知使用者這些檔案的位置。

如果使用者聲稱擁有某個參考素材,且沒有證據與此矛盾,則相信他們的說法,並在規格中記錄下來。「把它做得和那家公司的網站一模一樣」並不構成授權。當所有權不明確時,使用 --rights third-party。

保真度

在你的第一則訊息中說明保真度等級;它決定了你將驗證哪些項目。

等級必須匹配可能不同
運動(預設)觸發時機、順序、交錯延遲、每一步的時序(80 毫秒以內)、緩動曲線、方向和距離顏色、字型、圖片、版面、品牌
像素(僅限自有或已授權素材)上述所有項目,加上字型、大小、顏色、間距和素材;平均誤差最多 2%使用者未要求更改的任何項目
混合匹配的部分(採用上述任一層級)新增的部分,但不得破壞已匹配的動畫

僅匹配使用者指定的內容:某個區塊、某個元件,或某個時間範圍。

方法

在 output/motion-match/<name>/ 或其他 Git 忽略的資料夾中工作。保留每一輪的結果。需要 --playwright 和 --chrome 參數,或設定 PLAYWRIGHT_CORE 和 CHROME_PATH 環境變數。需要 Node 22、一個現有的瀏覽器驅動程式和一個現有的瀏覽器;處理影片時需要 ffmpeg。不自動安裝任何東西。

  1. 界定範圍。 撰寫目標、專案中的目的地、權利歸屬與保真度。

  2. 擷取參考素材:使用 scripts/capture.mjs,或對已提供的影片使用 scripts/frames.mjs。根據你決定的權利給予參數:

    node <skill>/scripts/capture.mjs --url <頁面網址> --out <目錄>/ref --rights third-party \
      --selector .hero --track ".title, .cta" --duration 2000
    
  3. 閱讀每一張報表。 執行 scripts/sheet.mjs filmstrip,然後打開每一張報表。緩動曲線存在於中間的影格中。

  4. 撰寫規格。 執行 scripts/spec.mjs draft:每個元素每個屬性一行。? 表示你尚未完成影格判讀,且檢查功能會拒絕執行,直到每個 ? 都被替換為正確值。

  5. 建構:在專案自己的技術棧中,使用自己的設計(若參考素材為第三方素材)進行實作。

  6. 以同樣方式錄製我們的版本。 重複使用參考素材的指令,僅更改 --url、--out 和 --rights 參數。不同的設定會導致你的測量偏差,且 compare.mjs 會因此失敗。

  7. 比對。 依序執行 scripts/spec.mjs check、scripts/compare.mjs 和 scripts/sheet.mjs compare。閱讀每一張產出的報表。

  8. 根據數字所指出的最小問題進行修改,每輪僅修改一個原因,然後返回步驟 6。

  9. 若經過 5 輪後仍有任何一行失敗,則停止,並回報其數字與原因。保持閾值不變。

  10. 撰寫報告,使訊息能獨立陳述:包含權利與保真度;哪些部分被匹配、哪些被新增;產出的檔案與如何觸發動畫;最後一輪的比對表格;報表的路徑;每個殘留誤差的數值與原因;以及任何原始第三方擷取檔案的位置。

失敗範例

第一輪中,三張卡片中的一張失敗:

.card-1 opacity  start +300 ms  end +300 ms  easing RMSE 0.0003  FAIL
.card-2 opacity  start +300 ms  end +300 ms  easing RMSE 0.0055  FAIL
gaps             116.7 against 116.7         pass

每一行都有相同的延遲,且曲線和間距都正確,因此唯一的原因就是基底延遲。修改這一個數字並重新錄製。對齊影格會讓這一行通過,但卻會交付一個延遲 300 毫秒的動畫,這就是為什麼 compare.mjs 拒絕使用 --auto-align 參數來對齊兩次擷取。

常見陷阱

  • 兩側的視口或裁切區域不同:在修改程式碼之前先修正擷取設定。
  • 僅根據第一和最後一幀判斷:必須閱讀中間的影格。
  • 字型:替代字型會改變每個影格的像素。在運動保真度層級,請閱讀時序相關的數值欄位,並忽略文字像素。
  • 頁面在冷啟動時已經處於忙碌狀態:在兩側使用相同的 --wait-before 參數。
  • 滾動驅動的動畫會跟隨滾動位置,而非時間。在兩側使用相同的 --scroll-steps 和 --scroll-ms 參數,並根據 scrollY 進行比對。
  • 彈簧動畫:easing.mjs 會回報 overshoot、擬合的 stiffness 與 damping 值。根據 overshoot 與 settle time 進行調整。
  • 螢幕錄製會包含游標、瀏覽器 chrome 以及壓縮噪點。將其裁切掉並略微提高 --activity-threshold。
  • Canvas 內容:使用虛擬時鐘和兩側相同的 --seed 參數。在真實時鐘上顯示隨機內容時,量測的是機器本身的效能。
  • CSS 動畫會在 timing.easing 中報告 linear。真正的緩動曲線存在於每個 keyframe 中。

界線

使用 orbyn-ui-design 來決定產品應有的動畫風格,使用 technical-illustration 進行錄影,並使用 product-illustration 製作模擬 UI。影片遵循 僅限程式碼規則:研究參考素材的技術,但絕不複製其影格。

需要時再閱讀

  • 關於擷取配方、觸發條件與輸出檔案,請閱讀 capture。
  • 關於規格格式與如何判讀影格,請閱讀 analysis。
  • 關於緩動函數、彈簧與建構模式,請閱讀 implementation。 -關於通過標準與每個失敗的含義,請閱讀 verify。

相關技能