Motion · Chuyển cảnh
Ghép lại bố cục mosaic
12 ô mosaic biến hình liên tục giữa ba kiểu bố cục — lưới đều, feature mosaic, và thác chéo — vị trí và kích thước mỗi ô đều nội suy riêng, lệch nhịp nhẹ từng ô, giữa các đoạn có giữ hình.
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
Chuyển cảnh trưng bày kiểu "cùng một lô nội dung, nhiều cách nhìn khác nhau": thể hiện năng lực bố cục cho sản phẩm portfolio/thư viện mẫu/album ảnh.
Ý đồ
Cho khán giả thấy "chính bố cục đang suy nghĩ": cùng 12 nội dung, từ trạng thái lưu trữ ngay ngắn (lưới), biến thành trạng thái tuyển chọn có chính có phụ (feature mosaic), rồi thành trạng thái động có cá tính (thác chéo). Ba kiểu bố cục là ba giọng điệu kể chuyện, quá trình biến hình chính là năng lực sản phẩm.
Thời lượng & năng lượng
- Thời lượng: Khoảng 6.0s (180f@30fps; xuất hiện 0–0.6s · A→B 1.6–2.5s · giữ hình · B→C 3.7–4.8s)
- Năng lượng: Trung bình (sắp xếp lại liên tục, mượt, không đỉnh điểm, khí chất điềm đạm)
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)
意图
让观众看见"布局本身在思考":同样 12 张内容,从整齐档案态(网格)变成有主次的策展态(feature mosaic),再变成有态度的动态态(对角瀑布)。三段排版是三种叙事语气,变形过程即产品能力。
动效核心
- 三套布局硬编码为坐标表:A=4×3 规则网格;B=6×4 单元格 mosaic(首片占 3×2 大位);C=对角瀑布
x=1+i*6.4, y=-7+i*7.6, rot=-15+i*3°递增旋转 - 每片对
x/y/w/h/rot五个通道独立插值(acc按段查表 + smoothstep),不走 transform 整体缩放——宽高真实变化,圆角阴影不变形 - 段窗口 A→B t=0.26–0.42、B→C t=0.62–0.80,之间留 ≥0.2 的 hold 读版面
- 逐片微 stagger
i*0.007(约每片错 2 帧):重排像波浪扫过而非整版闪变 - 开场逐片浮现:
i*0.012错峰 + scale 0.82→1 + opacity(outCubic),首片始终 zIndex 抬高(它是 mosaic 段的主图)
参数表
| 参数 | 典型值 | 调节手感 | |------|--------|----------| | 段窗口 | 每段变形 0.16–0.18,hold ≥0.2 | hold 是读版面的呼吸位,压缩到 <0.1 三段糊成一段 | | 微 stagger | 0.007/片(≈2 帧) | 0 = 整版机械闪变;>0.02 波浪太明显抢过版面本身 | | 瀑布参数 | 间距 6.4/7.6%,rot −15°+3°/片 | 旋转递增是"串"的灵魂;等角会退化成斜排网格 | | mosaic 大位 | 首片 3×2 单元格 | 换 slots 表可重排主次;保证有一块 ≥2×2 的锚点位 | | 浮现节奏 | 0.012/片 + 0.14 时长 | 12 片合计约 0.27 进完;作转场用时可砍掉浮现直接从 A 态起 | | 瓦片内容 | 渐变底 + 圆点 + 双信息条(占位) | 换真实截图/图片时保留 overflow:hidden 圆角容器,宽高插值不裁坏内容 |
已知坑
- 五通道独立插值意味着不能换成
transform: scale——宽高动画会引发子元素重排,占位内容用了百分比定位可自适应,换成真实图片要用object-fit: cover - C 段瓦片有意越出画框(y 从 −7% 到 91%),画框裁切是构图的一部分,别加 padding "修复"
- 三套坐标表都以 92% 内容区 + 4% 边距为基准,改画幅比例需整表重算
- 段窗口与 stagger 叠加后末片 B→C 到 0.887 才结束,再加段落需压缩前段而不是顺延(保证 t=1 前全部落定)
参考实现
demos/transition/mosaic-reframe/ (MosaicReframe.tsx)
Mã nguồn tham chiếu (Remotion)
- demos/transition/mosaic-reframe/MosaicReframe.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/transition/mosaic-reframe/MosaicReframe.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/mosaic-reframe.jsongit clone https://github.com/Vincentwei1021/video-shotcraft
# component: demos/transition/mosaic-reframe/MosaicReframe.tsx
npx remotion render <CompositionId> out.mp4claude mcp add --transport http gimgs https://gimgs.net/mcp
# then: search_motion_templates / get_motion_template("mosaic-reframe")Prompt
Use the video-shotcraft shot recipe "Ghép lại bố cục mosaic" (Remotion composition, Apache-2.0) published on gimgs.net. Recipe JSON (prompt = timing/easing/parameter table/pitfalls, files = TSX source): https://gimgs.net/motion/mosaic-reframe.json Raw TSX: https://gimgs.net/motion/mosaic-reframe/template.html Repository: https://github.com/Vincentwei1021/video-shotcraft (component: demos/transition/mosaic-reframe/MosaicReframe.tsx; imports demos/_fixtures and assets/lib) Spec: 1920x1080, 30 fps, 6.5s 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/mosaic-reframe/MosaicReframe.tsx =====
// mosaic-reframe — Mosaic Reframe 三段布局重排(motion-lab 定稿转原生 Remotion)
// 12 张图片瓦片在三种排版间连续变形:4x3 规则网格 → 带一块 2x2 大图的 feature
// mosaic → 对角线瀑布串(每片 -15°+i*3° 递增旋转)。位置与宽高各自独立插值,
// 每片按 index 微 stagger,smoothstep 缓动,段间留 hold。
// 设计坐标 480×270(DesignStage 等比放大),参数表数值以此坐标系标定。
import React from 'react';
import { DesignStage, E, lerp, rand, seg, useT } from '../../_fixtures/Motion';
export const MOSAIC_REFRAME_DURATION = 180; // 6000ms @30fps
// smoothstep:段内缓动(原配方即用它替代 E 表)
const smooth = (x: number) => x * x * (3 - 2 * x);
type Box = { x: number; y: number; w: number; h: number; rot: number };
const KEYS = ['x', 'y', 'w', 'h', 'rot'] as const;
// 累加式关键帧插值:各段进度独立过 ease 后按差值叠加,天然支持窗间 hold
const acc = (t: number, base: Box, kfs: { at: [number, number]; to: Box }[], ease: (x: number) => number): Box => {
const out: Box = { ...base };
let prev = base;
for (const kf of kfs) {
const u = seg(t, kf.at[0], kf.at[1], ease);
for (const k of KEYS) out[k] += u * (kf.to[k] - prev[k]);
prev = kf.to;
}
return out;
};
// ---- layout A: 4x3 规则网格 ----
const gw = (92 - 3 * 2) / 4, gh = (92 - 2 * 2) / 3;
const A: Box[] = Array.from({ length: 12 }, (_, i) => {
const c = i % 4, r = (i / 4) | 0;
return { x: 4 + c * (gw + 2), y: 4 + r * (gh + 2), w: gw, h: gh, rot: 0 };
});
// ---- layout B: feature mosaic(6x4 单元格,t0 占 3x2)----
const uw = (92 - 5 * 1.2) / 6, uh = (92 - 3 * 1.2) / 4;
const SLOTS: [number, number, number, number][] = [
[0, 0, 3, 2], [3, 0, 1, 1], [4, 0, 1, 1], [5, 0, 1, 1], [3, 1, 2, 1], [5, 1, 1, 1],
[0, 2, 1, 1], [1, 2, 2, 1], [3, 2, 1, 2], [4, 2, 2, 1], [0, 3, 3, 1], [4, 3, 2, 1],
];
const B: Box[] = SLOTS.map(([c, r, cw, rh]) => ({
x: 4 + c * (uw + 1.2), y: 4 + r * (uh + 1.2),
w: cw * uw + (cw - 1) * 1.2, h: rh * uh + (rh - 1) * 1.2, rot: 0,
}));
// ---- layout C: 对角线瀑布串 ----
const C: Box[] = Array.from({ length: 12 }, (_, i) => ({
x: 1 + i * 6.4, y: -7 + i * 7.6, w: 23, h: 27, rot: -15 + i * 3,
}));
export const MosaicReframe: React.FC = () => {
const t = useT();
return (
<DesignStage bg="#0a0b10" raster="zoom">
{A.map((base, i) => {
const hue = 198 + i * 13;
const st = i * 0.007; // ≈ index*2 帧微 stagger
const v = acc(t, base, [
{ at: [0.26 + st, 0.42 + st], to: B[i] }, // A → B
{ at: [0.62 + st, 0.80 + st], to: C[i] }, // hold 后 B → C
], smooth);
const pop = seg(t, i * 0.012, i * 0.012 + 0.14, E.outCubic); // 开场逐片浮现
return (
<div
key={i}
style={{
position: 'absolute',
borderRadius: 7,
overflow: 'hidden',
background: `linear-gradient(${140 + i * 9}deg,hsl(${hue},58%,42%),hsl(${hue + 26},64%,20%))`,
boxShadow: `0 8px 22px rgba(0,0,0,.45),inset 0 0 0 1px hsla(${hue},70%,72%,.22)`,
left: `${v.x}%`,
top: `${v.y}%`,
width: `${v.w}%`,
height: `${v.h}%`,
transform: `rotate(${v.rot}deg) scale(${lerp(pop, 0.82, 1)})`,
opacity: pop,
zIndex: 10 + (i === 0 ? 5 : 0),
}}
>
{/* 占位"图片"内容:一枚圆点 + 两条信息条 */}
<div
style={{
position: 'absolute',
left: 9,
top: 9,
width: 9,
height: 9,
borderRadius: '50%',
background: `hsla(${hue + 40},90%,78%,.95)`,
boxShadow: `0 0 10px hsla(${hue + 40},90%,70%,.7)`,
}}
/>
<div
style={{
position: 'absolute',
left: 9,
bottom: 16,
height: 5,
width: `${34 + rand(i) * 30}%`,
borderRadius: 3,
background: 'hsla(0,0%,100%,.6)',
}}
/>
<div
style={{
position: 'absolute',
left: 9,
bottom: 8,
height: 4,
width: `${20 + rand(i + 7) * 24}%`,
borderRadius: 2,
background: 'hsla(0,0%,100%,.28)',
}}
/>
</div>
);
})}
</DesignStage>
);
};
- 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/mosaic-reframe/MosaicReframe.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.