Communitygithub.com

og-image-animated

將專案的 Open Graph 分享卡片轉換為幾秒鐘的網頁動畫,包含品牌標誌與標題從頂部落入,應用程式畫面從底部升起並最終靜止於最終卡片的完整流程。

og-image-animated 是什麼?

此技能可為專案的 Open Graph 分享卡片創建一段簡短流暢的網頁動畫,讓靜態卡片變得生動。它支援將動畫輸出為 MP4、GIF 以及最終幀的 PNG 檔案。動畫過程包含品牌標誌與標題從頂部淡入滑落,以及應用程式視窗從底部淡入升起,整體節奏約 2-2.5 秒,最後停留約 1.5 秒。它適用於 Claude Code、Cursor 等需要生成動態社交分享預覽的開發工具,亦可應用於 README、產品頁面或支援 `og:video` 的社群平台。其工作原理是透過 CSS 關鍵幀動畫控制過渡,並使用 Playwright 與 ffmpeg 逐幀擷取渲染結果,確保每次輸出一致且無掉幀。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/paralect/saas-skills/tree/HEAD/skills/og-image-animated

在你喜歡的 AI 中提問

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

說明文件

動畫 OG 圖片

此技能使用的所有檔案都存放在自身資料夾(與此 SKILL.md 相鄰)中,路徑皆相對於該資料夾。此技能不需依賴其他技能或資料夾,請勿四處尋找。除非使用者指定其他位置,否則所有產出都儲存在目前專案的 out/og-image-animated/ 目錄下。

靜態分享卡片以短暫、平緩的揭曉動畫呈現:

  1. 空卡片:僅有背景與柔和光暈。
  2. 品牌標誌和標題從頂部落入(淡入 + 向下滑動)。
  3. 應用程式視窗從底部升起(淡入 + 向上滑動)並準確定位到靜態卡片上的位置。
  4. 停留於最終幀,該幀必須與靜態 OG 圖片完全相同。

範例:references/pulse.gif(結果)與 references/pulse-frames.png(四個幀:開始、標題進入、應用升起、最終成品)。

規則

  • 從靜態卡片開始。 如果專案尚未有 OG 卡片元件,請先遵循 references/static-card.md 建立(使用真實產品、目前網站的訊息以及實際資料)。動畫僅加入動作:使用相同標記、相同最終佈局,不加入新內容。
  • 單一元件,兩種模式。 在現有卡片元件上新增 animated 屬性,而不是複製一份,以確保靜態 PNG 與動畫永不偏離。沒有該屬性時,則不會有任何動畫效果。
  • 僅動作,無特效。 只使用 opacity + transform: translateY,並共用一個緩出曲線(cubic-bezier(0.16, 1, 0.3, 1))。無彈跳、模糊、縮放彈出、打字機文字或旋轉元素。
  • 簡短。 整個時間軸約 2–2.5 秒,之後停留約 1.5 秒。標題必須在約 1.3 秒時完全可讀。
  • 僅使用 CSS 動畫(keyframes + 帶有 both 填充的 animation),不可在卡片內使用 JS 驅動的補間或計時器。錄製器透過 Web Animations API 擷取 CSS 動畫;JS 驅動的動作無法被確定性捕獲。

時間軸

元素關鍵幀持續時間延遲
品牌標誌從 opacity: 0; translateY(-48px)900ms100ms
標題從 opacity: 0; translateY(-48px)1000ms250ms
應用視窗從 opacity: 0; translateY(320px)1300ms700ms

根據卡片調整距離:應用程式應從底部邊緣下方(約卡片高度的一半)開始,標題則應從其靜止位置上方自身高度處開始。如果存在浮動面板,則讓它在視窗開始後 +200ms 抵達。

步驟

1. 探索

  • 找到靜態卡片元件及其渲染路由(例如 og-image.tsx、/og/<page>),以及 public/ 中的目前 PNG。
  • 記下品牌標誌、標題和應用視窗的包裝器。如果視窗使用 zoom 來適配,則對內部包裝器進行動畫處理,而不是已縮放的元素,以確保偏移量正確。

2. 加入動畫模式

在卡片元件中:

