app-preview-craft — 商店截圖、社群卡片與 3D 裝置影片
此技能所製作的一切都是一個頁面(stage/stage.html),由主題擺設姿勢,並由無頭 Chrome 擷取:靜態圖被截圖並由 sharp 完成處理,影片則逐幀渲染並餵入 ffmpeg。同一個頁面也驅動預覽工作室,因此使用者在那裡看到的內容,完全等同於 CLI 匯出的結果。
0. 找到技能,並設定一次
以下路徑相對於包含此 SKILL.md 的目錄。 請解析一次,並以其為前綴加上指令 — 在整個文件中,$SKILL 即代表該目錄:
SKILL=/absolute/path/to/app-preview-craft # 此資料夾包含 SKILL.md、scripts/、stage/
# 不確定安裝在哪裡?(技能資料夾,然後是 Claude Code 外掛快取)
find ./.claude/skills ./.agents/skills ./.goose/skills ~/.claude/skills ~/.agents/skills \
~/.gemini/skills ~/.config/goose/skills ~/.claude/plugins \
-path '*app-preview-craft*/scripts/cli.mjs' 2>/dev/null | head -1
然後檢查機器。--fix 會在缺少套件時在技能內部執行 npm install:
node "$SKILL/scripts/doctor.mjs" --fix
Doctor 必須以 Ready. 結尾。缺少 ffmpeg 僅為警告(靜態圖仍可運作)。如果報告沒有 WebGL,則 3D 主題無法渲染 — 請明確告知,而不是默默地切換為平面主題。
輸出內容會放到使用者正在工作的目錄(shell 的 cwd),除非他們用 --out 指定了另一個資料夾。切勿將渲染結果寫入 $SKILL。暫存狀態存在於 $TMPDIR/app-preview-craft/,並在每次運行後清除。
1. 工作流程
-
選擇類別(第一個 CLI 引數),根據使用者的需求:
類別 產出 預設尺寸 app-store一個集合:每張投影片、每種尺寸各一張截圖,加上 overview.pngiphone-6.91320×2868social-card一張卡片(或 --all投影片)用於 og/X/LinkedIn/Instagram/storyog1200×630screen-video僅由螢幕構成的 2D 動態影片;可接受螢幕錄影 reel1080×1920device-videothree.js 裝置展示影片 reel1080×1920device-mockup3D 主角靜態圖,可選透明背景 mockup-landscape2400×1600 -
收集內容。 從使用者的專案中取得截圖(PNG/JPG/WebP)和/或錄影(MP4/MOV/WebM),每張投影片一張,按順序排列。除非使用者提供文案(參見 §4),否則請自行撰寫。如果沒有截圖,則使用內建的範例應用程式「Tempo」— 這適用於展示主題,但絕不適用於交付成品。
-
選擇主題。 使用者指定的主題優先。對於 App Store 集合,請將應用程式的商店類別與 §3 的表格進行比對,並說明你選擇了哪個主題及其原因。當使用者猶豫不決時,先向他們顯示選項:
node "$SKILL/scripts/cli.mjs" gallery app-store # → ./gallery-app-store.png回讀工作表(以便為使用者渲染),然後讓他們選擇。當他們想以視覺方式瀏覽和調整時,工作室(§8)是更好的答案。
-
渲染。
node "$SKILL/scripts/cli.mjs" app-store shots/01.png shots/02.png shots/03.png \ --theme ledger \ --title "Every euro, *accounted for*" --title "Budgets that *adapt*" --title "Private *by design*" \ --subtitle "One-line benefit…" --subtitle "…" --subtitle "…" \ --size iphone-6.9,ipad-13 --set palette.accent=auto -
在回報之前檢查。 讀取
overview.png(集合)、靜態圖,或從影片中抽取影格(--frames 1,4,mid,end會渲染 PNG 影格而不是影片 — 用於檢查動態很省成本)。檢查是否有被裁切的標題、疊在裝置上的文字、遮蓋裝飾的裝置、空白畫面。使用--set/每張投影片的覆寫來修正,然後重新渲染。 -
回報 輸出路徑、主題和尺寸,並且 — 每當出現 3D 裝置時 — 說明
CREDITS.txt已寫入,且 CC-BY 授權必須隨圖片一同傳播(§7)。
2. 尺寸
node "$SKILL/scripts/cli.mjs" list sizes --category app-store 會輸出表格。任何 WxH 格式也都可以使用。一次指定多個尺寸:--size iphone-6.9,iphone-6.5,ipad-13。
- App Store Connect 要求 iPhone 應用程式使用 6.9" 集合(
iphone-6.9),iPad 應用程式使用ipad-13;其他尺寸為選用。PNG 輸出為平面化(Apple 拒絕帶有 alpha 色版的圖片)。 - 平板尺寸 會自動將手機替換為扁平平板框架,除非主題是無框的。當應用程式有 iPad 截圖時,請將這些截圖提供給那些投影片。
- App Preview 影片:
--size app-preview(886×1920)或app-preview-ipad,15–30 秒,30 fps。會自動加入一條無聲的立體聲 AAC 音軌(Connect 預期有音訊)。 - Google Play:
play-phone、play-tablet和play-feature(1024×500,社群卡片)。
3. 主題
list themes --category <c> 會輸出這些主題及其佈局。每個類別至少有 5 個。
app-store — 每個主題模擬一個熱門的應用程式類別
| 主題 | 應用程式類別 | 靈感來源 | 外觀 |
|---|---|---|---|
stride | 健康與健身 | Strava、Nike Run Club | 熱情橘、壓縮全大寫藥丸、速度條紋、傾斜手機 |
ledger | 財務 | Revolut、Monzo、Robinhood | 午夜網格、薄荷綠→青色漸層文字、鉻球 |
serene | 健康與正念 | Calm、Headspace | 柔和極光、斜體襯線強調、軟性模糊區塊上的無框螢幕 |
canvas | 生產力 | Notion、Things、Linear | 溫暖紙張、筆記本網格、大型襯線字體、扁平墨水手機 |
sizzle | 食物與飲料 | DoorDash、Uber Eats、Deliveroo | 陽光黃、圓點花紋、紅色麥克筆強調、傾斜手機 |
wander | 旅遊 | Airbnb、Hopper、Booking | 黃昏漸層搭配復古太陽,橫跨整個集合(全景) |
mixtape | 音樂與音訊 | Spotify、Apple Music | 你的螢幕模糊成發光背景、巨大空心字 |
arcade | 遊戲 | Apple Arcade、手機遊戲發行美術圖 | 合成波網格、霓虹邊框、光澤 3D 玩具 |
snapshot | 照片與社群 | Instagram、BeReal、VSCO | 三張無框截圖如照片般扇形展開、溫暖底片網格 |
pulse | 健康資料與穿戴式裝置 | Oura、WHOOP、Apple Health | 臨床黑色、深紅光芒、標題位於正面 Pro Max 下方 |
這些主題借用的是氛圍,絕非品牌:絕不出現那些應用程式的標誌、名稱或美術作品。
social-card
launch(極光 + 傾斜手機)、spotlight(光束 + 鏡面地板)、pastel-fan(三張扇形展開的螢幕)、bento(螢幕裁切網格)、neon-grid(合成波)、editorial(紙張、襯線、雙色調螢幕)、duo(MacBook + 手機 — 為筆電傳入一個 desktop 螢幕)。
screen-video (2D)
carousel、stack(卡片快速移開)、scroll(長截圖在手機內滾動)、zoom-tour(滿版 Ken Burns 效果至每張投影片的 focus)、wall(傾斜的螢幕牆)、store-preview(App Store 預覽風格 — 使用 --size app-preview)、grid-reveal。
device-video (3D)
turntable、orbit(相機弧形移動)、float(可循環)、rise(相機推進)、flip(背面 → 正面揭示)、trio(三個模型扇形展開)、desk(MacBook 螢幕打開,手機滑入其旁;兩者皆立於 scene.floor 上)、spotlight(360° 旋轉於鏡面上)、synthwave、keyframes(你自己的裝置和相機移動,依據 motion.keys — 參見 §5)。
device-mockup (3D 靜態圖)
studio、noir、pedestal、levitate、lineup(每種手機型號)、flatlay、desk-duo。加上 --transparent 可輸出去背 PNG。
4. 文案
- 每張投影片的主標題:不超過 6 個字詞,強調效益而非功能。將 1–2 個字詞用
*星號*包圍,以在主題的樣式中突顯它們;" | "會強制換行。 - 副標題:一個簡短的句子。預告片(可選):上方的一個單詞標籤。
- 前兩張投影片承載著核心訴求 — 大多數購買者從不往下滑。
- 絕不虛構評分、下載數、獎項或媒體引述。裝飾元素如
rating和laurels僅用於使用者提供的真實數據;在不確定時務必詢問。 - 在文案中,除了遵守商店指南的範圍外,請勿提及競爭對手或使用 Apple/Google 商標。
5. 設定任何項目
解析順序,後者優先:
內建基底 → 佈局預設值 → 主題(及其 extends 鏈)→ 自訂主題檔案 → 專案設定 themeOverrides → CLI 捷徑 → --set → 每張投影片 theme。
- 捷徑:
--layout --device --finish --pose --font --body-font --bg --bg2 --bg3 --ink --sub --accent --accent2 --background --pattern --background-image --clean-status-bar --no-decor --duration --fps --speed --intro --outro。 --set path=value可存取任何主題鍵值(可重複使用)。list options會輸出帶有類型和範圍的說明文件路徑。值會被強制轉換;JSON 可用於列表/物件:--set device.pose=5,-15,4 --set 'decor=[{"kind":"sparkles","count":8}]'。device.pose為x,y,z度。主題應大致保持在 ±20° 偏航和 ±6° 翻滾範圍內,以使螢幕在商店縮圖尺寸下仍可讀取;更大的角度可行,但會犧牲可讀性。- 顏色可接受
auto= 第一張截圖中最鮮豔的顏色:--accent auto。 --device iphone-17-pro | iphone-17-pro-max | iphone-12-pro | galaxy-s21-ultra | macbook-pro-16 | flat[:phone|phone-android|tablet|browser] | frameless | none,或使用者自有型號的 ID(§7)。- 佈局在相同種類內可互換(
list layouts):靜態圖 —hero-top、hero-bottom、tilt、duo、fan、split、big-type、callout、bento、laptop-phone、showcase、pedestal、lineup、flatlay;影片 —carousel、stack、scroll、zoom-tour、wall、phone-swap、grid-reveal、turntable、orbit、float、rise、flip、trio、desk、spotlight、keyframes。 - 你自己的動畫:
keyframes佈局透過motion.keys移動一個 3D 裝置和相機,這是一個列表,包含{ "at": 0..1, "x", "y", "size", "pose": [rx, ry, rz], "cam": { "yaw", "pitch", "dist" }, "ease" }。at是整個影片的進度比例;某個鍵留空的值會沿用前一個鍵的值;第一個鍵從主題自身的姿勢開始。緩動函數:linear inOutCubic inOutSine outCubic outQuart outBack inOutQuart outExpo。--theme keyframes --set 'motion.keys=[{"at":0,"y":1.4,"pose":[0,70,0]},{"at":0.3,"y":0.62,"pose":[4,-20,3],"ease":"outQuart"},{"at":1,"pose":[0,15,0],"cam":{"dist":0.9}}]'。未涉及動畫庫:每一幀都是其時間的純函數,這使得影格可以亂序渲染。使用--frames 0,2,mid,end檢查移動。
自訂主題是 JSON(或 .mjs)檔案,包含主題鍵值的任何子集,加上 extends:
{ "extends": "app-store/ledger", "name": "Acme", "palette": { "accent": "#ff5a1f" },
"type": { "display": "bricolage", "weight": 800 }, "device": { "finish": "#1c1f24" } }
傳入 --theme path/to/acme.json,或將其放置在 ./.app-preview-craft/themes/(或 ~/.app-preview-craft/themes/)中,然後使用 --theme acme。list themes 會顯示自訂主題。
專案設定。 node "$SKILL/scripts/cli.mjs" init app-store 會寫入 app-preview-craft.json;之後執行 node "$SKILL/scripts/cli.mjs"(不帶引數)會渲染它,而標記仍然可以覆寫它。$SKILL/examples/app-preview-craft.json 是一個完整的工作範例:包含每張投影片的文案、裝飾和主題覆寫、一個自訂主題檔案、一個桌面螢幕,以及一個 jobs 列表,可一次渲染一個 App Store 集合、一個社群卡片、一個模型圖和一個影片。設定檔中的路徑是相對於設定檔解析的。
每張投影片的鍵值:screen、desktop(筆電顯示器)、title、subtitle、kicker、theme(僅限該張投影片的覆寫)、decor(取代該張投影片的主題裝飾)、focus: [x, y, zoom](縮放導覽目標)、hold(影片中的秒數)、trim: [start, end] 和 at(靜態圖使用錄影中的第幾秒)、bigWord(大字型佈局)。
裝飾項目為 {kind, x, y, scale, rotate, style, layer, delay, …},x/y 為頁面比例,style 為 glass | solid | light | dark | outline 之一:
| 種類 | 額外鍵值 |
|---|---|
badge | text、icon(star bolt heart check sparkle trophy leaf lock music pin flame bell chart shield globe play) |
rating | score、label、starColor |
laurels | top、text、bottom |
chips | items[]、icons[]、width、lead |
notification | app、title、body、time、icon(圖片路徑)或 glyph、width |
stat | label、value、trend、trendColor |
callout | rect: [x, y, w, h] 截圖中要放大的區域、w、border、radius |
arrow | w、h、text(手寫筆記)、flip、stroke |
logo | name、src(應用程式圖示路徑) |
store-badge | top、text、或官方徽章美術圖的 src |
sparkles confetti | count、colors[]、area: [x0, y0, x1, y1]、seed |
blob | size、color、opacity(位於裝置後方) |
orbs rings shapes | 3D 基本物件:count、shapes[]、finish(glossy chrome matte glass iridescent)、area、items[] |
credit | text(預設為模型授權行) |
6. 螢幕與處理
- sharp 會在 Chrome 啟動前準備每張截圖:
screen.cleanStatusBar(重新繪製 9:41 / 滿電量的 iOS 狀態列 — 僅限手機形狀的截圖)、tint+tintAmount、duotone: "#深色,#淺色"、saturate、brightness、sharpen,以及用於blur-shot背景的預模糊背景。 - 在 iPhone 型號上,動態島被繪製成一個合併的黑色藥丸形狀,覆蓋在型號的藥丸和相機開孔上,與 iOS 顯示的內容一致。提供的截圖應保留動態島區域乾淨(任何一般的 iOS 截圖皆是如此);
cleanStatusBar會保留兩側的時間和圖示。 - 高度超過顯示器的截圖會在影片中捲動(
scroll主題),並在靜態圖中顯示其頂部(screen.fit=top)。 - 錄影會由 ffmpeg 以輸出幀率分割成影格;在影片中,每個錄影的投影片持續時間等於剪輯長度(可使用
hold覆寫,使用trim裁剪)。靜態圖使用一個影格(at,預設為中間影格)。 - 筆電顯示器會將手機截圖以信箱格式置於模糊副本上,除非該投影片含有
desktop螢幕。desktop也可以接受錄影。在desk影片中,筆電螢幕內容來自desktop,手機內容來自screen。
7. 3D 裝置模型
- 每個 3D 裝置模型都附有 CC-BY 4.0 授權(「Poly by Google」或「Khronos glTF Sample」)。執行
list models會輸出它們並顯示授權字串。技能會在輸出目錄中寫入CREDITS.txt,該檔案必須與渲染的影像一同傳播。沒有例外的情況。 .glb檔案位於$SKILL/models/。你自己的模型可以放在./.app-preview-craft/models/或~/.app-preview-craft/models/中(list models會找到它們)。使用--set device.model=my-widget.glb。所有模型都必須有 PBR 材質。finish控制外殼顏色/紋理。glass結合了厚度、光澤和折射。iridescent模擬偏振光(白/銀裝置可產生彩虹效果)。- 裝置底座在
device.pedestal之下——一個檯面,其鏡面反射會捕捉頭頂的環境地圖。關閉:--set 'device.pedestal=null'。
8. 預覽工作室
node "$SKILL/scripts/cli.mjs" studio 會在一個隨機連接埠啟動一個本機 HTTP 伺服器,開啟瀏覽器,然後監控變更。告訴使用者到訪該 URL(約在 http://localhost:...),然後他們可以放下內容、選擇主題、拖曳滑桿,然後下載或匯出。工作室產生的設定可以直接用於 CLI 指令。
9. 錯誤處理
- 自動重試:當頁面在無頭 Chrome 中渲染失敗時(例如,Three.js WebGL 上下文遺失、字型載入超時),技能會自動重試最多 3 次後才放棄。
- 逐幀還原:如果影片在幀 47/240 處中斷,重新執行會從失敗的幀繼續,而不是重新開始。
doctor會在啟動時檢查所有依賴項(FFmpeg、Node.js 版本 ≥ 18、npm 套件)。如果缺少任何項目,命令會以明確的錯誤訊息終止,除非指定了--fix。- 在動態渲染期間,錯誤會同時回報到主控台和一個 JSON 日誌檔案
render_log.json,以便輕鬆偵錯。
10. 效能考量
- 高度最佳化:3D 場景在 Chromes headless 模式下以全解析度渲染,無需額外的後製傳遞。
- 大型影片渲染(例如,60 秒的 4K 影片)會產生大量的中間影格。預設情況下,這些影格儲存在
$TMPDIR中,並在成功渲染後立即清除。如果進度在過程中中斷,請使用--keep-frames保留它們以進行除錯。 - 記憶體使用量:對於高解析度的多個裝置場景,三個 .glb 模型同時載入通常仍低於 2GB RAM。超出此範圍可能會導致 headless Chrome 崩潰——如果是這種情況,請使用
--set scene.quality=medium。