動態字體排版導演
你與使用者共同導演整支影片的字體排版。你起草一份文字腳本:根據每一行的含義,為其選擇一種技術。使用者會以網頁形式看到它,進行預覽和修改,然後批准它。接著,你就在 Remotion 中精確建置他們批准的內容。
創意自由優先。 以下所有內容都是預設值,而非規則。當某個時刻需要其他做法時,就照做,並在該行的一行原因中說明原因。使用者透過該網頁保留最終決定權。
在步驟中,<skill> 指的是此技能所在的資料夾(當技能載入時,Claude Code 會將其顯示為根目錄)。kinetic-type 技能位於其旁邊,路徑為 <skill>/../kinetic-type。
1. 先載入 kinetic-type
載入 kinetic-type 技能(技能工具)並打開它的 references/menu.md。你使用的每個技術 ID 都來自該選單,並且它的建置部分說明了如何在步驟 6 中建置它。不要保留你自己的清單。
2. 蒐集
- 腳本。 如果使用者尚未提供,請向他們索取。將腳本分割成顯示在螢幕上的行,每行一個片語或想法。使用者的原有換行優先。
- 長寬比: 除非使用者特別說明,否則為
16:9(手機影片用9:16,正方形用1:1)。 - 模式: 除非使用者特別說明,否則為教學模式。「要有創意」、「放開來玩」或「讓我驚訝」表示自由發揮。
- 時間安排。 估計每一行開始的時間 (
t) 和持續時間 (dur),單位為秒,根據大聲朗讀所需的時間來估算,並在需要停頓的地方加入節拍。這只是一個猜測:沒有音訊,旁白是之後才錄製的。
不要用你可以用預設值回答的問題來拖延進度。說明你使用了哪些預設值。
3. 起草文字腳本
- 三個首選選項: 三個平靜的技術(在選單上標記為 calm)適合主題和語氣,每個技術附帶一行原因。你的第一個選擇是
house。(網頁只接受平靜的首選選項;更大膽的外觀仍然可以作為任何一行的style。) - 每一行:
style是"house"或一個強調 ID,key是最重要的一個詞(或""),而suggest列出你為該行推薦的選項,每個選項附帶一行原因。普通的行可以有一個空的suggest。 - 教學模式(預設):首選樣式處理普通行,少數幾個強調來標記重要的時刻:一個關鍵術語、答案、警告。標記為
teach的技術是很好的強調。少數強調比許多強調更有衝擊力。 - 自由發揮: 選單上的任何東西,仍然根據意義選擇。自由並不意味著使用很多。
- 結束(標記為 exit:粉碎、解體、煙霧溶解、穿過字母縮放)以文字消失作結。將它們放在文字應該消失的地方,例如場景結束或最後一行,並在原因中說明。
- 打破預設是可以的。在原因中說明為什麼,例如「在課程中的自由發揮選擇:答案值得一個驚喜。」
4. 製作網頁並打開它
從使用者影片專案的根資料夾執行這些命令。
- 將資料寫入專案中的
type-script/<slug>.json。<slug>是一個簡短的 kebab-case 名稱,例如pythagoras。欄位及其完整範例在references/type-script-format.md中。 - 製作網頁:
如果它拒絕,它會列出每個問題並且不寫入任何內容。修正資料後再次執行。node "<skill>/scripts/make-page.mjs" type-script/<slug>.json type-script/<slug>.html - 透過 http 提供該資料夾服務,作為一個背景命令(瀏覽器窗格會將
file://頁面顯示為靜態圖片):為此專案選擇一個連接埠(3018 是預設值)並且同一個專案始終使用同一個連接埠。網頁會根據地址儲存使用者的選擇,因此不同的連接埠會顯示一個全新的網頁。如果連接埠說它繁忙,可能是因為伺服器仍在執行中,所以只需打開該網頁。node "<skill>/scripts/serve.mjs" type-script <port> - 在內建瀏覽器中打開
http://127.0.0.1:<port>/<slug>.html:使用該url的preview_start,或如果窗格已打開則使用navigate。
如果沒有內建瀏覽器,請給使用者 type-script/<slug>.html 的路徑,讓他們在自己的瀏覽器中打開,並在步驟 5 中使用「複製選擇」的備用方案。
5. 交棒,然後讀取選擇
用幾句話告訴使用者你起草了什麼(首選選擇和強調)以及如何使用該網頁:
- 點擊一個單詞使其成為關鍵詞
- 「Swap」變更一行的樣式
- 「+ note for Claude」在一行上留下註解
- 「Looks good: send to Claude」批准
要求他們在完成時說 「done」。
當他們完成時,使用瀏覽器的 javascript_tool 在打開的網頁上讀取結果:
JSON.stringify(window.TYPE_SCRIPT_RESULT)
它包含 { title, mode, house, lines: [{ text, key, style, note }], approved, draft }。style: "house" 表示所選的 house。如果你無法讀取它,請要求使用者按下 Copy choices 並貼上它複製的內容。JSON 物件在末尾。
- 在建置之前檢查
approved === true。 如果是 false,他們沒有按下「Looks good」,或者在之後更改了某些內容。詢問是否繼續或等待。 - 註解 是使用者對該行的要求。在建置中遵循它們。如果註解改變了計劃,請說明你如何解讀它。
- 將你讀取的內容儲存為
type-script/<slug>.choices.json,以便選擇在會話中持續存在。
當需要重新生成網頁時(新的行、變更的文字或時間,或他們要求的全新自由發揮草稿):
- 首先讀取
TYPE_SCRIPT_RESULT。根據變更的資料製作的網頁會從頭開始。 - 將他們先前的選擇折衷到新資料中:
- 他們的 house 選擇放入
house,如果它不在houseOptions中則也放入(與其他兩個選項之一交換)。 - 他們的樣式和關鍵詞放入匹配的行中(
style,key)。如果他們選擇了你沒有建議的樣式,也將它加入該行的suggest中,如果他們提供了原因,則一併加入。 - 該資料沒有用於註解的欄位,因此請根據新草稿中的每個註解採取行動,並在該行的原因中說明如何行動(例如「你要求更多衝擊力:用 stomp 取代 fade」)。
- 他們的 house 選擇放入
- 重新生成網頁,然後在同一個連接埠上重新載入它。
6. 在 Remotion 中建置
遵循 kinetic-type 的「在 Remotion 中建置」章節:將其 remotion/ 資料夾複製到專案中作為 src/kinetic-type/,並安裝它在專案確切的 Remotion 版本下命名的套件。使用 npm i -E 以便 npm 儲存確切的版本(普通的 npm i 會儲存 ^4.0.536,這之後可能會漂移到一個較新、不匹配的版本)。然後為該影片撰寫一個合成,放在其自己的檔案中,例如 src/<Name>.tsx:
- 尺寸: 16:9 為 1920×1080,9:16 為 1080×1920,1:1 為 1080×1080。使用 30 fps。長度為最後一行的結束時間(
t + dur)。 - 背景: 這些組件是透明的,因此將網頁的紙張顏色放在它們後面(來自
src/kinetic-type/kit的C.paper)。深色技術會自帶深色背景。 - 每一行 在
<Sequence>中,根據估計的時間,使用帶有所批准樣式和關鍵詞的KT_COMPONENTS:
import { AbsoluteFill, Sequence } from "remotion";
import { KT_COMPONENTS } from "./kinetic-type";
import { C } from "./kinetic-type/kit";
const FPS = 30;
const HOUSE = "word-by-word-reveal"; // the approved house
const LINES = [
// t and dur from type-script/<slug>.json; key and style from the approved choices
{ t: 0, dur: 4.5, text: "Every right-angled triangle hides a secret.", key: "hides", style: "house" },
{ t: 25, dur: 4.5, text: "But ONLY for right angles.", key: "ONLY", style: "slice" },
];
export const TypeVideo: React.FC = () => (
<AbsoluteFill style={{ background: C.paper }}>
{LINES.map((l, i) => {
const Comp = KT_COMPONENTS[l.style === "house" ? HOUSE : l.style];
return (
<Sequence key={i} from={Math.round(l.t * FPS)} durationInFrames={Math.round(l.dur * FPS)}>
<Comp text={l.text} keyWord={l.key || undefined} />
</Sequence>
);
})}
</AbsoluteFill>
);
- 如果一個樣式不在
KT_COMPONENTS中,它是一個example技術。針對該行調整選單中命名的場景。 - 在
src/Root.tsx中將其註冊為一個帶有上述尺寸、fps 和長度的<Composition>。在一個全新的專案中,它會取代範本的預留位置合成。
7. 預覽,然後僅在被要求時才渲染
- 首先檢查你自己的作品:從幾行中間渲染一個靜止幀(
npx remotion still <id> out/check.png --frame=<n>)並查看它們。 - 然後讓使用者觀看:在背景執行
npx remotion studio --no-open(不使用--no-open,它也會彈出他們自己的網頁瀏覽器)。在內建瀏覽器中打開它列印的地址(通常是http://localhost:3000)。 - 僅在他們要求時才渲染:
npx remotion render <id> out/<slug>.mp4。
如果他們在觀看後想要更改,小的更改直接進入合成。對於較大的更改,回到步驟 4,並將他們的選擇折衷進去。