Communitygithub.com

產品示範導演

指導如何在螢幕上呈現真實軟體UI——包含游標編排、縮放/平移/標註語言、螢幕錄製 vs. 重建UI,並透過高亮、焦點拉近與減速讓狀態變化清晰可見。適用於為產品示範、功能導覽、入門影片或發布短片拍攝或重建應用程式時。

產品示範導演 是什麼?

產品示範導演技能旨在解決軟體行銷中最困難的拍攝問題:讓一個真實的UI執行真實操作,且讓陌生觀眾在第一次觀看時就能跟上。預設的失敗模式是原始螢幕錄製——游標瞬間移動、多個變化同時發生,觀眾無所適從。此技能的核心工作是編排觀眾的注意力:一次只改變一件事,鏡頭對準該變化,並停留足夠長的時間讓觀眾讀懂。 此技能支援所有主流AI代理平台(如Claude Code、Cursor、Codex),並與一系列相關技能緊密協作:將具體的緩動曲線和時間細節交給 motion-design-principles、節拍列表交給 video-storyboard、文字動畫交給 kinetic-typography。它定義了「相機和游標對UI做什麼」,然後將結果傳遞給這些技能以及建置包(remotion-compose、remotion-render)。 工作流程涵蓋從決定「螢幕錄製 vs. 重建UI」到最終鏡頭清單檢測的完整過程。關鍵步驟包括:將流程簡化為每個節拍一個變化、編排游標(帶意圖的移動、停留後再點擊)、導演相機(縮放、平移、標註),以及讓狀態變化清晰可見(減速、高亮、焦點拉近)。最後透過一個內建的 Linter 腳本自動檢測常見的可讀性問題,確保示範達到最高品質。

相容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/SkillMedev/tutorial-video-studio/tree/main/skills/product-demo-director

在你喜歡的 AI 中提問

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

說明文件

產品示範導演 是做什麼的?

您負責指導軟體行銷中最困難的單一拍攝:一個真實的UI執行真實操作,且讓陌生觀眾在第一次觀看時就能跟上。預設的失敗模式是原始螢幕錄製——游標瞬間移動、三個東西同時變化,觀眾永遠不知道該看哪裡。您的工作是編排注意力:一次只改變一件事,鏡頭對準它,並停留足夠長的時間讓觀眾讀懂。

這是品味層。事物「如何」移動的語法(緩動曲線、預備動作、12項原則)存在於 motion-design-principles;節拍列表存在於 video-storyboard;文字動畫存在於 kinetic-typography。您決定「相機和游標對UI做什麼」,然後將結果傳遞給這些技能以及建置包(remotion-compose、remotion-render)。

全程以一個範例演示:一個12秒的短片,展示用戶在設定儀表板中開啟一個功能開關,並觀察一個指標圖塊亮起。

工作流程

按順序執行。在決定「錄製 vs. 重建」之前,不要開始編排游標——這個決定會影響下游所有工作。

步驟 1 - 決定:螢幕錄製或重建UI

這是分叉點。在進行任何其他工作之前先選擇。

  • 螢幕錄製:當UI是真實的、穩定的,且示範的可信度取決於「這是實際產品」時使用。最快的捕捉方式;但您會失去控制權。您無法修復抖動的游標、緩慢的網路轉圈、真實客戶資料或縮放時出現鋸齒的字體。以最終解析度的2倍錄製,這樣您才有空間推近而不模糊。
  • 重建UI(將相關畫面重建為元件):當您需要乾淨的游標路徑、確定性的時間控制、虛構但誠實的資料、尚不存在的部分產品狀態或像素完美的縮放時使用。工作量更大;但完全可控。這是通往 remotion-compose 的路徑,每個畫面變成一個元件,游標變成一個動畫圖層。
  • 混合模式(常見且未被充分利用):螢幕錄製「紋理」(真實的滾動、應用程式內真實影片播放),然後在上方合成重建的標註、游標和高亮,以便編排仍然可控。當產品是真實的但原始錄製太亂而無法指導時使用。

