Communitygithub.com

d0-hyperframe

使用 HyperFrames 製作 D0 品牌影片。包含素材擷取、專案建置、場景佈局、GSAP 動畫、TG 元件規範與轉場規則。

d0-hyperframe 是什麼?

此技能提供了一套完整的 D0 品牌影片製作工作流程,基於 HyperFrames 框架以及 GSAP 動畫庫。它定義了從專案初始化、品牌資產(字體、Logo、品牌色)應用,到場景佈局與轉場的完整規範。核心設計理念是將影片場景分為「持久層」(靜態背景、Logo)與「內容層」(元件化區塊),所有動畫與轉場都只在內容層進行,以避免傳統幻燈片式的硬切效果,使影片過渡更流暢自然。技能文件內詳細說明了元件級交錯轉場(stagger)、力道曲線(easing)以及 GSAP 時間軸的撰寫規則,並提供了多種可選的轉場效果。此技能主要針對 D0 品牌的影片製作,特別適用於 Claude Code、Codex 等 AI 編碼代理,通過特定的觸發詞來調用,可快速生成符合品牌規範且具有專業動畫效果的宣傳影片。

相容平台~Claude Code✓Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/scof-real/d0-hyperframe-skill/tree/main/skills/d0-hyperframe

在你喜歡的 AI 中提問

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

說明文件

D0 HyperFrame 影片製作

使用 HyperFrames HTML + GSAP 製作 D0 品牌影片的完整工作流程。 以本文件為唯一權威——字型、色彩、佈局、動畫、轉場規則均在此定義。

字型規範以 d0-brand skill 為最終權威,本 skill 僅覆寫影片製作相關的補充規定。


觸發詞

  • "做一個 D0 影片" / "d0 hyperframe"
  • "用 hyperframes 做影片" / "/d0-hyperframe"

Step 0 — 初始化專案與素材

推薦:使用隨 Skill 提供的初始化腳本

安裝倉庫後,執行本 Skill 內的腳本。它會初始化 HyperFrames 專案,並複製 D0 Logo、D0 大頭貼和全部所需字型:

bash "${CODEX_HOME:-$HOME/.codex}/skills/d0-hyperframe/scripts/bootstrap_project.sh" .

如果專案已經初始化,只同步品牌素材:

bash "${CODEX_HOME:-$HOME/.codex}/skills/d0-hyperframe/scripts/bootstrap_project.sh" . --assets-only

腳本依賴 Node.js 18+ 與 npx。HyperFrames CLI 透過 npx hyperframes@latest 按需執行,不在 Skill 倉庫中複製第三方套件。

可選:從來源 HTML 覆蓋 D0_AVATAR 和 Logo

從來源 HTML 擷取 D0_AVATAR 和 Logo

來源海報 HTML 通常內嵌兩類 base64 圖片:

資產類型特徵用途
D0 LogoPNG,約 12–16 KB.brand img 或最短 PNG所有場景左上角
D0_AVATARJPEG,約 100 KB.av 或最長 JPEGTG 元件大頭貼
python3 - << 'EOF'
import re, base64, os

with open('SOURCE.html', 'r') as f:
    src = f.read()

os.makedirs('assets', exist_ok=True)

# Logo (最短 PNG)
pngs = re.findall(r'(data:image/png;base64,[A-Za-z0-9+/=]+)', src)
logo_b64 = min(pngs, key=len)
with open('assets/d0-logo.png', 'wb') as f:
    f.write(base64.b64decode(logo_b64.split(',')[1]))

# D0_AVATAR (最長 JPEG)
jpegs = re.findall(r'data:image/jpeg;base64,([A-Za-z0-9+/=]+)', src)
avatar = max(jpegs, key=len)
with open('assets/d0-avatar.jpg', 'wb') as f:
    f.write(base64.b64decode(avatar))

print("assets/ ready:", os.listdir('assets'))
EOF

字型(手動方式)

