Motion · UI xuất hiện
Danh sách hiện dần kèm trôi dạt
Menu dọc 6 mục lần lượt vào đúng vị trí cách nhau 0.09, vượt ngưỡng nhẹ khi ổn định, trong khi cả khối chứa danh sách trôi lên tuyến tính suốt toàn đoạn — hai lớp chuyển động không liên quan nhau.
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
Nhập cảnh cho điều hướng/thanh bên/bảng cài đặt; bất kỳ đoạn UI nào cần cảm giác "giao diện tự mọc ra", cũng phù hợp làm nền năng lượng thấp khi có lời thoại.
Ý đồ
Danh sách mờ hiện từng mục là một trong những kiểu chuyển động dễ làm chết nhất — mỗi mục xong là đứng yên, khung hình hoàn toàn tĩnh giữa các mục. Giải pháp của thẻ này là thêm một lớp trôi dạt chậm cho khối chứa, không liên quan đến việc từng mục vào cảnh — cục bộ đang "tìm vị trí", tổng thể đang "thở". Khán giả đọc rõ từng mục, đồng thời không có khung hình nào từ đầu đến cuối bị ghim chết cứng.
Thời lượng & năng lượng
- Thời lượng: Khoảng 3.6s (108f@30fps)
- Năng lượng: Thấp (nhịp ổn định, không có đỉnh; duy trì sức sống nhờ trôi dạt)
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)
意图
列表逐项淡入是最容易做得死板的一类动效:每项动完就停,画面在两项之间是完全静止的。 这张卡的解法是给容器加一层与逐项入场无关的慢速漂移——局部在"找位",整体在"呼吸"。 观众读得清每一项,同时画面从头到尾没有一帧是钉死的。
动效核心
- 两层运动完全解耦:容器
list.style.transform = translateY(lerp(t, 16, -16))只吃全局 t,
是贯穿全片的线性漂移;每项自己吃 seg(...) 的局部窗口,互不参与对方的计算
- 逐项入场:
seg(t, 0.06+i*0.09, +0.24, E.outBack),stagger 0.09(约 10f)比常规
UI stagger 慢一档——这是"读得完"的间隔,不是"快速铺开"的间隔
- 找位动作是 scale 主导:
scale(0.78 + p*0.22)配translateY(14→0),位移只有 14px,
观众感知到的是"从小长到实",而不是"从下面飞上来"
E.outBack的过冲让 scale 短暂越过 1(约 1.002 量级的软过冲)——量很小,作用是把
落位的那一帧从"停"变成"扣住"
- 透明度
min(1, p*2.2):行程走到 45% 就已全实,避免半透明的列表项和背景卡片色
(#161a26 + 1px #262c40 描边)糊在一起
参数表
| 参数 | 典型值 | 调节手感 | |------|--------|----------| | 项数 | 6(Dashboard…Sign out) | 末项窗口 0.51→0.75,尾部留 0.25 静置给观众收尾;>8 项必须压 stagger,否则末项吃到收尾 | | stagger | 0.09/项(≈10f) | 10f 是"逐项读得完";压到 0.04 变成一次铺开(另一种手法),拉到 0.15 以上节拍会散 | | 单项行程 | 窗 0.24(≈26f) | 行程比 stagger 长 2.6 倍 → 相邻三项同时在动,队列是连绵的;两者相等会变成一项一项硬接 | | 起始 scale | 0.78 | 0.78 是"已经能认出是个条目"的尺度;<0.5 读作从零弹出,和 pop 类手法混淆 | | 起始位移 | 14px | 位移必须远小于行高(9px gap + 约 33px 项高),否则项与项之间穿插 | | 过冲 | E.outBack | 这里的过冲要小到几乎读不出来;换 spring 或加大 back 系数,6 项连续抖会显得廉价 | | 容器漂移 | lerp(t, 16, -16),全程线性 | 总位移 32px 摊在 3.6s 上(约 0.3px/f)——刚好在"感觉画面活着"和"看得出在动"之间;>60px 会与逐项位移量级相当,两层运动混为一件事 | | 透明度斜率 | min(1, p*2.2) | 2.2 决定多早变实;降到 1 会看到半透明项叠在背景上,深色主题下尤其脏 |
已知坑
- 容器漂移是线性且贯穿全程,t=1 时停在 -16px 而不是 0——这个动效末帧不回位。
要循环播放或与后一镜对齐位置,得把漂移换成 seg(t, 0, 1, ...) 之外的收束曲线, 或在末段补一个反向缓收
- 项数变化必须重算 stagger:末项起点
0.06+(n-1)*0.09,10 项时起点已到 0.87,行程会
被 t=1 截断,最后一项永远进不来
- 文案没设
white-space:nowrap,容器宽度写死 240px——中文或更长的英文标签会换行,
行高一变整列节奏全乱
- 漂移方向(向上)与逐项位移方向(14px→0,也是向上)同向。这是有意的(同向叠加更
顺),但两者量级必须保持 2 倍以上差距,否则读作"一起往上飘"而非两层
- 图标是 hue 色环渐变方块的占位(6 个色相区分条目),落地要换成真实图标;条目底色
#161a26 属深色主题,浅色界面下描边和阴影都要重调
参考实现
demos/ui-entrance/list-reveal/ (ListReveal.tsx)
Mã nguồn tham chiếu (Remotion)
- demos/ui-entrance/list-reveal/ListReveal.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/ui-entrance/list-reveal/ListReveal.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/list-reveal.jsongit clone https://github.com/Vincentwei1021/video-shotcraft
# component: demos/ui-entrance/list-reveal/ListReveal.tsx
npx remotion render <CompositionId> out.mp4claude mcp add --transport http gimgs https://gimgs.net/mcp
# then: search_motion_templates / get_motion_template("list-reveal")Prompt
Use the video-shotcraft shot recipe "Danh sách hiện dần kèm trôi dạt" (Remotion composition, Apache-2.0) published on gimgs.net. Recipe JSON (prompt = timing/easing/parameter table/pitfalls, files = TSX source): https://gimgs.net/motion/list-reveal.json Raw TSX: https://gimgs.net/motion/list-reveal/template.html Repository: https://github.com/Vincentwei1021/video-shotcraft (component: demos/ui-entrance/list-reveal/ListReveal.tsx; imports demos/_fixtures and assets/lib) Spec: 1920x1080, 30 fps, 4.1s 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/ui-entrance/list-reveal/ListReveal.tsx =====
// list-reveal — List Reveal 菜单逐项找位(motion-lab 定稿转原生 Remotion)
// 垂直菜单列表项依次 scale 找位入场(outBack 轻微过冲),同时整个列表容器
// 全程线性缓慢上移——"整体漂移"与"逐项入场"两层运动分离叠加。
// 设计坐标 480×270(DesignStage 等比放大),参数表数值以此坐标系标定。
import React from 'react';
import { DesignStage, E, lerp, seg, useT } from '../../_fixtures/Motion';
export const LIST_REVEAL_DURATION = 108; // 3600ms @30fps
const LABELS = ['Dashboard', 'Projects', 'Analytics', 'Messages', 'Settings', 'Sign out'];
const HUES = [225, 250, 275, 300, 210, 340];
export const ListReveal: React.FC = () => {
const t = useT();
return (
<DesignStage bg="#0a0b10">
{/* 居中容器:flex 撑起列表垂直水平居中 */}
<div
style={{
position: 'absolute',
inset: 0,
background: '#0a0b10',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
{/* 整体漂移层:全程线性缓慢上移 */}
<div
style={{
position: 'relative',
width: 240,
display: 'flex',
flexDirection: 'column',
gap: 9,
// -0.5px:原样片浏览器 flex 居中落在整数位(列表高 255 → 顶部 7.0),
// Remotion 渲染落在 7.5,补回半个设计像素对齐原片
transform: `translateY(${lerp(t, 16, -16) - 0.5}px)`,
}}
>
{LABELS.map((s, i) => {
// 逐项入场:outBack 轻微过冲找位
const p = seg(t, 0.06 + i * 0.09, 0.06 + i * 0.09 + 0.24, E.outBack);
return (
<div
key={i}
style={{
display: 'flex',
alignItems: 'center',
gap: 11,
padding: '9px 13px',
borderRadius: 10,
background: '#161a26',
border: '1px solid #262c40',
opacity: Math.min(1, p * 2.2),
transform: `scale(${0.78 + Math.max(0, p) * 0.22}) translateY(${lerp(Math.max(0, p), 14, 0)}px)`,
}}
>
<div
style={{
width: 15,
height: 15,
borderRadius: 5,
flex: 'none',
background: `linear-gradient(140deg,hsl(${HUES[i]},75%,64%),hsl(${HUES[i]},70%,46%))`,
}}
/>
<div
style={{
fontFamily: '-apple-system,sans-serif',
fontWeight: 500,
fontSize: 13,
lineHeight: 1,
color: '#c6cde2',
}}
>
{s}
</div>
</div>
);
})}
</div>
</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/ui-entrance/list-reveal/ListReveal.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

Hiện hình cả bức tường: ba kiểu
Ba kiểu vào hình hàng loạt cả bức tường — bento thắp sáng từng ô, lưới lật sóng, và bản vẽ blueprint hiện nét; tất cả hiện hình tại chỗ không dịch chuyển, bổ trợ cho deck-deal-flyin kiểu bay vào dịch chuyển.

Cột nhập theo bậc thang giá trị
16 cột vào hình với delay là bậc thang thời gian, đồng thời chiều cao/sắc màu/dịch chuyển/độ mờ mỗi thuộc tính tự trải thành bậc thang giá trị từ đầu đến cuối; nhịp hai đổi gốc lệch nhịp về tâm, biên độ xung lấy tâm làm đỉnh trải lại.

Biến hình SVG lặp vòng
Một viền khép kín 140 điểm biến hình mượt sang viền khác rồi biến lại, hai hình trước hết được lấy mẫu lại cùng số điểm trong tọa độ cực, nội suy bán kính từng điểm + inOutCubic, giữa chừng chèn hơi thở scale nhẹ, tự xoay chậm và sắc màu trôi 185°→305°.

Hiện hình từ khung xương
Hiện hình ba tầng từ phác thảo đến khung xương đến nội dung — nét vẽ tay được thay bằng thanh xám khung xương rồi rõ nét thành UI thật.