const KEYFRAMES = `
@keyframes og-drop { from { opacity: 0; transform: translateY(-48px); } to { opacity: 1; transform: none; } }
@keyframes og-rise { from { opacity: 0; transform: translateY(320px); } to { opacity: 1; transform: none; } }
`;
const EASE = 'cubic-bezier(0.16, 1, 0.3, 1)';
const enter = (name: string, ms: number, delay: number) => ({ animation: `${name} ${ms}ms ${EASE} ${delay}ms both` });

// <div data-og-frame …>{animated && <style>{KEYFRAMES}</style>} …
// brand:  style={animated ? enter('og-drop', 900, 100) : undefined}
// title:  style={animated ? enter('og-drop', 1000, 250) : undefined}
// window: <div style={{ zoom }}><div className="h-full" style={animated ? enter('og-rise', 1300, 700) : undefined}>…

將關鍵幀放在元件(<style> 標籤)或專案的全局 CSS 中;使用 Tailwind v4 時,@theme 內的關鍵幀僅在使用了對應的 --animate-* token 時才會被產生,因此建議將其放在元件或純 CSS 中。

3. 加入播放動畫的網頁路由

作為靜態路由的同級路由,例如 /og/<page>-animated(設定 noindex,無應用程式外框):

  • 在 1200×630 的框架內渲染 <Card animated />。
  • 預覽時重播:透過每隔約 4.5 秒更換 key 來重新掛載卡片。
  • ?loop=0 只播放一次(錄製器使用此參數)。首先將搜尋參數正規化為字串:像 TanStack 這樣的路由器會將 ?loop=0 解析為數字 0,而一項漏掉的檢查會導致在錄製過程中不斷重新掛載卡片。

在瀏覽器中開啟它並觀看幾次。檢查進入順序,確保動畫開始前沒有任何閃爍,並且最終狀態與靜態卡片相符。

4. 錄製 MP4 + GIF

在開發伺服器運行時:

node <此技能資料夾>/scripts/record.mjs \
  --url "http://localhost:<port>/og/<page>-animated?loop=0" \
  --out out/og-image-animated/og-<page>

寫入 og-<page>.mp4(2400×1260,H.264,30fps)、og-<page>.gif(1200px 寬,調色板優化,循環播放)以及 og-<page>.png(最終幀)。運作原理:它暫停頁面上的所有動畫,讀取時間軸長度,然後逐幀尋找所有動畫並對 [data-og-frame] 區域進行螢幕截圖。每次執行的結果都相同,不會掉幀。選項:--fps、--hold、--lead、--scale、--formats mp4,gif,png、--selector。

需要在 PATH 中有 ffmpeg。Playwright 會在首次運行時安裝到此技能的 scripts/ 資料夾中,如果找不到 Chromium 也會一併安裝。

注意事項:

  • 頁面不得強制啟用減少動畫模式。許多全局樣式表會在 prefers-reduced-motion 下縮短動畫;錄製器不會模擬此設定,而且如果找不到任何動畫,它會大聲報錯。
  • 元素螢幕截圖會等待「穩定」,但動畫進行中永遠不會穩定。這就是為什麼腳本會裁剪頁面區域。
  • 請確保連接埠確實正在為此應用程式提供服務(另一個本地伺服器可能回應 localhost)。

5. 審查

提取一個聯絡表並查看:

ffmpeg -y -loglevel error -i og-<page>.mp4 \
  -vf "select='eq(n\,8)+eq(n\,22)+eq(n\,40)+eq(n\,<last>)',scale=1000:-1,tile=2x2" -frames:v 1 sheet.png
  • 大約第 0.25 秒:空卡片(僅光暈),無佈局跳動。
  • 大約第 0.7 秒:標題已進入或接近進入,應用程式尚未可見。
  • 大約第 1.3 秒:應用程式正在升起,標題完全可讀。
  • 最後一幀:內容與靜態 PNG 完全相同。

保持 GIF 大小合理(低於約 3MB)。如果太大,請降低 --fps(20–24)或縮短 --hold。

輸出

告知使用者:

  • 預覽路由 URL(循環播放)以及寫入的檔案(MP4、GIF、PNG)
  • 重新產生指令
  • 時間軸(哪些元素移動、持續時間)
  • og:image 必須保持為靜態 PNG:社群平台不播放動畫 OG 圖片。請將 MP4/GIF 用於貼文、README、發布頁面或支援 og:video 的地方。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相關技能