寫下決定及其原因。請參閱 references/record-vs-recreate 以了解完整的權衡表。

步驟 2 - 簡化為每個節拍一個變化

只有當一次只改變一件事,並且觀眾在變化發生時正看著它,示範才是清晰的。列出流程中的每個狀態變化(焦點移動、欄位填寫、開關切換、圖塊更新、提示出現)。如果兩個變化發生在同一幀,您必須將它們在時間上分開,或將其中一個降級(變暗、移出縮放範圍)。「開啟開關」不是一個節拍——它是:游標到達開關 → 開關切換 → 指標圖塊重新計算 → 確認提示。四個節拍,四次停留閱讀。

步驟 3 - 編排游標

游標是敘述者。把它當作演員,而不是滑鼠軌跡。

  1. 帶著意圖移動,稍微弧線運動。 從不瞬移,從不抖動。游標從靜止加速,並在目標處減速(ease-in-out——從 motion-design-principles 借用曲線)。微弱的弧線比直尺般的直線顯得更刻意。
  2. 在行動前先停留。 到達,暫停約6-10幀,然後點擊。暫停是眼睛需要的「我即將這樣做」的節拍。
  3. 顯示點擊。 真正的點擊是看不見的。添加一個可見的提示:游標快速縮小/放大、點擊點周圍的徑向漣漪、或目標上的短暫按壓狀態。選擇其中一種,不要三種都用。
  4. 一個游標,一條路徑。 如果流程需要游標在兩個地方,請剪接——不要將其快速橫掃過畫面。硬剪接比4幀的快速移動更清晰。
  5. 當游標不是主體時將其移除。 當圖塊正在更新而游標只是停在那裡時,將其淡出或移出縮放範圍。靜止的游標與真實主體競爭會分散注意力。

步驟 4 - 導演技鏡:縮放、平移、標註

畫面是覆蓋在UI上的一台攝影機。使用一致的移動詞彙,以便觀眾學會您的語言:

  • 推近(縮放):在變化發生之前鎖定一個區域——在開關之前到達。推近是預備動作;變化是回報。
  • 平移/跟隨:跟隨游標在兩個相距太遠而無法容納在一個畫面中的區域之間移動。保持平移緩慢並由游標驅動——攝影機跟隨演員。
  • 拉遠(縮小):在一個詳細的節拍之後重新建立上下文,以便觀眾在進入下一個區域之前重新定位。
  • 標註(高亮環、標籤、連接線、使其他一切變暗的聚光燈)指向那些原本需要用文字命名的東西。當UI元素在螢幕上時,優先使用標註而不是旁白。

規則:攝影機應該在元素變化之前就已經看著它。如果開關切換了然後您才放大到它,您就錯過了時機。

步驟 5 - 讓狀態變化清晰可見

整個示範就是為了狀態變化而存在。每個變化都獲得精心處理:

  • 在關鍵變化時放慢世界。 在導航時保持正常速度,然後將實際的切換/更新拉伸到其真實持續時間的約1.3-1.6倍,以便眼睛記錄因果關係。之後再加速恢復正常速度。
  • 高亮變化前後的差異。 脈衝變化的元素(發光、短暫的顏色覆蓋、縮放凸起)。對於數字的變化,讓數字計數上升而不是硬切數值——運動本身就是訊息。
  • 拉近焦點。 當指標圖塊更新時,將其他所有內容變暗或模糊約10幀,使圖塊毫無疑問地成為主體,然後再恢復。
  • 因果之間加入節拍。 開關切換(停留),然後圖塊更新(停留)。如果它們在同一幀觸發,觀眾無法判斷是開關導致了圖塊。

步驟 6 - 檢查鏡頭清單,然後交接

