用 HTML + GSAP 製作專業視頻:HyperFrames 深度實踐指南

作者:沐風
日期:2026年4月18日 下午3:18
來源:WeChat 原文

整理版優先睇

速讀 5 個重點 高亮

HyperFramesHTML 當作影片嘅唯一真相來源,前端開發者可以用寫網頁嘅方式製作專業 MP4。呢篇文章從原理到實戰,詳細講解安裝配置、動畫編寫、背景音視頻引入、多場景轉場及常見錯誤修復。

整理版摘要

呢篇文章係由一位有豐富實戰經驗嘅開發者整理,佢親身用 HyperFrames 製作咗 DueSight App 產品介紹同徐霞客遊廬山日記兩條影片,從中總結出完整嘅工作流程。作者想解決嘅問題係:點樣可以畀前端開發者用慣咗嘅 HTML/CSS/JS 技能,跳過 After Effects 等專業軟件,直接製作高質素嘅影片。整體結論係:HyperFrames 特別適合以文字、數據、UI 展示為主嘅影片,例如 App 產品介紹、營銷短視頻、數據可視化等;但唔適合需要大量真人拍攝或 3D 渲染嘅場景。

核心原理係HyperFramesHTML 定義為影片嘅唯一真相來源(source of truth),透過 CLI 工具載入 HTML,用無頭瀏覽器逐幀截圖,最後用 FFmpeg 編碼成 MP4。呢個流程決定咗好多關鍵約束——timeline 必須係確定性、同步構建、禁止無限循環;影片素材必須預處理為固定 30fps 同密集關鍵幀;瀏覽器預覽同渲染行為唔一致,需要額外處理。

文章提供咗完整嘅基礎模板、背景音樂同影片嘅引入方法、多場景轉場規則(淡入淡出、模糊溶解、縮放溶解),同埋六個常見錯誤嘅修復方案。最後嘅實戰案例展示咗 HyperFrames 嘅真正威力:手機 mockup 完全用 CSS 實現,山體背景用 clip-path 配合視差動畫,古風人物插圖用 Pollinations.ai 生成再 mix-blend-…

  • 結論HyperFramesHTML 視為影片唯一真相來源,透過 GSAP 時間線控制動畫,再離線渲染成 MP4,特別適合前端開發者製作產品展示、數據可視化等影片。
  • 方法:影片由多個場景組成,每個場景必須有入場動畫,轉場可使用淡入淡出、模糊溶解、縮放溶解等效果;最後一個場景可選擇退場動畫。
  • 差異:有別於 PremiereAfter Effects 嘅專有格式,HyperFrames 用 HTML/CSS/JS 描述影片,可 Git 版本管理、自動嵌入字體、支援子合成模塊化。
  • 啟發:渲染原理決定 timeline 必須確定性、同步構建、禁止無限循環;影片素材需要預處理為固定 30fps 及密集關鍵幀,否則會出現畫面凍結。
  • 可行動點:裝好 Node.js 18+ 同 FFmpeg,用 npx hyperframes render 指令將 HTML 目錄輸出為 MP4;推薦先喺瀏覽器預覽滿意再渲染,以節省時間。
值得記低
連結 github.com

HyperFrames GitHub 倉庫

HyperFrames 官方開源倉庫,包含文檔、示例同 issue 追蹤。

筆記

FFmpeg 影片預處理指令

將 VFR 影片轉為固定 30fps 及密集關鍵幀:ffmpeg -i input.mp4 -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart output.mp4

工具

HyperFrames CLI 常用指令

渲染:npx hyperframes render <composition-dir> --output <output.mp4>;檢查:npx hyperframes lint <composition-dir>;驗證:npx hyperframes validate <composition-dir>

整理重點

核心概念:HTML 就係影片

HyperFrames 嘅核心理念好簡單:HTML 係影片嘅唯一真相來源(source of truth)。傳統工具用專有格式描述動畫,HyperFrames 就翻轉呢個過程——用普通 HTML、CSS 同 GSAP 動畫庫寫內容,再透過 CLI 工具渲染成 MP4。

渲染流程分三個階段:編譯(Compile)——將字體內聯、CDN 腳本內聯,輸出自包含 HTML;幀捕獲(Frame Capture)——啟動無頭瀏覽器(Headless Chrome),逐幀 seek timeline 並截圖;編碼(Encode)——用 FFmpeg 將 PNG 序列加音頻編碼成 MP4。

  1. 1 編譯階段:字體自動從 Google Fonts 轉 base64 內聯,外部 JS 內聯確保離線可用。
  2. 2 幀捕獲階段:預設 30fps,按 CPU 核心數並行處理。
  3. 3 編碼階段:輸出 H.264 + AACMP4 檔案。
整理重點

優缺點與適用場景

HyperFrames 嘅優點好明顯:技術棧親和力強,前端開發者幾乎零學習成本;版本可控,HTML 可以 git commit、diff、review;字體自動嵌入,渲染機器無需安裝字體;支援子合成(Sub-composition)模塊化管理;內置 lint 同 validate 工具。

缺點都要留意:視頻素材需要預處理,原始錄屏通常係 VFR(可變幀率),必須用 FFmpeg 轉成固定 30fps 同密集關鍵幀;CSS transform 同 GSAP 容易衝突,要用 xPercent/yPercent 代替;瀏覽器預覽與渲染行為不一致,要額外寫 if (!window.__hyperframes) 分支;渲染速度較慢,72 秒影片可能需時數倍。

整理重點

實戰:從模板到渲染

基礎模板嘅結構好簡單:一個 <div id="root"> 用 data-composition-id、data-width、data-height、data-duration 定義合成參數;入面放多個場景 <div>,每個場景用 z-index 控制層級,非首場景預設 opacity: 0。

GSAP timeline 必須設 paused: true,所有動畫加入 tl 後,最後註冊到 window.__timelines["main"] = tl。瀏覽器預覽時要加上 if (!window.__hyperframes) tl.play()。

基礎模板骨架 html
<div id="root" data-composition-id="main" data-width="1920" data-height="1080" data-start="0" data-duration="20">
  <div id="scene1" class="scene" style="opacity:1">
    <h1 id="title">Hello, HyperFrames</h1>
  </div>
  <div id="scene2" class="scene" style="opacity:0">
    <h2 id="subtitle">製作你的第一個影片</h2>
  </div>
</div>
<script>
  window.__timelines = window.__timelines || {};
  var tl = gsap.timeline({ paused: true });
  tl.from("#title", { opacity: 0, y: 40, duration: 1 }, 0.5);
  tl.to("#scene1", { opacity: 0, duration: 0.6 }, 8);
  tl.set("#scene1", { visibility: "hidden" }, 8.61);
  tl.fromTo("#scene2", { opacity: 0 }, { opacity: 1, duration: 0.6 }, 8.2);
  tl.from("#subtitle", { opacity: 0, x: -30, duration: 0.8 }, 8.8);
  window.__timelines["main"] = tl;
  if (!window.__hyperframes) tl.play();
</script>

渲染指令好直接:npx hyperframes render <目錄路徑> --output <輸出.mp4>,注意係傳目錄路徑,唔係 index.html 檔案路徑。

整理重點

進階功能:背景音樂與影片

背景音樂要用獨立嘅 <audio> 元素,透過 data-start、data-duration、data-track-index、data-volume 控制。瀏覽器預覽時因為自動播放限制,要加一個 click-to-play 覆蓋層。

背景影片要用 <video> 元素,加上 muted 同 playsinline 屬性。如果影片本身有聲音,需要額外加一個獨立的 <audio> 元素播放同一條影片嘅音軌,並確保 data-track-index 唔重疊。