mkdir -p fonts
cp /path/to/d0-hyperframe/assets/fonts/*.woff2 fonts/
# 需要:InstrumentSerif-Regular.woff2, InstrumentSerif-Italic.woff2
#       OpenSans-400/600/700/800-normal.woff2

專案初始化(手動方式)

npx hyperframes@latest init . --non-interactive --example blank --skill=d0-hyperframe

Step 1 — 品牌 Token(CSS)

:root {
  --bg:    #06060d;
  --pu2:   #b3a8f7;
  --white: #f2f2f5;
  --t2:    #8d8d98;
  --t3:    #5a5a66;
  --green: #3ddc84;
  --red:   #f87171;
  --gold:  #f7a93a;
  --bdr:   #23232c;
  --bdr2:  #2e2e39;
  --grad:  linear-gradient(120deg, #5468F5 0%, #9B4FD6 34%, #C25C9A 62%, #DD8B57 100%);
}

@font-face { font-family:'Instrument Serif'; src:url('fonts/InstrumentSerif-Regular.woff2') format('woff2'); font-weight:400; font-style:normal; }
@font-face { font-family:'Instrument Serif'; src:url('fonts/InstrumentSerif-Italic.woff2')  format('woff2'); font-weight:400; font-style:italic; }
@font-face { font-family:'Open Sans'; src:url('fonts/OpenSans-400-normal.woff2') format('woff2'); font-weight:400; }
@font-face { font-family:'Open Sans'; src:url('fonts/OpenSans-600-normal.woff2') format('woff2'); font-weight:600; }
@font-face { font-family:'Open Sans'; src:url('fonts/OpenSans-700-normal.woff2') format('woff2'); font-weight:700; }
@font-face { font-family:'Open Sans'; src:url('fonts/OpenSans-800-normal.woff2') format('woff2'); font-weight:800; }

Step 2 — 舞台結構(持久 stage + 元件層)

核心模型:一層固定背景舞台,內容拆成元件。 背景 + 固定元素(logo/footer/頂部軌道)屬於持久層,全程不動;標題、數據、TG 面板、圖表等每個都是獨立的 .blk 元件,各自入場/退場。轉場發生在元件級,不是整螢幕級——這是擺脫"PPT 硬切"的根本。

HTML 骨架

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D0 · [影片標題]</title>
<style>/* tokens + scene CSS */</style>
</head>
<body>
<div id="main"
  data-composition-id="main"
  data-start="0"
  data-duration="[總秒數]"
  data-width="1920"
  data-height="1080">

  <!-- ── 持久層:全程不動,不寫任何 tl 動畫(見 Step 3) ── -->
  <div class="bg"></div>
  <div class="rail"></div>
  <div class="logo"></div>
  <div class="foot-tag">Agentic Trading for Every Market.</div>
  <div class="foot-url">getdonut.ai</div>

  <!-- ── 內容層:按 beat 分組,元件各自交錯進出(見 Step 6) ── -->
  <!-- beat 1 -->
  <div class="blk" id="b1-title">...</div>
  <div class="blk" id="b1-sub">...</div>
  <!-- beat 2 -->
  <div class="blk" id="b2-stat">...</div>
  <div class="blk" id="b2-tg">...</div>

</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<script>/* GSAP timeline */</script>
</body>
</html>

舞台 CSS(持久層 + 內容層)

/* 舞台容器 */
#main {
  position: absolute; inset: 0; overflow: hidden;
  font-family: 'Open Sans', sans-serif; color: var(--white);
}

/* 持久背景 — 全程固定,永不進入 tl 動畫 */
.bg {
  position: absolute; inset: 0; width: 1920px; height: 1080px; z-index: 0;
  background: var(--bg);
  background-image:
    radial-gradient(ellipse 46% 58% at 76% 50%, rgba(150,128,255,.16) 0%, transparent 60%),
    radial-gradient(ellipse 62% 50% at 8%   4%, rgba(110,100,255,.10) 0%, transparent 56%);
}

/* 頂部漸層軌道 — 固定,全片只需一條 */
.rail {
  position: absolute; top: 0; left: 0; right: 0; height: 5px; z-index: 10;
  background: var(--grad);
}

/* 內容元件 — 動畫的最小單元,預設隱藏,各自進出 */
.blk { position: absolute; opacity: 0; z-index: 2; }

舊模型每個整螢幕 .scene 自帶背景、整塊滑動 → PPT 感 + 卡點。 新模型只有一層固定背景,內容拆成 .blk 元件,轉場發生在元件級(見 Step 6)。


Step 3 — 固定元素規範(非協商)