在您的節拍列表上運行檢查器(如下),以捕捉經典的可讀性失敗——重疊的變化、遺漏的停留、游標瞬移、遲到的攝影機。修復每個標記。然後將指導過的鏡頭清單向下傳遞:時間/緩動細節交給 motion-design-principles,節拍順序交給 video-storyboard,實際實現(游標圖層、縮放變換、元件畫面)交給 remotion-compose 進行建置,以及 remotion-render 進行迭代循環。

品質標準

只有當以下所有條件成立時,示範才是A+:

  • 記錄 vs. 重建的決定已寫下原因,且製作過程遵守該決定(沒有將抖動的原始錄製偷偷塞進「乾淨」的重建中)。
  • 每個節拍中只有一個變化是主體;任何同時發生的變化都被刻意降級(變暗或移出畫面),絕非偶然。
  • 每次點擊都顯示可見的提示,且游標在行動前已先停留——沒有瞬移、抖動或快速平移。
  • 攝影機已在每個元素變化之前對準它。
  • 每個狀態變化至少獲得一種可讀性處理(減速、高亮、焦點拉近或計數上升),並在之後停留閱讀。
  • 鏡頭清單通過檢查器,沒有任何標記。

請勿

  • 不要將原始即時螢幕錄製作為示範發布——請指導它,否則它只是素材,不是示範。
  • 不要讓兩個狀態變化落在同一幀;觀眾無法分配因果關係。
  • 不要瞬移、抖動或快速平移游標;如果它必須在兩個地方,請剪接。
  • 不要在元素變化之後才放大到它——攝影機總是先到達。
  • 不要用旁白說明標註已經指向螢幕上的東西。
  • 不要在此指定確切的緩動曲線或逐幀時間——那是 motion-design-principles 的範圍;不要從頭開始編寫節拍順序——那是 video-storyboard 的範圍;不要在此為螢幕上的文字製作動畫——那是 kinetic-typography 的範圍;不要編寫 React/Remotion 程式碼或渲染——那是 remotion-compose 和 remotion-render 的範圍。

檢查器

獨立 Node 腳本。儲存為 demo_lint.js 並執行 node demo_lint.js。無依賴項。將您的示範描述為一個有序的節拍列表;檢查器會標記工作流程中經典的可讀性失敗。為您的示範編輯 beats 陣列。

// 產品示範鏡頭清單檢查器。執行:node demo_lint.js
// 每個節拍是時間線上的一個時刻。欄位:
//   t          開始時間(秒),有序遞增
//   dur        節拍持續時間(秒)
//   changes    此節拍發生的UI狀態變化(0、1 或多個)
//   camera     'push' | 'pan' | 'pull' | 'hold'(進入此節拍的攝影機移動)
//   framedOn   節拍開始時攝影機對準的元素
//   cursorTo   此節拍游標移動到的位置(null = 保持不動 / 不是主體)
//   click      此節拍是否有點擊
//   clickAffordance  點擊是否可見(漣漪/按壓/縮放)
//   legibility 'slowdown' | 'highlight' | 'focuspull' | 'countup' | null
const beats = [
  { t: 0.0, dur: 1.2, changes: [],               camera: 'push', framedOn: 'settings-panel', cursorTo: 'toggle',     click: false, clickAffordance: false, legibility: null },
  { t: 1.2, dur: 0.5, changes: [],               camera: 'hold', framedOn: 'toggle',         cursorTo: null,         click: true,  clickAffordance: true,  legibility: null },
  { t: 1.7, dur: 1.0, changes: ['toggle-on'],    camera: 'hold', framedOn: 'toggle',         cursorTo: null,         click: false, clickAffordance: false, legibility: 'slowdown' },
  { t: 2.7, dur: 1.4, changes: ['tile-update'],  camera: 'pan',  framedOn: 'metric-tile',    cursorTo: null,         click: false, clickAffordance: false, legibility: 'countup' },
  { t: 4.1, dur: 0.8, changes: ['toast','badge'],camera: 'hold', framedOn: 'metric-tile',    cursorTo: 'export-btn', click: false, clickAffordance: false, legibility: null },
]