背景音樂與影片 HTML 結構 html
<div id="root" data-composition-id="main" data-duration="34">
  <audio id="bg-music" data-start="0" data-duration="34" data-track-index="0" src="music.mp3" data-volume="0.55"></audio>
  <video id="app-video" data-start="6" data-duration="25" data-track-index="1" src="video-fixed.mp4" muted playsinline></video>
  <audio id="app-audio" data-start="6" data-duration="25" data-track-index="2" src="video-fixed.mp4" data-volume="1"></audio>
  <!-- 場景內容 -->
</div>
整理重點

常見錯誤與修復

  1. 1 瀏覽器打開一片黑:原因係 GSAP from() 喺 timeline 創建時立即設定 start state,而 timeline 係 paused,所以畫面停喺不可見狀態。解決:加上 if (!window.__hyperframes) tl.play()。
  2. 2 手機/元素位置偏移CSS 用咗 transform: translateY(-50%) 居中,GSAP 對同一元素嘅 y 做動畫時會完全覆蓋 CSS transform。解決:用 GSAP 嘅 yPercent 代替 CSS transform。
  3. 3 影片只播幾秒就消失:data-duration 設置過短,場景喺影片播完之前就結束。解決:檢查 data-duration 同合成總時長。
  4. 4 背景音樂冇聲:可能係檔案路徑錯誤(404)或瀏覽器自動播放限制。解決:確認 src 路徑正確,並加入 click-to-play 機制。
  5. 5 渲染報 "Video has sparse keyframes" 警告:影片關鍵幀間距過大。解決:用 FFmpeg 重編碼,指定 -g 30 -keyint_min 30。
  6. 6 render 命令報 "Not a directory":傳入咗 index.html 檔案路徑而非目錄路徑。解決:改為傳目錄路徑。

 

呢篇文章係整理自一次完整嘅 HyperFrames 實戰記錄,涵蓋咗框架原理、安裝配置、視頻製作成個流程,仲有背景音樂、背景視頻嘅引入方法,附帶真實踩坑經驗。


1. HyperFrames 係乜嘢?

HyperFrames 係一個以 HTML 做核心嘅視頻合成框架。佢嘅核心理念係:HTML 係視頻嘅 source of truth(唯一真相來源)

傳統視頻製作工具(例如 Premiere、After Effects)係用專有格式同二進制文件去描述動畫;HyperFrames 就將呢個過程倒轉過嚟——用普通嘅 HTML 文件、CSS 樣式同 GSAP 動畫庫嚟描述視頻內容,再經由 CLI 工具將佢渲染成 MP4。

一句講曬: HyperFrames = HTML/CSS/GSAP 寫動畫 → CLI 工具截幀 → 編碼輸出 MP4。

developer writes             HyperFrames CLI             output
  index.html          →      render engine        →    video.mp4
  (HTML + GSAP)               (headless browser + frame capture)

核心組件

組件
說明
Composition
一個 HTML 文件,透過 data-* 屬性描述時序
Timeline
GSAP timeline,控制所有動畫,一定要 { paused: true }
Clip
視頻、音頻、圖片、div 元素,透過 data-start/data-duration 定義時間點
CLInpx hyperframes render
 / lint / validate

2. 底層渲染原理

理解渲染原理係避免踩坑嘅關鍵。HyperFrames 嘅渲染流程如下:

階段一:編譯(Compile)

index.html
    │
    ├─ 字體嵌入:從 Google Fonts 獲取字體,轉為 base64 @font-face 內聯進 HTML
    ├─ CDN 腳本內聯:把外部 JS(如 GSAP CDN)下載並內聯,確保離線可用
    ├─ 元數據提取:讀取 data-duration、media 數量等
    └─ 輸出:編譯後的 HTML(自包含,不依賴網絡)

階段二:幀捕獲(Frame Capture)

編譯後的 HTML
    │
    ├─ 啓動無頭瀏覽器(Headless Chrome/系統瀏覽器)
    ├─ 加載 HTML,GSAP timeline 自動初始化(paused 狀態)
    ├─ 框架調用 timeline.seek(t) 逐幀定位
    │      └─ 默認 30fps → 每隔 1/30s 截一幀
    ├─ 對每幀截圖(Screenshot)
    └─ 多 Worker 並行處理(默認按 CPU 核心數自動配置)

階段三:編碼(Encode)

PNG 幀序列 + 音頻軌道
    │
    └─ FFmpeg 編碼 → MP4 (H.264 + AAC)

關鍵約束(由渲染原理決定)

  • • Timeline 一定要係確定性嘅seek(t) 要求每次跳到同一個時間點結果相同,所以禁止 Math.random()Date.now()
  • • Timeline 一定要同步構建:渲染引擎喺頁面加載之後同步讀取 window.__timelines,禁止喺 async/setTimeout/Promise 裏面構建。
  • • 禁止 repeat: -1:無限循環冇辦法俾 seek() 正確定位,一定要用 Math.ceil(duration / cycle) - 1 計算有限次數。
  • • 媒體元素唔可以手動控制:框架接管曬所有 video.play()/audio.play(),開發者唔準調用。

3. 優點同缺點

✅ 優點

1. 技術棧親和力強
前端開發者幾乎零學習成本。HTML + CSS + JS,冇任何專有 DSL,所有 CSS 動畫效果、GSAP 緩動函數可以直接用。

2. 版本可控
視頻源文件就係 HTML,可以 git commit、diff、review,好似代碼咁管理視頻資產。

3. 字體自動嵌入
只需喺 CSS 裏面寫 font-family: "Bricolage Grotesque",編譯器會自動從 Google Fonts 拉取並以 base64 內聯,渲染機器唔使安裝字體。

4. 強大嘅動畫能力
GSAP 係業界最成熟嘅 JS 動畫庫,支援複雜緩動、交錯動畫(stagger)、時間線嵌套。

5. 子合成(Sub-composition)
可以將長視頻拆分做多個獨立嘅 HTML 文件,透過 data-composition-src 組合,方便模塊化管理。

6. Lint + Validate 工具
內置 hyperframes lint(檢查代碼規範)同 hyperframes validate(WCAG 色彩對比度審計),輸出視頻之前可以自動發現問題。

7. 冇時長限制
理論上支援任意時長,實際限制係渲染時間同內存。


❌ 缺點

1. 視頻素材需要預先處理
原始錄屏(例如 iOS Simulator 錄製)通常係 VFR(可變幀率)+ 稀疏關鍵幀,直接使用會導致渲染卡頓、幀凍結。一定要用 FFmpeg 預先處理:

ffmpeg -i input.mp4 -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart output.mp4

2. CSS transform 同 GSAP 衝突
如果 CSS 裏面有 transform: translateY(-50%) 用嚟居中,同時 GSAP 又對同一元素嘅 y 做動畫,GSAP 會完全覆蓋 CSS transform,搞到居中失效。解決方法:將 CSS transform 換成 GSAP 嘅 xPercent/yPercent

3. 瀏覽器預覽同渲染行為不一致

  • • 瀏覽器自動播放策略:音頻一定要等用戶手勢之後先至可以播放,渲染時就冇呢個限制。
  • • 需要維護兩套邏輯(if (!window.__hyperframes) 分支)處理預覽時嘅媒體播放。

4. 本地文件 CORS 限制
瀏覽器直接打開 file:// 協議下嘅 HTML 時,帶 crossorigin="anonymous" 嘅本地資源會被 CORS 攔截。本地預覽時要整走 crossorigin 屬性,或者用本地 HTTP 服務器。

5. 外部圖片資源唔可控
用 Pollinations.ai 呢類在線圖片 API 嘅時候,渲染機器需要網絡訪問,而且圖片生成結果可能會變(建議提前下載到本地)。

