givemotion:HTML 輸入,影片輸出
一個合成就是一個 HTML 檔案。每一格都是該頁面在某一時刻的樣貌。CSS 動畫、轉場、Web Animations、計時器、requestAnimationFrame、Canvas 和 WebGL 都在一個虛擬時鐘上運行,因此你撰寫的內容每次都會以影格精確且完全相同的方式渲染。不需要 script 標籤或 import:執行階段 (window.gm) 和一個預設樣式表會自動為你注入。
這個檔案是核心(請完整閱讀)。然後只閱讀你的影片需要的 1-3 個技術食譜(表格在結尾):每個食譜都展示專業人士如何建立那種效果,附有數字和一個可運作的範例。需要時再查詢其他部分。
循環
- 直接。 在編寫程式碼之前,決定頂尖工作室會如何製作這個簡報:研究該類型(盡可能在網路上搜尋真實範例,否則憑記憶回想),然後在 HTML 頂端撰寫:以文字描述的視覺風格、字型系統、動作語言(緩動家族、節奏、場景如何交接)以及鏡頭清單(每個時刻一行:時間、畫面上有什麼、動作、交接)。如何做:
references/direction.md。 - 風格影格。 先建構 2-3 個關鍵靜止畫面,靜止不動,並
still它們:以海報的標準來評判(一個焦點、層級、邊距)。然後再加入動畫。 - 撰寫動作;邊進行邊使用
npx givemotion check video.html:修正每一個 ✖;⚠ 是真正的錯誤,除非是刻意為之;ℹ 是風格提示。 - 審查兩次。
npx givemotion review video.html會寫出觀眾所見的內容(總覽、人們會閱讀的影格、忙碌時刻的動作條)以及review/REVIEW.md:嚴格評分,修正最嚴重的五個問題,再次審查。新的眼光能發現更多:只將簡報和審查資料夾提供給子代理。將簡報的時間放入data-expect。 - 渲染:
npx givemotion render video.html -o out/video.mp4。
--json 用於機器輸出,<command> --help 用於選項。still video.html -t 3.2 -o f.png 渲染單一瞬間;inspect --at 4.5 --el "#logo" 顯示元素的位置。
這裡如何製作出優質動作
引擎讓你使用任何 HTML/CSS/SVG/canvas 和一個影格精確的時間軸;視覺效果來自於你如何編排它們。盲人觀眾更偏好每個元素都經過手動編排的影片,而非使用一個詞的預設效果所建立的影片。
- 手動編排。 對任何重要的事物使用
gm.timeline:明確的開始時間、每種動作的緩動(快速的expo.out重擊、柔和的sine.inOut飄移、back.out(1.6)的著陸)、相關部件之間 40-120 毫秒的偏移量。預設效果(data-enter、data-camera)適用於次要的小東西。 - 每個英雄時刻都有三個層次: 主要動作;次要細節使其更具說服力(快速時模糊、發光、會長大的陰影、跟隨動作、衝擊時的光環或粒子);以及環境動作,使畫面永不凍結(背景飄移、緩慢的攝影機推近)。
- 時間上的對比。 快速進入,緩慢穩定;某物落地後暫停 0.4-1 秒;退場比入場短。永遠不要讓所有事物以相同速度和相同曲線移動。
- 嚴格遵循簡報的顏色、字型、文案、尺寸和時間;你的工藝應體現在事物如何移動上,而不是添加額外的內容。
- 第 0 幀是鉤子,沒有任何東西被畫面邊緣裁切,文字要大(在 1080p 下,標題 96-200 px,內文 ≥ 36 px),每個時刻一個英雄,場景之間流暢銜接(推、甩、變形、匹配剪接),而不是淡出。
- 事物從事物中產生。 一個新元素是從已在畫面上的元素中誕生的,而不是從無中生有:三個圓圈從主圓圈中擠出;畫面中的一個矩形滑過去變成底線;卡片從被點擊的按鈕中長出來;Logo 的標記變成結尾卡片的標記。在增加新東西之前,先重複使用和改造。提前埋下下一組元素:當這個節奏播放時,它們已經存在於世界中(小而暗),讓攝影機可以揭示它們。
- 攝影機移動意味著「看這裡」。 只朝觀眾接下來應該閱讀的東西推近。永遠不要放大空無一物的地方,或放大到舊場景作為轉場方式:要離開一個場景,橫向移動(推、甩、擦)或帶著一個元素跨過去(變形,上述規則)。
- 動畫
transform/translate/scale/rotate/opacity/filter/clip-path,而不是width/top/left。 - 每個元素都有一個規劃好的生命週期: 進入、可閱讀的停頓(約 1 秒 + 每個單詞 0.25 秒),然後是退場或交接。鏡頭清單會給出每個停頓點。
層級:一次只關注一件事
觀眾偏好眼睛總是知道該看哪裡的影片。
- 每一行都有一個關鍵詞。 賦予承載意義的詞語對比(強調色、較粗的字重、較大的尺寸,或畫出的高亮);其餘部分保持低調。每行一個,每個畫面最多兩個。如果什麼都是強調,那就等於沒有強調。
- 每個時刻都有一個英雄: 最大、最亮、動作最多的東西。輔助元素較小(英雄 ≥ 下一級尺寸的 1.6 倍;最多三個層級)、較暗(柔和或 50-70% 不透明度)、在英雄之後到達且移動較少。效果(光環、火花)圍繞著英雄,永遠不跨越它。
- 依序引導視線: 英雄首先著陸;關鍵詞在該行穩定後 0.2-0.4 秒獲得其顏色或底線;輔助元素跟隨。當攝影機或提示框聚焦於某物時,將其餘部分調暗。
- 調色板角色嚴格: 強調色僅用於強調,柔和色用於次要文字。
緩動:將曲線與動作匹配
- 進入時減速(ease-out:
expo.out、power3.out,或當它帶有重量著陸時用back.out(1.4))。 - 離開時加速(ease-in:
power2.in),比進入時間短(60-70%)。 - 從 A 點移動到 B 點(同時保持可見)、攝影機移動、已存在畫面上的縮放變化:使用 ease-in-out(
power2.inOut、sine.inOut):它平穩開始,平穩著陸。 - 環境飄移: 長時間的
sine.inOut;linear僅用於循環(旋轉、跑馬燈)。沒有任何在畫面上開始或停止的物體是線性移動的。 - 省略
ease,引擎已經為你處理了這些(進入會彈入,移動會 ease in and out,退出會 ease in);當你設定一個時,請遵循上述規則。
最小合成
<!doctype html>
<html data-width="1920" data-height="1080" data-fps="30" data-duration="2.5">
<head>
<style>
:root { --bg: #0b0d12; --ink: #fff; --accent: #7c9cff; }
body { background: var(--bg); color: var(--ink); font-family: Inter, sans-serif; }
.scene { display: grid; place-items: center; } /* .scene 已經是 absolute + 全畫面 */
h1 { font-size: 160px; letter-spacing: -0.03em; margin: 0; }
.glow { position: absolute; width: 900px; height: 900px; border-radius: 50%; background: var(--accent); filter: blur(160px); opacity: .25; }
</style>
</head>
<body>
<section class="scene">
<div class="glow"></div>
<h1 id="t" data-split="chars">Hello</h1>
</section>
<script>
gm.timeline('.scene')
.from('.glow', { scale: 0.6, opacity: 0, duration: 1.2, ease: 'sine.out' }, 0) // 環境:光芒亮起…
.to('.glow', { x: 220, y: -90, duration: 2.5, ease: 'sine.inOut' }, 0) // …並持續飄移
.from('#t .gm-char', { y: 140, opacity: 0, filter: 'blur(12px)', duration: 0.7, ease: 'expo.out', stagger: 0.05 }, 0.2) // 主要:快速進入,快速時模糊
.fromTo('#t', { letterSpacing: '0.12em' }, { letterSpacing: '-0.03em', duration: 2.4, ease: 'expo.out' }, 0.2) // 細節:字距收緊
.to('#t', { scale: 1.06, duration: 1.9, ease: 'sine.inOut' }, 0.6); // 停頓時保持呼吸感
</script>
</body>
</html>
內建字型:Inter、JetBrains Mono、Playfair Display、Space Grotesk、Bebas Neue、Nunito、Caveat;其他可透過 @font-face。
時間模型(請閱讀此部分)
- 設定存在於
<html>上:data-width、data-height(偶數)、data-fps(預設 30)、可選的data-duration、可選的data-background。 - 時間單位為秒:
1.5、1.5s、500ms、45f(影格)、1:02.5。 - 片段。 帶有
data-start、data-duration或data-end的元素只在其開始到開始+持續時間內存在(顯示)。時間是相對於其父片段的。沒有時間設定的元素會一直存在。 - 影片長度 =
<html>上的data-duration,否則為最後一個片段的結束時間。 - 序列。 容器上的
data-sequence會逐個播放其子元素。每個子元素都需要data-duration,或者給容器data-cuts="0 2.13 4.27"(每個子元素開始的時間;也可以是"beats: 0 4 8"/"bars: 0 1 2")。data-gap="0.2"(負值代表重疊)。data-transition="<名稱> <秒數> [緩動]"會重疊相鄰元素並為變化製作動畫;子元素可以設定自己的data-transition(它如何進入)。每個轉場會從總時長中扣除其長度:3 個各 4 秒的場景,帶有fade 0.5,總長度為 11 秒。在節拍上剪輯、data-cut-align,以及場景時間 0 的位置:references/timeline.md。 - 轉場:
push-/cover-/whip-/wipe-+left/right/up/down(push:新元素將舊元素推出;cover:新元素滑過覆蓋;whip:快速、模糊)diagonalclockiriszoomzoom-through(舊場景飛過)flip(3D)dip(透過黑色)blurfade-upfade,以及morph:兩個場景中具有相同data-morph="name"的元素,會從舊位置飛躍並縮放到新位置,同時其餘部分進行交叉淡變。可用於攜帶 logo、卡片或數字跨場景;在單一場景內使用gm.fly。 - CSS 動畫在片段的時間軸上運行。
animation: fade-up .6s .4s both在其片段出現後 0.4 秒開始。使用both(或backwards)填滿模式,以便元素在延遲前保持隱藏。 - 在一個長場景內部,某物較晚出現(一個攝影機世界、一個白板):
data-enter中的延遲從元素自身的片段開始算起,所以data-enter="write 0.8 11.9"會在場景開始後 11.9 秒寫入一個標籤,並在此之前保持隱藏。不需要額外的片段。 gm.onFrame(fn)取得影片的時間,即使在場景內也一樣;gm.onFrame('#s', (local, info, el) => …)從#s的開始算起,就像gm.timeline('#s')。- 計時器、
requestAnimationFrame、Date.now()、performance.now()都是虛擬的,並且Math.random()是種子化的。一般的網頁動畫程式碼可以正常運作。
時間軸:精確編排(內建,類似 GSAP)
對於任何包含多個移動部件的內容,使用 gm.timeline:你熟悉的 GSAP API,根據時間計算(影格精確、並行)。時間是相對於包含該範圍的片段的秒數。
gm.timeline('#scene2') // 範圍:選擇器在其中查找
.from('.title .gm-word', { y: 120, opacity: 0, rotate: 8, stagger: 0.06 }) // 無緩動:彈簧式進入
.to('.card', { x: 400, y: -60, scale: 1.2 }, '+=0.3') // 弧形運動,尺寸適應距離
.fromTo('.bar', { scaleY: 0 }, { scaleY: 1, stagger: { each: 0.08, from: 'center' } }, '<')
.to('#line', { draw: 1, duration: 1.5 }, 2) // 繪製 SVG 筆畫
.to('.price', { textContent: 249, duration: 1.5 }, 2.5); // 數字計數
gm.fly('#event', { from: '#slot2', at: 7.5, duration: 0.8 }); // 從另一個元素的盒子飛到自己的位置
from()/fromTo() 會從片段開始時顯示它們的起始值(在進入前隱藏)。同一屬性的重疊補間:最新的開始時間獲勝。位置、所有屬性和選項、標籤、關鍵影格、gm.fly 和 SVG 注意事項:references/timeline.md。
也內建了(表格在 references/api.md):data-enter/data-exit 預設效果、data-split、data-stagger、data-count(-roll)、data-type(打字機)、data-scramble、data-camera(推、浮動、震動…)、data-parallax、data-morph、data-fit、data-pulse、緩動名稱(GSAP 名稱有效)、預設 CSS 關鍵影格和 var(--px),以及現成的區塊(npx givemotion blocks:字幕、程式碼視窗、游標、瀏覽器視窗、圖表…)。
技術食譜(閱讀你的影片需要的)
| 你的影片包含… | 閱讀 |
|---|---|
| Logo、品牌片頭、介紹或結尾卡片 | references/techniques/logo-reveal.md |
| 大型字體重擊、堆疊、旋轉;以標題為主角 | references/techniques/kinetic-type.md |
| 文字揭示:單詞/字元、打字機、書寫、亂碼、高亮 | references/techniques/text-reveals.md |
| 攝影機移動:推、跟隨、甩、傾斜、放大細節、震動 | references/techniques/camera-moves.md |
| 多個場景交接(推、甩、變形、形狀擦除) | references/techniques/scene-transitions.md |
| 發光、光掃、漸層、顆粒、模糊、深度 | references/techniques/light-and-depth.md |
| 數字、計數器、長條/折線圖、提示框 | references/techniques/numbers-and-charts.md |
| 繪製線條、路線、地圖、圖釘、沿路徑行進 | references/techniques/paths-and-maps.md |
| 平面形狀:生長、壓縮、分裂、環繞、變形 | references/techniques/shapes-and-motion-graphics.md |
| 帶有游標、點擊、打字、列表的應用程式/UI | references/techniques/ui-demo.md |
| 編輯器中的程式碼、打字、行高亮 | references/techniques/code-on-screen.md |
| 衝擊與能量:重擊、震動、爆發、音樂節拍 | references/techniques/impacts-and-energy.md |
| 逐字字幕、直式 9:16 短片 | references/techniques/captions-vertical.md |
| 白板、草圖、手繪 | references/techniques/hand-drawn.md |
| 所有事物後面的動態背景 | references/techniques/backgrounds-and-ambient.md |
API 參考(需要時查詢)
| 當… | 閱讀 |
|---|---|
| 屬性、預設效果、緩動名稱、預設 CSS 或區塊 | references/api.md |
gm.timeline 完整內容:位置、關鍵影格、標籤、gm.fly、SVG | references/timeline.md |
gm.camera 世界、鏡頭、gm.path.travel、跟隨、視差 | references/camera.md |
gm.chart.*、圖表區塊 | references/charts.md |
圖表、箭頭、data-sketch、gm.connect、gm.shape、路徑變形 | references/diagrams.md |
音樂、節拍、旁白 + givemotion words、影片片段、字幕 | references/media-audio.md |
資料/樣板、<gm-in |
…
[為翻譯而截斷]