const HOLD_MIN = 0.4 // 狀態變化至少需要這麼長時間才能讀取
const flags = []
for (let i = 0; i < beats.length; i++) {
  const b = beats[i]
  const id = `節拍 ${i + 1} (t=${b.t}s)`
  // 1. 每個節拍一個變化。
  if (b.changes.length > 1)
    flags.push(`${id}: ${b.changes.length} 個變化同時發生 (${b.changes.join(', ')}) - 拆分或將所有變化降級,只保留一個`)
  // 2. 每個變化都有停留閱讀。
  if (b.changes.length === 1 && b.dur < HOLD_MIN)
    flags.push(`${id}: 變化 "${b.changes[0]}" 只停留了 ${b.dur}s - 需停留 >= ${HOLD_MIN}s 以便閱讀`)
  // 3. 每個變化都有可讀性處理。
  if (b.changes.length >= 1 && !b.legibility)
    flags.push(`${id}: 變化 "${b.changes[0]}" 沒有可讀性處理(slowdown/highlight/focuspull/countup)`)
  // 4. 點擊必須可見。
  if (b.click && !b.clickAffordance)
    flags.push(`${id}: 點擊沒有可見的提示 - 添加漣漪/按壓/縮放`)
  // 5. 攝影機在元素變化之前對準它,而不是在變化發生的節拍上。
  if (b.changes.length >= 1 && (b.camera === 'push' || b.camera === 'pan'))
    flags.push(`${id}: 攝影機在變化發生的同一節拍移動 (${b.camera}) - 先到達,再改變`)
  // 6. 沒有游標瞬移:游標剛到達就點擊的節拍沒有停留。
  if (b.click && b.cursorTo)
    flags.push(`${id}: 游標在同一節拍移動並點擊 - 在點擊前需停留(約6-10幀)`)
}

if (flags.length === 0) console.log('通過 - 鏡頭清單清晰可讀。')
else {
  console.log(`${flags.length} 個標記:`)
  for (const f of flags) console.log('  - ' + f)
}

範例輸出

使用上面的 beats,腳本輸出:

3 個標記:
  - 節拍 4 (t=2.7s): 攝影機在變化發生的同一節拍移動 (pan) - 先到達,再改變
  - 節拍 5 (t=4.1s): 2 個變化同時發生 (toast, badge) - 拆分或將所有變化降級,只保留一個
  - 節拍 5 (t=4.1s): 變化 "toast" 沒有可讀性處理(slowdown/highlight/focuspull/countup)

解讀:開關點擊(節拍 2-3)是乾淨的——游標停留,點擊有漣漪,切換被減速並停留。但節拍 4 在指標圖塊更新時平移到它,所以攝影機在回報時遲到了;解決方法是將平移移到節拍 3 的停留期間,以便在圖塊重新計算之前對準它。而節拍 5 同時做了兩件錯事:它在同一幀觸發了提示和徽章,並且提示沒有可讀性處理。將徽章降級(變暗,或將其移出縮放範圍),使提示成為單一主體,並為提示添加高亮或停留。修復所有三個問題,檢查器就會通過。

範本:示範鏡頭卡片

複製此內容,填寫 FILL 欄位,並將結果餵給檢查器,然後傳遞給同級技能。

產品示範鏡頭卡片。 [FILL: 功能名稱] - [FILL: 長度]秒

製作決策
  錄製 / 重建 / 混合:   [FILL]
  原因:                 [FILL: 為什麼選擇此路徑]
  捕捉解析度:           [FILL: 如果錄製,為最終解析度的2倍]

片段主題(觀眾應記住的一句話)
  [FILL]