6. 渲染速度比較慢
30fps 視頻,72 秒 = 2160 幀,每幀要截圖編碼,總渲染時間通常係視頻時長嘅幾倍。


4. 適合嘅使用場景

場景
適合度
說明
App 產品介紹視頻
⭐⭐⭐⭐⭐
文字動效、手機 mockup、數據展示,HTML/CSS 本身就好擅長
營銷短視頻
⭐⭐⭐⭐⭐
品牌色、排版、轉場效果完全可控
數據可視化視頻
⭐⭐⭐⭐⭐
配合 Charts.js / D3,動態圖表本身已經支援
教學/解說視頻
⭐⭐⭐⭐
古風水墨、字幕、註釋,排版能力強
社交媒體內容
⭐⭐⭐⭐
支援 1080x1920 豎屏格式
真人出鏡視頻
冇辦法處理實時攝像頭,要配合視頻素材
3D 渲染場景
⭐⭐
淨係支援 CSS 3D 變換,冇辦法調用 WebGL 渲染器

5. 安裝同環境配置

前提條件

  • • Node.js >= 18(推薦用 nvm 管理)
  • • FFmpeg(視頻預先處理必需)
# 安裝 Node.js(推薦 nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 20
nvm use 20

# 安裝 FFmpeg(macOS)

brew install ffmpeg

用 npx(唔使全局安裝)

HyperFrames 推薦透過 npx 使用,唔使全局安裝:

# 渲染視頻
npx hyperframes render <composition-dir> --output <output.mp4>

# 代碼檢查

npx hyperframes lint <composition-dir>

# 對比度審計

npx hyperframes validate <composition-dir>

⚠️ 注意:render 命令傳入嘅係目錄路徑,不是 index.html 文件路徑。

目錄結構

my-video/
├── index.html      ← 合成文件(必須)
├── video.mp4       ← 應用錄屏(可選)
├── music.mp3       ← 背景音樂(可選)
└── images/         ← 圖片資源(可選)

6. 製作第一個視頻:完整步驟

基礎模板

<!DOCTYPE html>
<html lang="zh">

<head>

  <meta charset="UTF-8" />

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js">
</script>
  <style>

    * { box-sizing: border-box; margin: 0; padding: 0; }

    body
 {
      width
: 1920px;
      height
: 1080px;
      overflow
: hidden;
      background
: #1A1A2E;
      font-family
: 'Bricolage Grotesque', sans-serif;
    }

    .scene
 {
      position
: absolute;
      top
: 0; left: 0;
      width
: 1920px; height: 1080px;
      overflow
: hidden;
    }

    #scene1
 { z-index: 1; }
    #scene2
 { z-index: 2; opacity: 0; }  /* 非首場景默認隱藏 */
  
</style>
</head>

<body>

  <div
    id
="root"
    data-composition-id
="main"
    data-width
="1920"
    data-height
="1080"
    data-start
="0"
    data-duration
="20"          <!-- 視頻總時長-->

  >
    <!-- 場景 1 -->

    <div id="scene1" class="scene">

      <h1 id="title">
Hello, HyperFrames</h1>
    </div>


    <!-- 場景 2 -->

    <div id="scene2" class="scene">

      <h2 id="subtitle">
製作你的第一個視頻</h2>
    </div>

  </div>


  <script>

    window
.__timelines = window.__timelines || {};
    var
 tl = gsap.timeline({ paused: true });  // ← 必須 paused

    // 場景 1 動畫

    tl.from("#title", { opacity: 0, y: 40, duration: 1.0, ease: "power3.out" }, 0.5);

    // 轉場:場景 1 → 場景 2(T=8s)

    var
 T1 = 8;
    tl.to("#scene1", { opacity: 0, duration: 0.6, ease: "power2.inOut" }, T1);
    tl.set("#scene1", { visibility: "hidden" }, T1 + 0.61);  // ← 防殘影
    tl.fromTo("#scene2",
      { opacity: 0 },
      { opacity: 1, duration: 0.6, ease: "power2.inOut" },
      T1
 + 0.2
    );

    // 場景 2 動畫

    tl.from("#subtitle", { opacity: 0, x: -30, duration: 0.8, ease: "expo.out" }, T1 + 0.8);

    // 註冊 timeline(必須)

    window
.__timelines["main"] = tl;

    // 瀏覽器預覽模式:自動播放

    if
 (!window.__hyperframes) {
      tl.play();
    }
  
</script>
</body>

</html>

渲染命令

# 在項目根目錄執行
npx hyperframes render my-video --output my-video/output.mp4

7. 引入背景音樂

HyperFrames 規定音頻一定要用獨立嘅 <audio> 元素(禁止用視頻元素嘅音軌),透過 data-* 屬性同時間線同步。

HTML 結構

<div id="root" data-composition-id="main" data-duration="34" ...>

  <!-- 背景音樂:src 為本地文件路徑(相對於 index.html) -->

  <audio
    id
="bg-music"
    data-start
="0"           <!-- 從第 0 秒開始播放 -->

    data-duration="34"       <!-- 播放時長(與視頻總時長一致)-->
    data-track-index="0"     <!-- 軌道編號(同軌道元素不可重疊)-->
    src="music.mp3"
    data-volume="0.55"       <!-- 音量 0–1 -->
  ></audio>

  <!-- 其他場景... -->

</div>

瀏覽器預覽時嘅音頻問題

瀏覽器安全策略禁止自動播放音頻,需要用戶手勢觸發。解決方案:

if (!window.__hyperframes) {
  // 創建點擊播放按鈕,覆蓋整個畫面

  var
 btn = document.createElement("div");
  btn.innerHTML = "▶ 點擊播放";
  btn.style.cssText = [
    "position:fixed"
, "inset:0", "display:flex",
    "align-items:center"
, "justify-content:center",
    "font-size:40px"
, "color:rgba(255,255,255,0.8)",
    "background:rgba(0,0,0,0.7)"
, "cursor:pointer",
    "z-index:9999"

  ].join(";");
  document
.body.appendChild(btn);

  btn.addEventListener("click", function() {
    btn.remove();
    document
.getElementById("bg-music").play().catch(function(){});
    tl.play();
  });
}

本地文件注意事項

  • • 不要加 crossorigin="anonymous":本地 file:// 協議下 CORS 檢查會失敗,導致音頻加載 404。
  • • 文件格式推薦 MP3 或 AAC,兼容性最好。

8. 引入背景視頻

HTML 結構

<div id="root" data-composition-id="main" data-duration="34" ...>

  <!-- 視頻軌道:muted + playsinline 是必須的 -->

  <video
    id
="app-video"
    data-start
="6"          <!-- 在時間線第 6 秒開始播放 -->

    data-duration="25"      <!-- 播放 25 秒 -->
    data-track-index="1"    <!-- 軌道編號 -->
    src="video.mp4"
    muted
    playsinline
    style="display:block; width:100%; height:100%; object-fit:cover;"
  ></video>

  <!-- 同時需要獨立的音頻元素來播放視頻的聲音(如果需要) -->

  <audio
    id
="app-audio"
    data-start
="6"
    data-duration
="25"
    data-track-index
="2"
    src
="video.mp4"
    data-volume
="1"
  >
</audio>

</div>

⚠️ data-track-index 相同嘅 clip 唔能夠喺時間上重疊,但唔影響視覺層級(層級用 CSS z-index 控制)。

視頻預先處理(重要!)

iOS 模擬器錄屏、手機錄製嘅視頻通常係 VFR(可變幀率),且關鍵幀間距過大,直接用喺 HyperFrames 會導致:

  • • 畫面凍結
  • • 幀跳躍
  • • seek 失敗