以下三個元素在所有場景中保持一致,不寫入場或出場動畫:

元素位置字型大小說明
Donut Logo左上 top:40px left:72px200×76pxCSS background,不用 <img>
Agentic Trading for Every Market.左下 bottom:48px left:72px27pxInstrument Serif italic,--pu2
getdonut.ai右下 bottom:50px right:72px14pxOpen Sans,--t3
/* Logo — CSS background,不寫 opacity:0 */
.logo {
  position: absolute; top: 40px; left: 72px; z-index: 10;
  width: 200px; height: 76px;
  background: url('assets/d0-logo.png') left center / contain no-repeat;
}

/* Footer — 直接可見,無動畫 */
.foot-tag {
  position: absolute; bottom: 48px; left: 72px; z-index: 10;
  font-family: 'Instrument Serif', serif; font-style: italic;
  font-size: 27px; color: var(--pu2);
}

.foot-url {
  position: absolute; bottom: 50px; right: 72px; z-index: 10;
  font-size: 14px; font-weight: 700; letter-spacing: .06em; color: var(--t3); opacity: 0;
}

固定元素屬於持久層,從第 0 幀即可見,全程不寫任何 tl 動畫。 foot-tag 直接可見;foot-url 可保留一次性輕微淡入,但不強制。


Step 4 — 佈局原則

左右均衡,消除中心空白

  • 雙欄佈局優先:文案 / 數據在左,TG 元件 / 圖像在右
  • 右側有角色背景圖時:絕對定位鋪滿右側,疊加從左到右的漸層遮罩
.scene-char {
  position: absolute; top:0; right:0; bottom:0; width:62%;
  background: url('assets/bg-char.png') right center / cover no-repeat;
  z-index: 0;
}
.scene-char::after {
  content:''; position:absolute; inset:0;
  background: linear-gradient(to right,
    var(--bg) 0%, rgba(6,6,13,.82) 18%, rgba(6,6,13,.45) 45%, transparent 100%);
}
  • 左側文案區設 position: relative; z-index: 2 確保疊在背景圖之上

字型大小最小標準

以 D0 Thorp Engine 影片為基準,不得低於:

層級最小字型大小字型
主標題80pxInstrument Serif
場景副標題56pxInstrument Serif
Kick label / eyebrow18pxOpen Sans 700 uppercase
正文 / feature bullet22pxOpen Sans
數據錨點 (stat-val)48pxInstrument Serif
Footer tag27pxInstrument Serif italic
TG 元件內文字13px(可接受最小值)Open Sans

Step 5 — TG 元件規範

大頭貼:必須使用 D0_AVATAR

/* 大頭貼(header,40px) */
.av  { width:40px; height:40px; border-radius:50%; flex:none;
       background: url('assets/d0-avatar.jpg') center/cover no-repeat; }

/* 小頭貼(訊息行,28px) */
.mav { width:28px; height:28px; border-radius:50%; flex:none; margin-top:2px;
       background: url('assets/d0-avatar.jpg') center/cover no-repeat; }

不使用 <img> 標籤,避免 HyperFrames 偵測到重複 media 節點(lint warning)。 不使用漸層 fallback,必須是真實 D0_AVATAR 檔案。

TG Panel 結構

<div id="tg-panel">
  <div class="tg-chrome">
    <div class="dot r"></div><div class="dot y"></div><div class="dot g"></div>
    <div class="tg-url">t.me / D0_Bot</div>
  </div>
  <div class="tg-hdr">
    <div class="av"></div>
    <div>
      <div class="tg-nm">D0</div>
      <div class="tg-st">bot · online</div>
    </div>
  </div>
  <div class="tg-body">
    <div class="msg-user">使用者 prompt</div>
    <div class="msg-bot">
      <div class="mav"></div>
      <div class="bbubble">D0 回覆內容</div>
    </div>
  </div>
</div>

Step 6 — 轉場規則(非協商)

核心原則:背景不動,元件動。 "PPT 感"來自整塊 scene(含背景)一起滑走——觀眾失去穩定錨點; "卡點"來自 out 動畫和 in 動畫首尾相接——中間有一瞬全靜止。 兩者的解法都是同一句話:固定背景 + 元件交錯、進出重疊。

預設轉場:元件級交錯進出(element cross-stagger)