節拍表(每行一個變化;攝影機在變化前到達)
  #  時間   攝影機   對準元素          游標            變化            可讀性          停留時間
  1  [FILL] [push]   [FILL]           [移動到 FILL]   -                 -              [FILL]s
  2  [FILL] [hold]   [FILL]           [停留+點擊]     -                 -              [FILL]s
  3  [FILL] [hold]   [FILL]           [停放/淡出]     [FILL: 切換]      [slowdown]     [FILL]s
  4  [FILL] [pan]    [FILL]           [移出畫面]      [FILL: 效果]      [countup/glow] [FILL]s
  (添加行;切勿在一行中有兩個變化)

標註語言(在整個片段中保持一致)
  高亮風格:             [FILL: 環 / 聚光燈變暗 / 連接線]
  點擊提示:             [FILL: 漣漪 / 按壓 / 游標縮放]
  焦點拉近處理:         [FILL: 其他變暗 / 其他模糊]

交接
  緩動 + 時間細節 ->     motion-design-principles
  節拍順序 / 故事弧 ->   video-storyboard
  螢幕文字 ->             kinetic-typography
  高亮的顏色+光線 ->      motion-color-and-light
  音效設計

……

[為翻譯而截斷]

Individual skills in this repo

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

Captions From Transcript

Produce an accurate, properly timed caption track (SRT or WebVTT) from a video

Kinetic Typography

Put text in motion the right way - title cards, animated captions, lower-thirds, callouts, and word-by-word reveals - with a reading-time-per-word budget so copy holds long enough to read, plus enter/exit timing, weight and size transitions, and type hierarchy in motion. Use when someone asks to

Motion Design Principles

The craft layer for motion: pick the right easing (ease-in / ease-out / ease-in-out / spring), get timing and spacing right, build the anticipation→action→follow-through arc, and apply Disney

Narration Script

Write the spoken voiceover for a tutorial or demo - the actual words, phrased for the ear and synced one-instruction-per-action to what is on screen, with a pacing budget and a confident, jargon-checked tone. Use when someone says

Remotion Compose

Turns a natural-language video brief into a complete, ready-to-preview Remotion composition - extracts duration, scenes, brand colors, aspect ratio, and real copy; plans the frame budget; and writes data-driven React/TypeScript using useCurrentFrame, interpolate, spring, AbsoluteFill, and Sequence, registered in Root.tsx. Use when someone says

Remotion Render

Renders a Remotion composition to MP4 and runs the edit-and-re-render loop - CLI render commands, 1080p/4K/9:16 presets, concurrency tuning, codec selection, batch variants from a JSON data file, and Lambda for cloud rendering. Use when someone says

Remotion Setup

Scaffolds a new Remotion video project wired for Claude Code Agent Skills - Node check, create-video scaffold, skills install, folder conventions, Google Fonts, and a smoke-test render. Use whenever someone wants to start making videos with Remotion and Claude, even just

Screencast Capture

Capture clean raw screen and camera footage for a tutorial or product demo - choosing the recorder (macOS Screenshot toolbar, QuickTime, OBS, Windows Game Bar), setting resolution / frame-rate / cursor / microphone, prepping a distraction-free stage, and recording in retakeable segments. Use when someone says

SkillMedev/tutorial-video-studio

Plan a product demo, feature announcement, or launch video as a beat sheet and shot list BEFORE animating - hook in the first 3s, problem, reveal, proof, CTA - with target duration and pacing per scene type, output as a JSON scene plan that remotion-compose consumes directly. Use when someone says

Social Video Formatter

Reframe and export a finished video for social platforms - 9:16 ↔ 16:9 cropping, burned-in captions, a platform-native first frame, loop design, and per-platform specs (aspect, length, safe areas) for TikTok, Reels, Shorts, X, and LinkedIn. Use when someone says

Sound and Music Sync

Score a video like an editor: beat-match cuts to the music, land SFX on transitions, pace the voiceover so it breathes, source royalty-free tracks safely, and duck the music so the VO sits clearly on top. Use when adding music, sound effects, or voiceover to a video, when asked to

相關技能