Motion · Chuyển cảnh
Thẻ lật lộ kết quả
Thẻ tính năng lật 180° quanh trục Y, mặt trước UI lóe một dải highlight di chuyển theo góc lật đúng lúc mép mỏng nhất, mặt sau lộ ra con số kết quả cỡ lớn, các thẻ lật so le lần lượt trên cả hàng.
Nguồn: video-shotcraft (Vincent Wei) ↗ · Apache-2.0 · Composition Remotion (React/TSX) — có video preview, không có player trong trình duyệt
Khi nào dùng
Tường thuật cặp "tính năng → kết quả": một hàng thẻ tính năng lần lượt lật lộ chỉ số/kết luận riêng; chuyển cảnh cấp phần tử.
Ý đồ
Nhóm "lật" hiện có trong thư viện đã có wall-reveal-moves B (cả bức tường lật kiểu sóng, dùng để vào cảnh) và split-flap (lật ký tự, dùng cho chữ). Thẻ này là lật ngữ nghĩa: hai mặt của một thẻ tạo thành một cặp nhân quả — mặt trước là giao diện tính năng, mặt sau là con số kết quả nó mang lại. Bản thân động tác lật chính là câu trả lời cho "vậy thì sao?" — ngữ pháp chuẩn của đoạn bento-grid kiểu Apple. Lật so le 10f trên cả hàng ba thẻ đọc thành "kết quả báo cáo liên tiếp".
Thời lượng & năng lượng
- Thời lượng: Một thẻ lật 26f, ba thẻ so le cách nhau 10f, toàn đoạn ~4.9s (kèm giữ hình).
- Năng lượng: Trung bình cao
Công thức cảnh quay (bản gốc tiếng Trung — timing, easing, bảng tham số, lỗi hay gặp)
意图
库内"翻"字辈已有 wall-reveal-moves B(整墙波浪翻面,讲入场)和 split-flap(字符翻牌,讲文字)。本卡是语义翻面:一张卡的正反两面 是一对因果——正面是功能界面,背面是它带来的数字结论。翻面动作本身 就是"所以呢?"的回答,Apple bento 段落的标准语法。逐张错峰 10f 扫过 一排,三张卡三个数字节奏读作"成果连报"。
动效核心
- perspective 1200px + transformStyle preserve-3d;双面各自
backfaceVisibility hidden,背面预转 rotateY(180°)
- 翻转 18f Easing.bezier(0.55,0,0.3,1) 冲到 192°(12° 过冲,原案 8°
不可感已加码),再 8f Easing.out(poly(5)) 回落 180°
- 侧棱高光:linear-gradient 位置随角度 35°→145° 从卡左外扫到右外,
强度 sin 包络在 90°(最薄瞬间)达峰 0.32 加深灰——白底用加深不用 提亮(判例);高光与角度联动才读作"光扫过转动的面"
- 错峰 delay 10f/卡;全部翻完真静止 ≥40f
参数表
| 参数 | 典型值 | 调节手感 | |------|--------|----------| | 翻转时长 | 18f + 8f 回弹 | <14f 看不到侧棱瞬间;>28f 读作慢慢转 | | 过冲 | 192°→180°(12°) | 无过冲落定读作生硬停表 | | 高光峰值 | 0.32 加深灰 @90° | 峰值错开 90° 读作贴图错误 | | 错峰 | 10f/卡,≤4 卡 | 同时翻读作整墙翻面(那是 wall-reveal B 的活)| | 背面内容 | 大号数字(90px 级)+ 一行小标签 | 背面塞完整 UI 读不完——翻面后只有一拍注意力 | | 收尾 | 末卡落定真静止 ≥40f | R1 |
已知坑
- demo 在灰阶/占位素材上调校通过——参数是调校起点非实战定稿,
首次实战须以真实素材回验
- 与 wall-reveal-moves B 式(网格波浪翻面)同技术根不同语义:那是
入场(背面灰卡→正面 UI),这是揭示(正面 UI→背面结论)——同片 两者都用时翻转方向要区分(入场 rotateX、揭示 rotateY)
- 正反两面必须语义成对(界面→它的成果);翻出无关内容,翻面就
只是花哨的换图
- 真实素材正面用截图时注意 backface 渲染开销,三卡以上分 Sequence
- 声音候选位:每卡翻停帧一声轻"啪"(sound-design §4.5),三连啪
节奏感翻倍
参考实现
demos/transition/card-flip-reveal/ (CardFlipReveal.tsx)
Mã nguồn tham chiếu (Remotion)
- demos/transition/card-flip-reveal/CardFlipReveal.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/transition/card-flip-reveal/CardFlipReveal.tsx
Component import fixture chung từ demos/_fixtures và helper từ assets/lib của repo; xem SKILL.md trong repo để biết quy trình render.
Mọi thứ trên trang này đều có bản máy đọc. Đưa agent link JSON, hoặc thêm MCP server gimgs rồi bảo nó tìm motion template.
- Tải JSON — trong đó có công thức cảnh quay (timing, easing, bảng tham số, lỗi hay gặp) và toàn bộ source TSX.
- Clone repo video-shotcraft; component import fixture chung từ demos/_fixtures và helper từ assets/lib.
- Đăng ký component thành <Composition> trong project Remotion rồi render bằng `npx remotion render`, hoặc dựng lại công thức bằng engine của bạn.
curl -s https://gimgs.net/motion/card-flip-reveal.jsongit clone https://github.com/Vincentwei1021/video-shotcraft
# component: demos/transition/card-flip-reveal/CardFlipReveal.tsx
npx remotion render <CompositionId> out.mp4claude mcp add --transport http gimgs https://gimgs.net/mcp
# then: search_motion_templates / get_motion_template("card-flip-reveal")Prompt
Use the video-shotcraft shot recipe "Thẻ lật lộ kết quả" (Remotion composition, Apache-2.0) published on gimgs.net. Recipe JSON (prompt = timing/easing/parameter table/pitfalls, files = TSX source): https://gimgs.net/motion/card-flip-reveal.json Raw TSX: https://gimgs.net/motion/card-flip-reveal/template.html Repository: https://github.com/Vincentwei1021/video-shotcraft (component: demos/transition/card-flip-reveal/CardFlipReveal.tsx; imports demos/_fixtures and assets/lib) Spec: 1920x1080, 30 fps, 4.89s 1. Read the JSON and follow its "prompt" section (when to use, intention, parameter table, known pitfalls). 2. Adapt it for: <describe what you want>. 3. Either clone the repo, register the component as a <Composition> in a Remotion project and run npx remotion render <CompositionId> out.mp4 — or re-implement the recipe in your own engine (HTML/WAAPI works: keep the same timing and easing).
// ===== demos/transition/card-flip-reveal/CardFlipReveal.tsx =====
// 功能卡 3D 翻面揭示(card-flip-reveal)——Apple bento 翻转段。
// 横排 3 张占位卡逐张错峰沿 Y 轴翻 180°(perspective 1200px,双面结构
// backface-visibility hidden),背面白卡中央大号结论数字。翻转先加速后
// 弹性落定(末端过冲 +12° 回 180°);翻到侧棱(90°)附近闪过一道随角度
// 移动的加深灰高光带(白底用加深而非提亮)。
// 关键帧(卡 i 起点 = 18 + i*10,i = 0/1/2):
// 0–18 hold → 卡0: 18–36 翻至 192° → 36–44 回弹落 180° →
// 卡1: 28–46–54,卡2: 38–56–64 → 64–145 三卡全静止(81f ≥ 40f)。
import React from 'react';
import { useCurrentFrame, interpolate, Easing } from 'remotion';
import { G, Card, TitleBlock } from '../../_fixtures/Fixtures';
const CW = 440;
const CH = 300;
const GAP = 60;
const X0 = (1920 - (CW * 3 + GAP * 2)) / 2; // 240
const Y = (1080 - CH) / 2; // 390
const FLIP_START = 18;
const STAGGER = 10;
const FLIP_DUR = 18;
const SETTLE = 8;
const OVERSHOOT = 12; // 末端过冲角度(原案 8°,肉眼存疑加码到 12°)
const RESULTS = ['4.9×', '−38%', '99.9%'];
// 卡 i 在帧 f 的翻转角:0 → 192(先加速后减速)→ 180(弹性落定),帧确定
const angleAt = (f: number, i: number): number => {
const s = FLIP_START + i * STAGGER;
if (f < s + FLIP_DUR) {
return interpolate(f, [s, s + FLIP_DUR], [0, 180 + OVERSHOOT], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.bezier(0.55, 0, 0.3, 1),
});
}
return interpolate(f, [s + FLIP_DUR, s + FLIP_DUR + SETTLE], [180 + OVERSHOOT, 180], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.out(Easing.poly(5)),
});
};
// 随角度移动的加深高光带:位置从卡左外扫到右外,强度在 90°(侧棱)达峰
const Sheen: React.FC<{ angle: number }> = ({ angle }) => {
const pos = interpolate(angle, [35, 145], [-25, 115], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
});
const op = Math.max(0, 1 - Math.abs(angle - 90) / 55);
if (op <= 0.004) return null;
return (
<div
style={{
position: 'absolute',
inset: 0,
borderRadius: 14,
pointerEvents: 'none',
opacity: op,
background: `linear-gradient(105deg, rgba(0,0,0,0) ${pos - 14}%, rgba(0,0,0,0.32) ${pos}%, rgba(0,0,0,0) ${pos + 14}%)`,
}}
/>
);
};
const FlipCard: React.FC<{ i: number; frame: number }> = ({ i, frame }) => {
const angle = angleAt(frame, i);
return (
<div
style={{
position: 'absolute',
left: X0 + i * (CW + GAP),
top: Y,
width: CW,
height: CH,
perspective: 1200,
}}
>
<div
style={{
width: '100%',
height: '100%',
position: 'relative',
transformStyle: 'preserve-3d',
transform: `rotateY(${angle}deg)`,
}}
>
{/* 正面:占位卡 */}
<div style={{ position: 'absolute', inset: 0, backfaceVisibility: 'hidden' }}>
<Card w={CW} h={CH} seed={i + 1} />
<Sheen angle={angle} />
</div>
{/* 背面:白卡 + 大号结论数字(预先转 180°,翻满后正读) */}
<div
style={{
position: 'absolute',
inset: 0,
backfaceVisibility: 'hidden',
transform: 'rotateY(180deg)',
background: G.card,
border: `2px solid ${G.border}`,
borderRadius: 14,
boxSizing: 'border-box',
boxShadow: '0 2px 8px rgba(0,0,0,0.06)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<span
style={{
fontFamily: 'Helvetica, Arial, sans-serif',
fontWeight: 800,
fontSize: 96,
color: G.ink,
letterSpacing: -2,
}}
>
{RESULTS[i]}
</span>
<Sheen angle={angle} />
</div>
</div>
</div>
);
};
export const CardFlipReveal: React.FC = () => {
const frame = useCurrentFrame();
return (
<div style={{ width: 1920, height: 1080, background: G.bg, position: 'relative', overflow: 'hidden' }}>
<div style={{ position: 'absolute', left: 120, top: 96 }}>
<TitleBlock text="CARD FLIP REVEAL" size={54} />
</div>
{[0, 1, 2].map((i) => (
<FlipCard key={i} i={i} frame={frame} />
))}
</div>
);
};
- Read the recipePrompt = when to use, intention, parameter table with typical values and how each one feels, known pitfalls. Treat values as calibrated starting points.
- Get the codetool: git
git clone https://github.com/Vincentwei1021/video-shotcraft && cd video-shotcraft && npm install - Register + rendertool: remotion
npx remotion render <CompositionId> out.mp4 # component: demos/transition/card-flip-reveal/CardFlipReveal.tsx - Or re-implementPort the timing/easing from the recipe to HTML + WAAPI (gimgs motion contract) or any engine; keep the same segment windows and easing.
| param | type | default | description |
|---|---|---|---|
| — | |||
Cùng danh mục

Chớp trắng: logo giản lược
Chữ hiệu gradient lỏng nhiều màu đứng yên chảy sáng, màn hình chớp trắng cháy sáng một nhịp, chữ hiệu phiên bản phẳng trên nền trắng mờ vào định hình — một lần chớp trắng hoàn tất bước giản lược chất liệu.

Chuyển cảnh quét hình học
Hai kiểu chuyển cảnh quét hình học — clock-wipe kim đồng hồ radar quét đổi trang và blinds-slice 12 dải dọc lật lệch nhịp thành sóng.

Chuyển cảnh giấu điểm cắt
Ba kiểu chuyển cảnh giấu điểm cắt — che khuất tiền cảnh cắt vô hình, đối đầu va chạm mở màn, và cháy sáng rò rỉ ánh sáng ấm; cắt cứng giấu trong 1-3 khung che khuất/va chạm/đỉnh sáng, khán giả không thấy kéo cắt.

Chuyển cảnh xuyên qua
Hai kiểu chuyển cảnh xuyên qua — trở về vị trí bằng phần tử chung và xuyên khoang chữ, máy quay khoan xuyên phần tử thực trong khung hình để hoàn tất đổi cảnh.