一定要用 FFmpeg 預先處理:

ffmpeg -i input.mp4 \
  -c:v libx264 \
  -r 30 \          # 固定 30fps
  -g 30 \          # 每 30 幀一個關鍵幀(1 秒一個)
  -keyint_min 30 \ # 最小關鍵幀間距
  -movflags +faststart \
  -c:a copy \
  output-fixed.mp4

瀏覽器預覽時嘅視頻播放

渲染時框架會自動控制視頻播放,瀏覽器預覽時就要手動觸發:

var appVid = document.getElementById("app-video");

// 視頻加載失敗時顯示佔位符

appVid.addEventListener("error", function() {
  document
.getElementById("placeholder").style.display = "flex";
});

if
 (!window.__hyperframes) {
  // 在 timeline 到達視頻開始時間時觸發播放

  tl.call(function() {
    appVid.play().catch(function(){});
  }, [], 6);  // 第 6 秒觸發
}

9. 多場景切換同轉場

規則(非常重要)

  1. 1. 一定要有轉場:禁止直接跳切(jump cut)
  2. 2. 每個場景一定要有入場動畫:所有元素透過 gsap.from() 動畫進入,禁止直接出現
  3. 3. 淨係最後一個場景可以有退場動畫:其他場景嘅「退出」由轉場效果承擔
  4. 4. 轉場後一定要加 visibility 硬關閉:防止舊場景殘影
// ✅ 正確寫法
var
 T1 = 8;  // 轉場時間點

// 場景退出

tl.to("#scene1", { opacity: 0, duration: 0.6 }, T1);
tl.set("#scene1", { visibility: "hidden" }, T1 + 0.61);  // 硬關閉

// 場景進入

tl.fromTo("#scene2",
  { opacity: 0 },
  { opacity: 1, duration: 0.6 },
  T1
 + 0.2
);

// 場景 2 入場動畫(必須有)

var
 S2 = T1 + 0.8;
tl.from("#s2-title",    { y: 50, opacity: 0, duration: 0.8, ease: "power3.out" }, S2);
tl.from("#s2-subtitle", { y: 30, opacity: 0, duration: 0.6, ease: "power2.out" }, S2 + 0.3);

常見轉場類型

// 淡入淡出(最簡單)
tl.to("#scene1", { opacity: 0, duration: 0.5 }, T);
tl.fromTo("#scene2", { opacity: 0 }, { opacity: 1, duration: 0.5 }, T + 0.1);

// 模糊溶解(電影感)

tl.to("#scene1", { filter: "blur(20px)", opacity: 0, duration: 0.7 }, T);
tl.fromTo("#scene2",
  { filter: "blur(20px)", opacity: 0 },
  { filter: "blur(0px)", opacity: 1, duration: 0.7 },
  T + 0.2
);

// 縮放溶解(有力量感)

tl.to("#scene1", { scale: 1.05, opacity: 0, duration: 0.8 }, T);
tl.fromTo("#scene2",
  { scale: 0.95, opacity: 0 },
  { scale: 1, opacity: 1, duration: 0.8 },
  T + 0.2
);

10. 常見錯誤同修復

問題一:瀏覽器打開一片黑

原因:GSAP from() 喺 timeline 創建時即刻設置 start state(opacity: 0),而 timeline 係 paused 嘅,所以畫面停咗喺所有元素都睇唔到嘅狀態。

修復

if (!window.__hyperframes) {
  tl.play();  // 瀏覽器預覽時自動播放
}

問題二:手機/元素位置偏移

原因:CSS 用咗 transform: translateY(-50%) 進行垂直居中,GSAP 對同一元素嘅 y 做動畫時會完全覆蓋 CSS transform,居中失效。

修復

/* ❌ 錯誤:依賴 CSS transform 居中 */
#phone-wrap
 {
  top
: 50%;
  transform
: translateY(-50%);  /* 會被 GSAP 覆蓋 */
}
// ✅ 正確:用 GSAP 的 yPercent 代替 CSS transform
tl.set("#phone-wrap", { yPercent: -50 }, 0);

// 入場動畫保持 yPercent

tl.fromTo("#phone-wrap",
  { yPercent: -50, y: 160, opacity: 0 },
  { yPercent: -50, y: 0,   opacity: 1, duration: 1.2 },
  S2
 + 0.35
);

問題三:視頻只係播幾秒就消失

原因data-duration 設置得太短,場景喺視頻播完之前就已經結束咗。

修復:檢查 data-duration 係咪覆蓋咗完整嘅視頻播放時間,並確保總合成時長足夠長。


問題四:背景音樂冇聲

可能原因有兩個:

  1. 1. 文件揾唔到(404):檢查 src 路徑係咪正確,music.mp3 係咪存在於 index.html 同級目錄。
  2. 2. 瀏覽器自動播放限制:需要用戶手勢觸發,參考第 7 節嘅 click-to-play 方案。

問題五:渲染報「Video has sparse keyframes」警告

原因:視頻嘅關鍵幀間距過大(例如截圖中顯示 max interval: 20.13s),搞到 seek 失敗、畫面凍結。

修復:用 FFmpeg 重新編碼(參考第 8 節預先處理命令)。


問題六:render 命令報「Not a directory」

原因:傳入咗 index.html 文件路徑而唔係目錄路徑。

# ❌ 錯誤
npx hyperframes render video/product-intro/index.html

# ✅ 正確

npx hyperframes render video/product-intro

11. 實戰案例:DueSight App 產品介紹視頻