背景 + 固定元素(logo/footer/rail)全程不動。每次 beat 切換只讓內容元件動:

  • 舊 beat 元件依次退場(stagger,.in ease,細微位移 + 淡出)
  • 新 beat 元件依次入場(stagger,.out ease)
  • 兩者時間上重疊 ≈ 0.2–0.3s——舊的還沒退完,新的已經開始進。這是消除卡點的關鍵。
// beat 切換:舊組交錯退場,新組交錯入場,時間交疊(不是首尾相接)
function beat(outEls, inEls, t) {
  outEls.forEach((el, i) =>
    tl.to(el, { opacity:0, y:-30, duration:0.45, ease:'power2.in' }, t + i*0.06));
  inEls.forEach((el, i) =>
    tl.fromTo(el, { opacity:0, y:40 },
      { opacity:1, y:0, duration:0.6, ease:'expo.out' }, t + 0.2 + i*0.08));  // +0.2 = 重疊
}
// 用法:beat(['#b1-title','#b1-sub'], ['#b2-stat','#b2-tg'], 4.0);
  • 位移量小(20–40px);方向可統一(如都向上走)營造"翻頁氣流",但背景絕不參與。
  • 元件多時靠 stagger 讓畫面持續有動作,避免"同時入場 → 一起凍住"。

何時才用整螢幕轉場

僅在大分段(如品牌標題卡 → 數據段)偶爾使用,且只推內容層,不推背景——把該段元件包進一個 #grp 容器再推:

// Push-slide(僅推內容容器,背景 .bg 不動)
tl.to('#grpA',     { x:-1920, duration:0.55, ease:'power3.inOut' }, t);
tl.fromTo('#grpB', { x:1920, opacity:1 }, { x:0, duration:0.55, ease:'power3.inOut' }, t);

// Blur crossfade(情緒轉場,通常用於最後一次過渡)
tl.to('#grpC', { filter:'blur(20px)', opacity:0, duration:0.65, ease:'power2.in' }, t);
tl.fromTo('#grpD', { filter:'blur(20px)', opacity:0 },
  { filter:'blur(0px)', opacity:1, duration:0.65, ease:'power2.out' }, t);

❌ 禁止:整塊 scene(含背景)滑走、角落縮放、整螢幕 zoom、out/in 首尾相接無重疊。


Step 7 — GSAP 動畫規則

必須遵守

const tl = gsap.timeline({ paused: true });
// ...tweens...
window.__timelines['main'] = tl;
  • 用 tl.fromTo() 而非 tl.from()(確保 HyperFrames seek 確定性)
  • 重複動畫用 Math.floor(duration / cycle) - 1,禁止 repeat: -1
  • 同一元素多組動畫加 overwrite: 'auto'
  • 入場用 .out easing,出場用 .in easing

佈局優先,動畫其次

先寫元素的最終狀態(CSS 定位),再用 fromTo 描述入場路徑:

// ✅ 正確
tl.fromTo('#title', { opacity:0, y:40 }, { opacity:1, y:0, duration:0.8, ease:'expo.out' }, 0.3);

持久層不加動畫

.bg、.rail、.logo、.foot-tag、.foot-url 全程固定,動畫只發生在 .blk 元件上。背景一旦參與移動,立刻回到 PPT 感——轉場只動內容層(見 Step 6 beat())。


Step 8 — Lint & 預覽

npx hyperframes lint     # 必須 0 errors
npx hyperframes preview  # http://localhost:300x,熱重載
常見 warning處理
overlapping_gsap_tweens加 overwrite:'auto'
duplicate_media_discovery_risk改用 CSS background:url() 替代 <img>
composition_file_too_large單檔 <500 行時可忽略

依賴與資產來源

  • d0-brand Skill:字型、字型大小和品牌原則的最終權威,必須與本 Skill 一起安裝。
  • HyperFrames CLI:透過 npx hyperframes@latest 按需取得。
  • GSAP:範例固定使用 3.14.2 CDN 版本;如升級版本,先重新執行 lint 與 seek 驗證。
  • assets/fonts/:Instrument Serif 與 Open Sans;許可文件位於對應字型目錄。
  • assets/brand/:D0 Logo 與 D0 大頭貼,僅供獲得授權的 Donut 團隊成員用於 D0 品牌內容。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能