✨ Skill: Video fancy bằng HyperFrames
Skill này là lớp đạo diễn (art direction + nhịp + QC). Cú pháp HTML/GSAP đúng chuẩn thì dựa vào skill chính thức của HeyGen (xem Bước 0).
🎯 Mục tiêu: mọi frame đều đang chuyển động, mỗi cảnh một bố cục khác, chữ đọc được trên điện thoại, không có gì bị UI của TikTok/Reels che.
0. 🛠️ Setup + kho kiến thức
npx hyperframes doctor # Node, Chrome, FFmpeg
npx hyperframes init <ten-video> --example blank --resolution portrait --non-interactive
Skill chính thức của HeyGen đã cài sẵn (2026-10-11, ~/.claude/skills/): hyperframes (router), hyperframes-core (schema), hyperframes-animation (rule/blueprint/transition/text effect), hyperframes-keyframes (camera, punch-in), hyperframes-creative (palette, typography, frame preset), hyperframes-registry (tìm block), media-use (voice, SFX, grade, treatment), hyperframes-audio (mix), embedded-captions (35 kiểu caption)… Load đúng skill khi cần tra API; skill này lo phần đạo diễn.
Cập nhật: npx hyperframes skills update.
📚 Kho tham chiếu của skill này (đọc khi lập beat sheet):
| File | Dùng khi |
|---|---|
| reference/scene-picker.md | ⭐ luôn đọc: cảnh nào dùng hiệu ứng nào, chuyển cảnh, caption, style, 8 công thức từ launch film |
| reference/catalog-index.md | tra đủ 446 block/component (id, tác dụng, khung 16:9/9:16, 3D) |
| reference/prompting-digest.md | luật motion cao cấp, transition, vocabulary, color grade, VFX, data/map, code |
| reference/examples-digest.md | công thức chi tiết của 11 launch film + 8 template + 30 bài học |
| reference/official-skills-map.md | skill chính thức nào chứa gì, file reference nào cần mở |
- Trước khi dùng một block:
npx hyperframes add <block-id>(hoặcnpx hyperframes catalog <từ khoá>để tìm). Không có → chọn block khác cùng hàng trong scene-picker, đừng bịa. - Flag chưa chắc →
npx hyperframes <lệnh> --help.
1. 📥 Input — hỏi user nếu còn thiếu
| Cần có | Mặc định nếu user không nói |
|---|---|
| Chủ đề hoặc script | — (bắt buộc) |
| Độ dài | 35–60s |
| Footage / screen record / ảnh UI thật | Hỏi. Nếu không có → dùng capture <url> để chụp web, hoặc mockup UI trong block |
| Giọng đọc | TTS có word timestamps (ElevenLabs with-timestamps, HeyGen, hoặc npx hyperframes tts) |
| Style pack | Print Lab (Bước 3) |
| Nguồn / credit | Nếu là tin tức hay tính năng mới: credit nguồn ở cảnh đầu và cảnh cuối |
2. 🎬 Beat sheet — DỪNG LẠI để user duyệt
Chia script thành các beat 1.5–3s (hook ≤ 2s). Gán cho mỗi beat 1 loại:
HOOK · CLAIM · DEMO (UI/sản phẩm thật) · STAT (con số) · LIST · CONTRAST (trước/sau, đúng/sai) · ERROR · CTA
Xuất bảng như sau rồi chờ user OK mới bắt tay build:
| # | Thời gian | Loại | Voice (câu đọc) | Tiêu đề trên màn (≤ 4 từ) | Hình chính | Block | Chuyển cảnh vào |
|---|
Kiểm tra beat sheet trước khi gửi:
- Cứ 3–4 beat có ít nhất 1 beat
DEMOvới UI hoặc footage thật - Tiêu đề trên màn khác câu voice: tiêu đề là từ khoá, voice giải thích
- Beat cuối gợi nhắc lại hook (loop)
3. 🎨 Style pack mặc định: "Print Lab"
Giữ chất giấy in + halftone, nhưng có chiều sâu và chuyển động.
:root {
--paper: #E9E6DF; /* nền giấy */
--ink: #111111; /* chữ chính */
--accent: #FF4A1C; /* cam — nhấn mạnh */
--cool: #2B4BFF; /* xanh — khái niệm kỹ thuật */
--alert: #E0262B; /* đỏ — chỉ dùng cho LỖI/SAI */
}
- Font phải có đủ dấu tiếng Việt ⚠️: tiêu đề dùng
Be Vietnam Pro800/900, chữ mono dùngJetBrains Mono. Máy render là Chrome sạch, không có font: chỉ một nhóm font (Inter, Montserrat, Oswald, JetBrains Mono…) được tự nhúng. Be Vietnam Pro qua link Google Fonts chạy được khi render local, nhưng để chắc ăn (nhất là cloud render) hãy tải.woff2vàoassets/fonts/và khai báo@font-face. Font vẽ lên canvas (Three.js) phảidocument.fonts.load()trước. 🚫 Font bị coi là "dấu hiệu AI": Inter, Roboto, Open Sans, Poppins, Outfit, Playfair Display… Render thử chữ "Ữ Ặ Ỡ ẩ" trước. Dấu bị rời ra hoặc lệch là phải đổi font. - Lớp nền chạy suốt video: texture giấy +
grain-overlay+vignettenhẹ. - Halftone chỉ phủ lên footage đã tăng sáng và tương phản (curves, exposure +0.5). Footage tối mà phủ halftone sẽ thành mảng đen ❌
🔧 Muốn đổi style: thêm pack mới ở đây (Liquid Glass, Neon Terminal, Swiss Minimal…) với cùng cấu trúc token.
4. 🧩 Menu block theo loại beat (bản rút gọn, bản đầy đủ + 9:16/16:9 ở scene-picker.md)
Tên block lấy từ catalog. ★ = hiệu ứng "đắt", tối đa 2 lần mỗi video.
| Loại beat | Ưu tiên | Thay thế |
|---|---|---|
HOOK | ★parallax-device-dive, headline-slam | shutter-slam, char-slam-explode, ★glass-shard-title |
CLAIM | kinetic-type-swap, lt-mask-reveal | variable-axis-type, line-swap, blur-in |
DEMO | ai-chat-reveal, browser-device-stage + ui-focus-zoom | vfx-iphone-device, claude-exchange, cursor-zoom-follow |
STAT | number-wheel, data-chart | count-up, bar-chart-race, mk-usage-arc |
LIST | split-flap-board, marker-checklist-card | carousel-path-*, pan-stations |
CONTRAST | grade-split-reveal, split-tilt-cards | focus-rack, match-cut |
ERROR | caption-glitch-rgb, scan-band | rgb-glitch-text, camera-shake |
CTA | yt-comment-card + organic-light-leak-overlay | pull-back-reveal |
| Chủ đề AI/code | scramble-reveal, matrix-decode | code-typing, ★code-particle-assemble |
| Hoàn thiện card | light-sweep-pass, gloss-sweep | — |
5. 🎞️ Ngữ pháp chuyển cảnh
| Ý nghĩa của điểm cắt | Dùng |
|---|---|
| Cùng ý, chỉ đổi chi tiết | Hard cut theo beat, hoặc match-cut / type-match-cut |
| Sang ý mới hoặc chương mới | whip-pan, zoom-through-transition |
| Giữ chất giấy in | torn-paper-rip, halftone-dissolve, ink-bleed-reveal, paper-collage-reveal |
| Khoảnh khắc "wow" (★ tối đa 2) | gravitational-lens, swirl-vortex, sdf-iris, cinematic-zoom |
| Lỗi hoặc sai | glitch, chromatic-aberration-wipe — chỉ dùng ở đây |
🚫 Một kiểu chuyển cảnh không lặp quá 2 lần liền nhau. 🚫 Glitch không được dùng làm chuyển cảnh mặc định.
6. 🌀 Luật chuyển động (bắt buộc)
- ⏱️ Không có giây nào đứng im. Mỗi cảnh luôn có ≥ 1 lớp chuyển động:
push-inscale 1.00 → 1.05 suốt cảnh, parallax giữa các lớp, ticker, hoặc grain. - 📐 Cứ 3 cảnh phải có 1 cảnh phá bố cục: full-bleed, device 3D, zoom macro, hoặc chữ chiếm cả khung. Không được 18 cảnh cùng kiểu "tiêu đề trên, hình giữa, phụ đề dưới".
- 🥁 Phần tử quan trọng xuất hiện đúng lúc voice đọc tới từ đó, lấy mốc từ word timestamps (ElevenLabs
with-timestamps, hoặcnpx hyperframes transcribe --model small --language vi. ⚠️ Model mặc địnhsmall.ensẽ dịch tiếng Việt sang tiếng Anh). - 🎯 Ease: vào bằng
power3.out/expo.out, ra bằngpower2.in. Overshoot nhẹ (back.out(1.4)) cho sticker/nhãn. - 💡 Khi card vừa hiện xong → cho
light-sweep-passhoặcgloss-sweeplướt qua 1 lần. - 🎆 Đúng 1 "Spectacle beat" được đặt tên ở payoff (ví dụ: "cụm cuối slam 1.35× + rung 3 frame + chromatic split 0.2s"). Không đặt tên là nó bị bỏ qua.
- 🎥 3 lớp chiều sâu (~0.2× / 1× / 6×) + một vật thể mờ lớn ở tiền cảnh lướt qua. Ease window của camera dài hơn cảnh một chút để không bao giờ dừng hẳn.
7. 📱 Safe zone & chữ (khung 1080×1920)
y 0–250 ⛔ vùng UI trên (chỉ đặt được nền hoặc texture)
y 260–720 📰 vùng TIÊU ĐỀ
y 720–1180 🖼️ vùng HÌNH chính
y 1180–1400 💬 vùng PHỤ ĐỀ
y 1420–1920 ⛔ vùng caption/nút của app (chỉ đặt nền)
x > 900 ⛔ cột icon bên phải; lề trái ≥ 60
- Chữ nhỏ nhất ≥ 36px, tiêu đề 110–160px, phụ đề 48–56px.
- HUD trang trí (timecode, "LOOK 05/18"…) được phép nằm trong vùng ⛔ vì chỉ để trang trí, nhưng không được chứa thông tin cần đọc.
8. 💬 Phụ đề
- Dùng
caption-pill-karaoke: highlight từng từ đang đọc, màu--accent. Từ khoá kỹ thuật dùng--cool. - Mỗi lần hiện tối đa 2 dòng, ≤ 7 từ.
- Phụ đề là lời voice; tiêu đề là từ khoá. Không lặp nguyên văn của nhau.
9. 🏗️ Build
Mỗi beat là một sub-composition compositions/beat-XX.html, còn index.html để ghép lại.
Phải nhớ (theo HTML schema):
- Root:
data-composition-id,data-start="0",data-width="1080",data-height="1920",data-duration - Clip:
id,class="clip",data-start(cho phép dạngbeat-02 + 0.2),data-duration - GSAP: 1 timeline
{ paused: true }→ thêm tween → gánwindow.__timelines["<composition-id>"] - Video không có tiếng →
muted; video có tiếng →data-has-audio="true". Không gọiplay(),pause()haycurrentTime - 🎲 Random phải có seed (ví dụ mulberry32); không dùng
Date.now(), khôngrepeat: -1
10. ✅ QC loop — chưa pass thì không render bản cuối
npx hyperframes lint
npx hyperframes check # layout, motion, contrast
npx hyperframes snapshot --at 0.5,2,<giữa mỗi beat>,<cuối>
Mở từng snapshot ra xem và tick checklist:
- 2 giây đầu có hiệu ứng ★ và chữ hook đọc được ngay
- Không có chữ cần đọc nào nằm trong vùng ⛔
- Dấu tiếng Việt hiển thị đúng, không bị cắt ở dòng trên
- Không có hình nào gần như toàn đen sau khi phủ halftone
- Không có kiểu chuyển cảnh nào lặp > 2 lần liền nhau, ★ ≤ 2
- Mỗi 3 cảnh có 1 cảnh phá bố cục
- Phụ đề khớp voice (lệch ≤ 0.1s)
Pass hết thì render:
npx hyperframes render --output out/<ten-video>.mp4
Sau đó: âm lượng khoảng −14 LUFS, xem lại toàn bộ 1 lần ở tốc độ 1x.
10b. 🧯 Bẫy đã gặp (test 1, 2026-10-11, video Opus 5.5)
- 🧩 Block trong catalog phần lớn là demo mẫu, có cái cố định 1920×1080 (
whip-pan). Dùng chúng làm mẫu kỹ thuật rồi tự viết lại trong composition 9:16, đừng mount nguyên block. - ⛓️ Không nối
.to().to()trên timeline gốc. Tween nối không ghi vị trí sẽ bị đẩy xuống cuối timeline, làm flash không tắt và rung không chạy. Luôn ghi vị trí tuyệt đối cho từng tween. - 🔄 Phần tử nào GSAP tween
scale/rotationthì không được đểtransformtrong CSS (lint báo lỗi). Đưa giá trị ban đầu vàofromTo. - 🔠 Tiêu đề tiếng Việt 900 weight: khoảng ≤ 11 ký tự/dòng ở 116px trong khung 820px. Dài hơn thì giảm cỡ chữ theo từng cảnh, đừng để rớt dòng thứ 3 đè lên card.
- ⭕
iris/clip-path: scene không có nền riêng nên cảnh cũ vẫn lộ ra ngoài vòng tròn → cho cảnh cũ mờ hẳn trong 0.3s. - 🎙️ Giọng TTS gốc tiếng Anh (vd ElevenLabs "Adam") đọc tiếng Việt hay lệch dấu: "bảo→báo", "mẹo→mèo", "Người test→Nội thét". Phải chạy ASR (faster-whisper
small,language="vi"), sai chỗ nào thì đổi từ chỗ đó. - 🧊 Block 3D (
orbit-card, Three.js): copyassets/*.jsrồi sửa scene. Đổi sang 9:16 bằng cách giữ góc dọc của rig làm góc ngang. Dùng canvasalphađể nền CSS lộ ra, chữ vẽ lên canvas phảidocument.fonts.load()font tiếng Việt trước. Card chỉ xuất hiện ~0.9–8.2s → co giãn thời gian video sang thời gian block. - ✂️ Mask cắt mất dấu tiếng Việt: chữ trong khung
overflow:hiddenvớiline-height ≤ 1sẽ bị cụt dấu (Ữ, Ặ, Ỡ). Thêmpadding-block: 0.2em; margin-block: -0.2em.data-layout-allow-overflowsẽ giấu lỗi này khỏicheck→ luôn xem snapshot. - 🔤 Font kèm theo block: Archivo (orbit-card) có đủ 67 chữ cái tiếng Việt, Geist (code-slice-hero, glass-shard-title, wireframe-portal-title, frost) chỉ có 23/67 → phải thay font khi dùng các block đó.
- 🔇
<audio>không cóidsẽ render ra im lặng. - 🚪 Không viết animation "exit" cho từng cảnh (trừ cảnh cuối): chuyển cảnh chính là exit. Code transition mẫu tính quãng đường theo ±1920/±1080 → đo lại cho khung dọc.
- 🧱 Hai tween transform cùng lúc trên một phần tử (ví dụ
yvào + Ken Burnsscale) có thể làm nó biến mất → tách wrapper. Khai báo style trong<template>khi viết sub-composition. Không dùng CSS transition. - 🌐
canopy-part-title,glass-shard-title,wireframe-portal-titletải script từ CDN lúc render → cần mạng. - 📏
render --resolution portraitchỉ phóng to, không bố cục lại → phảiinit --resolution portraittừ đầu. Skill chính thức không có danger zone của TikTok/Reels (chỉ có title-safe 80%) → vẫn giữ luật 250/500/180px của mình. - ⚠️
checkluôn báotext_occludeddo vignette/grain → bỏ qua được. Nhưng contrast fail thì phải xem snapshot, vì thường là lỗi thật (lần này là flash bị kẹt).
11. 📤 Báo cáo cho user
- Đường dẫn file MP4 + 3–4 snapshot tiêu biểu
- Bảng beat → block → chuyển cảnh đã dùng
- Những block bị thay thế (do không có trong catalog) và lý do
- Các điểm QC còn tạm chấp nhận (nếu có)