目標

  • • 時長 35 秒
  • • 3 個場景:氛圍開場 → App 展示(手機 mockup + 25s 應用錄屏) → CTA 結尾
  • • 淺色背景(#EEEDF8
  • • 背景音樂

手機 Mockup 實現

手機外殼完全用 CSS 實現,唔依賴任何圖片資源:

<div id="phone-wrap">
  <div id="phone-frame">

    <!-- 側邊按鈕 -->

    <div class="phone-btn" id="btn-vol-up">
</div>
    <div class="phone-btn" id="btn-vol-dn">
</div>
    <div class="phone-btn" id="btn-power">
</div>

    <!-- 屏幕 -->

    <div id="phone-screen">

      <video id="app-video" data-start="6" data-duration="25"
        data-track-index
="1" src="video-fixed.mp4" muted playsinline>
</video>
    </div>


    <!-- Dynamic Island -->

    <div id="phone-island">
</div>
  </div>

</div>
#phone-frame {
  width
: 390px; height: 840px;
  background
: linear-gradient(160deg, #2C2C42 0%, #1A1A2C 100%);
  border-radius
: 56px;
  box-shadow
:
    0
 70px 180px rgba(26,26,46,0.28),
    0
 24px 64px rgba(26,26,46,0.16),
    inset 0 1px 0 rgba(255,255,255,0.13);
}

執行腳本

安裝 hyperframes:

npx skills add heygen-com/hyperframes

喺 Claude Code 入面執行生成 html 提示詞:

Using /hyperframes, create a 25-second product intro with a fade-in title, a background video, and background music.

喺 html 所在目錄放 video.mp4、music.mp3、images/

視頻同音樂係可選嘅

  • • 冇 video.mp4 / music.mp3 → 背景只係顯示 #EEEDF8 淺色,文字動畫正常運行,完全可以就咁用
  • • 有嘅話放喺同一目錄 video/product-intro/ 就會自動加載

導出做真正嘅 MP4 視頻文件,需要先安裝 HyperFrames cli:

npm install -g @hyperframes/cli

安裝之後導出 mp4 視頻:

cd /Users/Work/iOS_Projects/DueSight
npx hyperframes render video/product-intro --output video/product-intro/product-intro.mp4

注意:

hyperframes render 接受嘅係目錄路徑,唔係 HTML 文件路徑,佢會自動揾目錄裏面嘅 index.html。


推薦做法: 先喺瀏覽器裏面預覽滿意,再安裝 HyperFrames 導出 MP4。如果你只係想做 App Store
預覽視頻,視頻背景唔係必要嘅,淺色純底效果本身已經好乾淨。

渲染結果

渲染之後嘅視頻包含完整嘅手機動效、App 錄屏同步播放,以及字體渲染——全部透過 HTML/CSS 實現,唔使設計工具。

實戰生成嘅視頻:


12. 實戰案例:徐霞客遊廬山日記水墨學習視頻

目標

  • • 時長 72 秒
  • • 6 個場景:題目 + 5 段原文(配現代漢語註釋)
  • • 水墨風格(#0C100B 深色背景、金色高亮、青綠註釋)
  • • CSS 多層山體剪影(clip-path: polygon)視差背景
  • • 古風字體(ZCOOL 小薇 + Noto Serif SC)

山體背景實現

三層山體疊加,產生遠近縱深感:

#mtn-far {
  position
: absolute;
  bottom
: 0; left: 0;
  width
: 1920px; height: 520px;
  background
: #131A11;
  clip-path
: polygon(
    0
 100%, 0 55%,
    180px
 42%, 360px 58%, 540px 28%, 680px 48%,
    820px
 18%, 960px 38%, 1100px 22%, 1240px 44%,
    1380px
 30%, 1520px 50%, 1680px 35%, 1800px 52%,
    1920px
 42%, 1920px 100%
  );
}
// 視差:三層山體以不同速度漂移
tl.to("#mtn-far",  { x: -40,  duration: 72, ease: "none" }, 0);
tl.to("#mtn-mid",  { x: -70,  duration: 72, ease: "none" }, 0);
tl.to("#mtn-near", { x: -100, duration: 72, ease: "none" }, 0);

古風人物插圖版(v2)

喺文字版基礎上,v2 引入咗從 Pollinations.ai 生成嘅古風水墨人物插圖:

  • • 6 個場景各一幅:站立、穿越石縫、遠眺、峯頂、探崖、執筆
  • • 人物圖片用 mix-blend-mode: screen 同深色背景融合,黑色部分會透明消融
  • • Pollinations.ai 請求參數入面指定 pure black background white ink brush strokes,配合 screen 模式產生水墨融入效果
.char-figure {
  position
: absolute;
  right
: 70px; bottom: 0;
  width
: 520px;
  mix-blend-mode
: screen;   /* 黑色背景透明化 */
  filter
: contrast(1.12) brightness(0.92) sepia(0.08);
}
<img id="s2-char" class="char-figure"
  src
="https://image.pollinations.ai/prompt/ancient+Chinese+explorer+squeezing+through+narrow+rocky+gorge+...+white+ink+brush+painting+pure+black+background+guofeng?width=520&height=1040&seed=3002&nologo=true&model=flux"
  alt
="" crossorigin="anonymous" />

13. 總結

HyperFrames 代表咗一種新嘅視頻製作思路:將視頻當代碼嚟寫。佢特別適合技術背景嘅創作者,以及需要將設計系統(Design Token、品牌色、字體)精確落地到視頻內容嘅場景。

選擇 HyperFrames 嘅最佳時機:

  • • 你已經有前端開發經驗,唔想學 After Effects
  • • 視頻內容以文字、數據、UI 界面展示為主
  • • 需要批量生成風格一致嘅視頻
  • • 視頻內容需要版本管理同團隊協作

唔適合嘅場景:

  • • 需要大量真人拍攝素材剪輯
  • • 需要 3D 建模渲染
  • • 需要實時合成(HyperFrames 係離線渲染)

總之,HyperFrames 結合 Claude Code 呢種方式去製作 AppStore 宣傳視頻,效果都算幾好,但係唔適合製作長視頻,例如《徐霞客遊記》呢啲長視頻,人物、動畫都仲係唔夠好。

不過相信未來隨住 AI 嘅發展,以後創作視頻嘅門檻會越來越低。

喺咁樣一個 AI 日新月異嘅時代裏面,真正被重新定義嘅唔單止係我哋嘅工作方式,仲有我哋對生產力同創造力嘅理解。AI 唔會取代人類對美嘅判斷、對品牌嘅洞察、對戰略嘅規劃,但佢嘅到來卻令到每個人都有機會更加專注喺呢啲最具價值嘅能力上。

我哋需要好好經營嘅係自己嘅品味同決策力。有咗呢樣嘢,喺 AI 時代,我先至可以有所作為。


文章係基於 HyperFrames 實戰經驗整理,案例代碼都經過真實渲染驗證。

工具鏈:HyperFrames + GSAP 3.14 + FFmpeg 7.1

參考:

  1. 1. github hyperframes : https://github.com/heygen-com/hyperframes

2026.04.18 22:58
📍 滬 · 趙巷

📌 聲明:本文由 AI 輔助完成

 


 

本文整理自一次完整的 HyperFrames 實戰記錄,涵蓋框架原理、安裝配置、視頻製作全流程,以及背景音樂、背景視頻的引入方法,並附上真實踩坑經驗。


1. HyperFrames 是什麼

HyperFrames 是一個以 HTML 為核心的視頻合成框架。它的核心理念是:HTML 是視頻的 source of truth(唯一真相來源)

傳統視頻製作工具(如 Premiere、After Effects)使用專有格式和二進制文件描述動畫;HyperFrames 把這個過程翻轉過來——用普通的 HTML 文件、CSS 樣式和 GSAP 動畫庫來描述視頻內容,再通過 CLI 工具把它渲染成 MP4。

一句話概括: HyperFrames = HTML/CSS/GSAP 寫動畫 → CLI 工具截幀 → 編碼輸出 MP4。

developer writes             HyperFrames CLI             output
  index.html          →      render engine        →    video.mp4
  (HTML + GSAP)               (headless browser + frame capture)

核心組件

組件
說明
Composition
一個 HTML 文件,通過 data-* 屬性描述時序
Timeline
GSAP timeline,控制所有動畫,必須 { paused: true }
Clip
視頻、音頻、圖片、div 元素,通過 data-start/data-duration 定義時間點
CLInpx hyperframes render
 / lint / validate

2. 底層渲染原理

理解渲染原理是避免踩坑的關鍵。HyperFrames 的渲染流程如下:

階段一:編譯(Compile)

index.html
    │
    ├─ 字體嵌入:從 Google Fonts 獲取字體,轉為 base64 @font-face 內聯進 HTML
    ├─ CDN 腳本內聯:把外部 JS(如 GSAP CDN)下載並內聯,確保離線可用
    ├─ 元數據提取:讀取 data-duration、media 數量等
    └─ 輸出:編譯後的 HTML(自包含,不依賴網絡)

階段二:幀捕獲(Frame Capture)

編譯後的 HTML
    │
    ├─ 啓動無頭瀏覽器(Headless Chrome/系統瀏覽器)
    ├─ 加載 HTML,GSAP timeline 自動初始化(paused 狀態)
    ├─ 框架調用 timeline.seek(t) 逐幀定位
    │      └─ 默認 30fps → 每隔 1/30s 截一幀
    ├─ 對每幀截圖(Screenshot)
    └─ 多 Worker 並行處理(默認按 CPU 核心數自動配置)

階段三:編碼(Encode)

PNG 幀序列 + 音頻軌道
    │
    └─ FFmpeg 編碼 → MP4 (H.264 + AAC)

關鍵約束(由渲染原理決定)

  • • Timeline 必須是確定性的seek(t) 要求每次跳到同一時間點結果相同,因此禁止 Math.random()Date.now()
  • • Timeline 必須同步構建:渲染引擎在頁面加載後同步讀取 window.__timelines,禁止在 async/setTimeout/Promise 內構建。
  • • 禁止 repeat: -1:無限循環無法被 seek() 正確定位,必須用 Math.ceil(duration / cycle) - 1 計算有限次數。
  • • 媒體元素不可手動控制:框架接管所有 video.play()/audio.play(),開發者不得調用。

3. 優點與缺點

✅ 優點

1. 技術棧親和力強
前端開發者幾乎零學習成本。HTML + CSS + JS,沒有任何專有 DSL,所有 CSS 動畫效果、GSAP 緩動函數直接可用。

2. 版本可控
視頻源文件就是 HTML,可以 git commit、diff、review,像代碼一樣管理視頻資產。

3. 字體自動嵌入
只需在 CSS 裏寫 font-family: "Bricolage Grotesque",編譯器自動從 Google Fonts 拉取並以 base64 內聯,渲染機器無需安裝字體。

4. 強大的動畫能力
GSAP 是業界最成熟的 JS 動畫庫,支持複雜緩動、交錯動畫(stagger)、時間線嵌套。

5. 子合成(Sub-composition)
可以把長視頻拆分為多個獨立的 HTML 文件,通過 data-composition-src 組合,便於模塊化管理。

6. Lint + Validate 工具
內置 hyperframes lint(檢查代碼規範)和 hyperframes validate(WCAG 色彩對比度審計),輸出視頻前可自動發現問題。

7. 無時長限制
理論上支持任意時長,實際限制是渲染時間和內存。


❌ 缺點

1. 視頻素材需要預處理
原始錄屏(如 iOS Simulator 錄製)通常是 VFR(可變幀率)+ 稀疏關鍵幀,直接使用會導致渲染卡頓、幀凍結。必須用 FFmpeg 預處理:

ffmpeg -i input.mp4 -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart output.mp4

2. CSS transform 與 GSAP 衝突
如果 CSS 裏有 transform: translateY(-50%) 用於居中,同時 GSAP 又對同一元素的 y 做動畫,GSAP 會完全覆蓋 CSS transform,導致居中失效。解決方法:把 CSS transform 換成 GSAP 的 xPercent/yPercent

3. 瀏覽器預覽與渲染行為不一致

  • • 瀏覽器自動播放策略:音頻必須等用戶手勢後才能播放,渲染時沒有此限制。
  • • 需要維護兩套邏輯(if (!window.__hyperframes) 分支)處理預覽時的媒體播放。

4. 本地文件 CORS 限制
瀏覽器直接打開 file:// 協議下的 HTML 時,帶 crossorigin="anonymous" 的本地資源會被 CORS 攔截。本地預覽時需去掉 crossorigin 屬性,或用本地 HTTP 服務器。

5. 外部圖片資源不可控
使用 Pollinations.ai 等在線圖片 API 時,渲染機器需要網絡訪問,且圖片生成結果可能變化(建議提前下載到本地)。

6. 渲染速度較慢
30fps 視頻,72 秒 = 2160 幀,每幀需截圖編碼,總渲染時間通常是視頻時長的數倍。


4. 適合的使用場景

場景
適合度
說明
App 產品介紹視頻
⭐⭐⭐⭐⭐
文字動效、手機 mockup、數據展示,HTML/CSS 天然擅長
營銷短視頻
⭐⭐⭐⭐⭐
品牌色、排版、轉場效果完全可控
數據可視化視頻
⭐⭐⭐⭐⭐
配合 Charts.js / D3,動態圖表天然支持
教學/解說視頻
⭐⭐⭐⭐
古風水墨、字幕、註釋,排版能力強
社交媒體內容
⭐⭐⭐⭐
支持 1080x1920 豎屏格式
真人出鏡視頻
無法處理實時攝像頭,需配合視頻素材
3D 渲染場景
⭐⭐
僅支持 CSS 3D 變換,無法調用 WebGL 渲染器

5. 安裝與環境配置

前提條件

  • • Node.js >= 18(推薦使用 nvm 管理)
  • • FFmpeg(視頻預處理必需)
# 安裝 Node.js(推薦 nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 20
nvm use 20

# 安裝 FFmpeg(macOS)

brew install ffmpeg

使用 npx(無需全局安裝)

HyperFrames 推薦通過 npx 使用,無需全局安裝:

# 渲染視頻
npx hyperframes render <composition-dir> --output <output.mp4>

# 代碼檢查

npx hyperframes lint <composition-dir>

# 對比度審計

npx hyperframes validate <composition-dir>

⚠️ 注意:render 命令傳入的是目錄路徑,不是 index.html 文件路徑。

目錄結構

my-video/
├── index.html      ← 合成文件(必須)
├── video.mp4       ← 應用錄屏(可選)
├── music.mp3       ← 背景音樂(可選)
└── images/         ← 圖片資源(可選)

6. 製作第一個視頻:完整步驟

基礎模板

<!DOCTYPE html>
<html lang="zh">

<head>

  <meta charset="UTF-8" />

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js">
</script>
  <style>

    * { box-sizing: border-box; margin: 0; padding: 0; }

    body
 {
      width
: 1920px;
      height
: 1080px;
      overflow
: hidden;
      background
: #1A1A2E;
      font-family
: 'Bricolage Grotesque', sans-serif;
    }

    .scene
 {
      position
: absolute;
      top
: 0; left: 0;
      width
: 1920px; height: 1080px;
      overflow
: hidden;
    }

    #scene1
 { z-index: 1; }
    #scene2
 { z-index: 2; opacity: 0; }  /* 非首場景默認隱藏 */
  
</style>
</head>

<body>

  <div
    id
="root"
    data-composition-id
="main"
    data-width
="1920"
    data-height
="1080"
    data-start
="0"
    data-duration
="20"          <!-- 視頻總時長-->

  >
    <!-- 場景 1 -->

    <div id="scene1" class="scene">

      <h1 id="title">
Hello, HyperFrames</h1>
    </div>


    <!-- 場景 2 -->

    <div id="scene2" class="scene">

      <h2 id="subtitle">
製作你的第一個視頻</h2>
    </div>

  </div>


  <script>

    window
.__timelines = window.__timelines || {};
    var
 tl = gsap.timeline({ paused: true });  // ← 必須 paused

    // 場景 1 動畫

    tl.from("#title", { opacity: 0, y: 40, duration: 1.0, ease: "power3.out" }, 0.5);

    // 轉場:場景 1 → 場景 2(T=8s)

    var
 T1 = 8;
    tl.to("#scene1", { opacity: 0, duration: 0.6, ease: "power2.inOut" }, T1);
    tl.set("#scene1", { visibility: "hidden" }, T1 + 0.61);  // ← 防殘影
    tl.fromTo("#scene2",
      { opacity: 0 },
      { opacity: 1, duration: 0.6, ease: "power2.inOut" },
      T1
 + 0.2
    );

    // 場景 2 動畫

    tl.from("#subtitle", { opacity: 0, x: -30, duration: 0.8, ease: "expo.out" }, T1 + 0.8);

    // 註冊 timeline(必須)

    window
.__timelines["main"] = tl;

    // 瀏覽器預覽模式:自動播放

    if
 (!window.__hyperframes) {
      tl.play();
    }
  
</script>
</body>

</html>

渲染命令

# 在項目根目錄執行
npx hyperframes render my-video --output my-video/output.mp4

7. 引入背景音樂

HyperFrames 規定音頻必須使用獨立的 <audio> 元素(禁止用視頻元素的音軌),通過 data-* 屬性與時間線同步。

HTML 結構

<div id="root" data-composition-id="main" data-duration="34" ...>

  <!-- 背景音樂:src 為本地文件路徑(相對於 index.html) -->

  <audio
    id
="bg-music"
    data-start
="0"           <!-- 從第 0 秒開始播放 -->

    data-duration="34"       <!-- 播放時長(與視頻總時長一致)-->
    data-track-index="0"     <!-- 軌道編號(同軌道元素不可重疊)-->
    src="music.mp3"
    data-volume="0.55"       <!-- 音量 0–1 -->
  ></audio>

  <!-- 其他場景... -->

</div>

瀏覽器預覽時的音頻問題

瀏覽器安全策略禁止自動播放音頻,需要用戶手勢觸發。解決方案:

if (!window.__hyperframes) {
  // 創建點擊播放按鈕,覆蓋整個畫面

  var
 btn = document.createElement("div");
  btn.innerHTML = "▶ 點擊播放";
  btn.style.cssText = [
    "position:fixed"
, "inset:0", "display:flex",
    "align-items:center"
, "justify-content:center",
    "font-size:40px"
, "color:rgba(255,255,255,0.8)",
    "background:rgba(0,0,0,0.7)"
, "cursor:pointer",
    "z-index:9999"

  ].join(";");
  document
.body.appendChild(btn);

  btn.addEventListener("click", function() {
    btn.remove();
    document
.getElementById("bg-music").play().catch(function(){});
    tl.play();
  });
}

本地文件注意事項

  • • 不要加 crossorigin="anonymous":本地 file:// 協議下 CORS 檢查會失敗,導致音頻加載 404。
  • • 文件格式推薦 MP3 或 AAC,兼容性最好。

8. 引入背景視頻

HTML 結構

<div id="root" data-composition-id="main" data-duration="34" ...>

  <!-- 視頻軌道:muted + playsinline 是必須的 -->

  <video
    id
="app-video"
    data-start
="6"          <!-- 在時間線第 6 秒開始播放 -->

    data-duration="25"      <!-- 播放 25 秒 -->
    data-track-index="1"    <!-- 軌道編號 -->
    src="video.mp4"
    muted
    playsinline
    style="display:block; width:100%; height:100%; object-fit:cover;"
  ></video>

  <!-- 同時需要獨立的音頻元素來播放視頻的聲音(如果需要) -->

  <audio
    id
="app-audio"
    data-start
="6"
    data-duration
="25"
    data-track-index
="2"
    src
="video.mp4"
    data-volume
="1"
  >
</audio>

</div>

⚠️ data-track-index 相同的 clip 不能在時間上重疊,但不影響視覺層級(層級用 CSS z-index 控制)。

視頻預處理(重要!)

iOS 模擬器錄屏、手機錄製的視頻通常是 VFR(可變幀率),且關鍵幀間距過大,直接用於 HyperFrames 會導致:

  • • 畫面凍結
  • • 幀跳躍
  • • seek 失敗

必須用 FFmpeg 預處理:

ffmpeg -i input.mp4 \
  -c:v libx264 \
  -r 30 \          # 固定 30fps
  -g 30 \          # 每 30 幀一個關鍵幀(1 秒一個)
  -keyint_min 30 \ # 最小關鍵幀間距
  -movflags +faststart \
  -c:a copy \
  output-fixed.mp4

瀏覽器預覽時的視頻播放

渲染時框架自動控制視頻播放,瀏覽器預覽時需要手動觸發:

var appVid = document.getElementById("app-video");

// 視頻加載失敗時顯示佔位符

appVid.addEventListener("error", function() {
  document
.getElementById("placeholder").style.display = "flex";
});

if
 (!window.__hyperframes) {
  // 在 timeline 到達視頻開始時間時觸發播放

  tl.call(function() {
    appVid.play().catch(function(){});
  }, [], 6);  // 第 6 秒觸發
}

9. 多場景切換與轉場

規則(非常重要)

  1. 1. 必須有轉場:禁止直接跳切(jump cut)
  2. 2. 每個場景必須有入場動畫:所有元素通過 gsap.from() 動畫進入,禁止直接出現
  3. 3. 僅最後一個場景可以有退場動畫:其他場景的"退出"由轉場效果承擔
  4. 4. 轉場後必須添加 visibility 硬關閉:防止舊場景殘影
// ✅ 正確寫法
var
 T1 = 8;  // 轉場時間點

// 場景退出

tl.to("#scene1", { opacity: 0, duration: 0.6 }, T1);
tl.set("#scene1", { visibility: "hidden" }, T1 + 0.61);  // 硬關閉

// 場景進入

tl.fromTo("#scene2",
  { opacity: 0 },
  { opacity: 1, duration: 0.6 },
  T1
 + 0.2
);

// 場景 2 入場動畫(必須有)

var
 S2 = T1 + 0.8;
tl.from("#s2-title",    { y: 50, opacity: 0, duration: 0.8, ease: "power3.out" }, S2);
tl.from("#s2-subtitle", { y: 30, opacity: 0, duration: 0.6, ease: "power2.out" }, S2 + 0.3);

常見轉場類型

// 淡入淡出(最簡單)
tl.to("#scene1", { opacity: 0, duration: 0.5 }, T);
tl.fromTo("#scene2", { opacity: 0 }, { opacity: 1, duration: 0.5 }, T + 0.1);

// 模糊溶解(電影感)

tl.to("#scene1", { filter: "blur(20px)", opacity: 0, duration: 0.7 }, T);
tl.fromTo("#scene2",
  { filter: "blur(20px)", opacity: 0 },
  { filter: "blur(0px)", opacity: 1, duration: 0.7 },
  T + 0.2
);

// 縮放溶解(有力量感)

tl.to("#scene1", { scale: 1.05, opacity: 0, duration: 0.8 }, T);
tl.fromTo("#scene2",
  { scale: 0.95, opacity: 0 },
  { scale: 1, opacity: 1, duration: 0.8 },
  T + 0.2
);

10. 常見錯誤與修復

問題一:瀏覽器打開一片黑

原因:GSAP from() 在 timeline 創建時立即設置 start state(opacity: 0),而 timeline 是 paused 的,所以畫面停在所有元素都不可見的狀態。

修復

if (!window.__hyperframes) {
  tl.play();  // 瀏覽器預覽時自動播放
}

問題二:手機/元素位置偏移

原因:CSS 使用了 transform: translateY(-50%) 進行垂直居中,GSAP 對同元素的 y 做動畫時會完全覆蓋 CSS transform,居中失效。

修復

/* ❌ 錯誤:依賴 CSS transform 居中 */
#phone-wrap
 {
  top
: 50%;
  transform
: translateY(-50%);  /* 會被 GSAP 覆蓋 */
}
// ✅ 正確:用 GSAP 的 yPercent 代替 CSS transform
tl.set("#phone-wrap", { yPercent: -50 }, 0);

// 入場動畫保持 yPercent

tl.fromTo("#phone-wrap",
  { yPercent: -50, y: 160, opacity: 0 },
  { yPercent: -50, y: 0,   opacity: 1, duration: 1.2 },
  S2
 + 0.35
);

問題三:視頻只播幾秒就消失

原因data-duration 設置過短,場景在視頻播完之前就結束了。

修復:檢查 data-duration 是否覆蓋了完整的視頻播放時間,並確保總合成時長足夠長。


問題四:背景音樂沒聲音

可能原因有兩個:

  1. 1. 文件找不到(404):檢查 src 路徑是否正確,music.mp3 是否存在於 index.html 同級目錄。
  2. 2. 瀏覽器自動播放限制:需要用戶手勢觸發,參考第 7 節的 click-to-play 方案。

問題五:渲染報 "Video has sparse keyframes" 警告

原因:視頻的關鍵幀間距過大(如截圖中顯示 max interval: 20.13s),導致 seek 失敗、畫面凍結。

修復:使用 FFmpeg 重編碼(參考第 8 節預處理命令)。


問題六:render 命令報 "Not a directory"

原因:傳入了 index.html 文件路徑而不是目錄路徑。

# ❌ 錯誤
npx hyperframes render video/product-intro/index.html

# ✅ 正確

npx hyperframes render video/product-intro

11. 實戰案例:DueSight App 產品介紹視頻

目標

  • • 時長 35 秒
  • • 3 個場景:氛圍開場 → App 展示(手機 mockup + 25s 應用錄屏) → CTA 結尾
  • • 淺色背景(#EEEDF8
  • • 背景音樂

手機 Mockup 實現

手機外殼完全用 CSS 實現,不依賴任何圖片資源:

<div id="phone-wrap">
  <div id="phone-frame">

    <!-- 側邊按鈕 -->

    <div class="phone-btn" id="btn-vol-up">
</div>
    <div class="phone-btn" id="btn-vol-dn">
</div>
    <div class="phone-btn" id="btn-power">
</div>

    <!-- 屏幕 -->

    <div id="phone-screen">

      <video id="app-video" data-start="6" data-duration="25"
        data-track-index
="1" src="video-fixed.mp4" muted playsinline>
</video>
    </div>


    <!-- Dynamic Island -->

    <div id="phone-island">
</div>
  </div>

</div>
#phone-frame {
  width
: 390px; height: 840px;
  background
: linear-gradient(160deg, #2C2C42 0%, #1A1A2C 100%);
  border-radius
: 56px;
  box-shadow
:
    0
 70px 180px rgba(26,26,46,0.28),
    0
 24px 64px rgba(26,26,46,0.16),
    inset 0 1px 0 rgba(255,255,255,0.13);
}

執行腳本

安裝 hyperframes:

npx skills add heygen-com/hyperframes

在 Claude Code 中執行生成 html 提示詞:

Using /hyperframes, create a 25-second product intro with a fade-in title, a background video, and background music.

在 html 所在目錄放入video.mp4、music.mp3、images/

視頻和音樂是可選的

  • • 沒有 video.mp4 / music.mp3 → 背景只顯示 #EEEDF8 淺色,文字動畫正常運行,完全可以用
  • • 有的話放進同一目錄 video/product-intro/ 就會自動加載

導出成真正的 MP4 視頻文件,需要先安裝 HyperFrames cli:

npm install -g @hyperframes/cli

安裝後導出 mp4 視頻:

cd /Users/Work/iOS_Projects/DueSight
npx hyperframes render video/product-intro --output video/product-intro/product-intro.mp4

注意:

hyperframes render 接受的是目錄路徑,不是 HTML 文件路徑,它會自動找目錄裏的 index.html。


推薦做法: 先在瀏覽器裏預覽滿意,再安裝 HyperFrames 導出 MP4。如果你只是想做 App Store
預覽視頻,視頻背景不是必須的,淺色純底效果本身就很乾淨。

渲染結果

渲染後的視頻包含完整的手機動效、App 錄屏同步播放,以及字體渲染——全部通過 HTML/CSS 實現,無需設計工具。

實戰生成的視頻:


12. 實戰案例:徐霞客遊廬山日記水墨學習視頻

目標

  • • 時長 72 秒
  • • 6 個場景:題目 + 5 段原文(配現代漢語註釋)
  • • 水墨風格(#0C100B 深色背景、金色高亮、青綠註釋)
  • • CSS 多層山體剪影(clip-path: polygon)視差背景
  • • 古風字體(ZCOOL 小薇 + Noto Serif SC)

山體背景實現

三層山體疊加,產生遠近縱深感:

#mtn-far {
  position
: absolute;
  bottom
: 0; left: 0;
  width
: 1920px; height: 520px;
  background
: #131A11;
  clip-path
: polygon(
    0
 100%, 0 55%,
    180px
 42%, 360px 58%, 540px 28%, 680px 48%,
    820px
 18%, 960px 38%, 1100px 22%, 1240px 44%,
    1380px
 30%, 1520px 50%, 1680px 35%, 1800px 52%,
    1920px
 42%, 1920px 100%
  );
}
// 視差:三層山體以不同速度漂移
tl.to("#mtn-far",  { x: -40,  duration: 72, ease: "none" }, 0);
tl.to("#mtn-mid",  { x: -70,  duration: 72, ease: "none" }, 0);
tl.to("#mtn-near", { x: -100, duration: 72, ease: "none" }, 0);

古風人物插圖版(v2)

在文字版基礎上,v2 引入了從 Pollinations.ai 生成的古風水墨人物插圖:

  • • 6 個場景各一幅:站立、穿越石縫、遠眺、峯頂、探崖、執筆
  • • 人物圖片使用 mix-blend-mode: screen 與深色背景融合,黑色部分透明消融
  • • Pollinations.ai 請求參數中指定 pure black background white ink brush strokes,配合 screen 模式產生水墨融入效果
.char-figure {
  position
: absolute;
  right
: 70px; bottom: 0;
  width
: 520px;
  mix-blend-mode
: screen;   /* 黑色背景透明化 */
  filter
: contrast(1.12) brightness(0.92) sepia(0.08);
}
<img id="s2-char" class="char-figure"
  src
="https://image.pollinations.ai/prompt/ancient+Chinese+explorer+squeezing+through+narrow+rocky+gorge+...+white+ink+brush+painting+pure+black+background+guofeng?width=520&height=1040&seed=3002&nologo=true&model=flux"
  alt
="" crossorigin="anonymous" />

13. 總結

HyperFrames 代表了一種新的視頻製作思路:把視頻當代碼來寫。它特別適合技術背景的創作者,以及需要將設計系統(Design Token、品牌色、字體)精確落地到視頻內容的場景。

選擇 HyperFrames 的最佳時機:

  • • 你已經有前端開發經驗,不想學 After Effects
  • • 視頻內容以文字、數據、UI 界面展示為主
  • • 需要批量生成風格一致的視頻
  • • 視頻內容需要版本管理和團隊協作

不適合的場景:

  • • 需要大量真人拍攝素材剪輯
  • • 需要 3D 建模渲染
  • • 需要實時合成(HyperFrames 是離線渲染)

總之,HyperFrames 結合 Claude Code 這種方式製作 AppStore 宣傳視頻,效果還是不錯的,但是不適合製作長視頻,比如《徐霞客遊記》這樣的長視頻,人物、動畫還是不夠好。

不過相信未來隨着 AI 的發展,以後創作視頻的門檻會越來越低。

在這樣一個 AI 日新月異的時代裏,真正被重新定義的不僅是我們的工作方式,還有我們對生產力和創造力的理解。AI 不會取代人類對美的判斷、對品牌的洞察、對戰略的規劃,但它的到來卻讓每個人都有機會更加專注於這些最具價值的能力。

我們需要好好經營的是自己的品味以及決策力。有了這個,在 AI 時代,我們方能有所作為。


文章基於 HyperFrames 實戰經驗整理,案例代碼均經過真實渲染驗證。

工具鏈:HyperFrames + GSAP 3.14 + FFmpeg 7.1

參考:

  1. 1. github hyperframes : https://github.com/heygen-com/hyperframes

2026.04.18  22:58
📍 滬 · 趙巷

📌 聲明:本文由 AI 輔助完成