- AI 技能
- 媒体生成
- 视频
【免费下载链接】video-shotcraft
AI video skill for Claude Code & Codex — cinematic product videos with Remotion: 152 shot recipe cards, 209 motion previews, a production-ready template
本文以 video-shotcraft 镜头卡库中的radial-ripple-phone-chips(同心波纹手机)卡片为核心,完整拆解其「错相呼吸同心圆 + 自动滚屏手机 mockup + 两侧 spring pop chip」的三层动效配方,对照卡片配套的原生 Remotion 参考实现讲解每个参数的物理含义与手感边界,并给出把该镜头卡落地到你自己的 Remotion 项目中的完整操作路径。读完你可以直接复制这套低能量「产品定格镜头」标准配法,为移动端产品的"这就是它"镜头、功能点分列两侧的介绍段或片头片尾的产品全景提供一版经过全帧验收的动画骨架。
卡片速览:一张"安静但活着"的低能量产品定格镜头
镜头卡的前置元信息(Frontmatter)定义了它的身份与适用边界:
| 字段 | 内容 |
|---|---|
| 卡名 | radial-ripple-phone-chips |
| 一句话 | 浅灰底四层同心圆错相呼吸如水波,中央手机 mockup 屏内 feed 自动缓滚,两侧白色 chip 先后 spring pop 入场并悬浮 |
| 适用 | 移动端产品的"这就是它"定格镜头;功能点分列两侧的介绍段;片头/片尾的产品全景 |
| 时长 | 约 5.6s(168f @ 30fps) |
| 能量 | 低(安静、有呼吸感,靠同心圆的持续起伏撑住不冷场) |
卡片源文件位于 gallery/source/radial-ripple-phone-chips.md,与 references/shots/effects/radial-ripple-phone-chips.md 内容一致;gallery/api/library.json中该卡同样以category: effects收录。"能量:低"是这张卡最关键的定位——它不靠冲击帧、不靠高速位移制造存在感,而是靠持续的细微运动让画面"活着",因此在全片节奏里通常承担"定格展示产品本身"的角色,而不是情绪峰值。
设计意图:把手机"放稳"并让它"活着"的三明治结构
卡片原文档的"意图"一节给出了这张镜头的构图哲学:
用最少的动作把手机放在画面正中并让它"活着":同心圆负责氛围呼吸,屏内自动滚屏负责证明"里面有内容在跑",两侧 chip 负责点出功能名。三层动作各自极慢,叠起来才不会显得静止——这是产品定格镜头的标准配法。
也就是说,画面被拆成三个互不干扰的动效层,每层都很慢,但三层的"慢"叠加后画面没有任何一帧是死的:
- 氛围层——背景同心圆持续起伏,负责"呼吸感";
- 证据层——手机屏内的 feed 匀速自动滚动,负责证明"这是真实在运行的产品";
- 语义层——两侧白色 chip 先后弹出并悬浮,负责逐个点出功能名。
三层的语义分工清晰:没有滚动的 feed,观众会觉得手机只是个空壳贴图;没有呼吸的同心圆,长 hold 段会冷场;没有 chip 的错峰入场,画面就没有"信息递进"的节奏。这套"三层各司其职、各自极慢"的结构,是产品发布片里定格展示镜头的通用骨架,换掉手机和 chip 文案即可复用到任何移动端产品。
动效核心拆解:三个关键参数的物理含义
卡片文档"动效核心"一节给出了三层动作的配方,这里逐条展开并结合源码说明其底层实现。
1. 四层同心圆:错相才是"水波"
- 4 层同心圆,直径 560/440/320/210px,颜色由深到浅
#d7dbe1 → #e0e4e9 → #e8ebef → #eef0f3; - 每层
scale 1 ± 0.06,全片走1.5 个正弦周期; - 相邻层相位差1.7 rad。
对应的源码实现位于 demos/effects/radial-ripple-phone-chips/RadialRipplePhoneChips.tsx:
const RCOL = ['#d7dbe1', '#e0e4e9', '#e8ebef', '#eef0f3']; const RSZ = [560, 440, 320, 210]; const RINGS = RSZ.map((size, i) => ({ size, color: RCOL[i], phase: i * 1.7 })); // ... transform: `scale(${1 + 0.06 * Math.sin(t * Math.PI * 2 * 1.5 + phase)})`,关键点在于phase: i * 1.7:相邻层的正弦相位错开 1.7 rad。如果所有层相位全同,画面读作"整块放大缩小"(一个呼吸的圆盘);相位错开 1.7 rad 后,各层在任意时刻处于不同的膨胀/收缩阶段,才会产生"波从中心向外荡开"的错觉。代码里每层的半径不同,错相缩放叠加后视觉上就是一圈圈此起彼伏的水波。
实现细节:每层圆用position: absolute; left/top: 50%加负 margin(margin: ${-size/2}px 0 0 ${-size/2}px)居中,配合borderRadius: '50%'与实色background。注意这是实色圆叠放而非描边圆环,层序必须由大到小依次 append(见后文"已知坑")。
2. 手机 mockup 与自动滚屏:匀速才是"自动播放"
- 手机 132×264、22px 圆角,投影
0 24px 50px rgba(58,64,74,.35); - 屏内 8 张骨架卡组成 feed;
- feed
translateY 0 → −150px,时间窗t 0.08 → 0.98,匀速、无缓动。
源码对应:
width: 132, height: 264, borderRadius: 22, boxShadow: '0 24px 50px rgba(58,64,74,.35)', // feed 滚动: transform: `translateY(${-seg(t, 0.08, 0.98) * 150}px)`,seg(t, 0.08, 0.98)是归一化分段进度函数(见 demos/_fixtures/Motion.tsx),默认使用E.linear,即从全片 8% 开始、98% 结束的线性匀速滚动。卡片的调节手感备注写得很直白:"加 ease 立刻读作'有人在滑';匀速才是自动播放"——自动播放的语义来自滚动的机械匀速,任何缓动都会让人脑补出"一只手指在拖动",这层"机器在跑"的证据感就破了。
投影0 24px 50px(24px 垂直偏移 + 50px 模糊)是手机"浮在波上"的唯一深度依据:去掉投影,手机就"贴平"到背景上,三层空间感立刻塌陷。
3. 两侧 chip:outBack 过冲 + 错峰 + 渐进悬浮
- chip pop:
seg(t0, t0+0.12, outBack)驱动scale 0.8 → 1,opacity 在前 0.08 就跳满; - 左 chip 起于 t=0.22,右 chip 起于 t=0.40(约 0.6s 差);
- pop 完成后接
sin悬浮 ±3px(2 周期/全片),由seg(t0+0.12, t0+0.3)渐进介入——不是一落位就开始飘。
源码中chipStyle函数完整实现了这套节奏:
const chipStyle = (t0: number, ph: number): React.CSSProperties => { const p = seg(t, t0, t0 + 0.12, E.outBack); const fl = Math.sin(t * Math.PI * 2 * 2 + ph) * 3 * seg(t, t0 + 0.12, t0 + 0.3); return { opacity: seg(t, t0, t0 + 0.08), transform: `scale(${lerp(p, 0.8, 1)}) translateY(${fl}px)`, }; };两个 chip 的挂载位置:
<div style={{ ...chipBase, top: '38%', right: 'calc(50% + 86px)', ...chipStyle(0.22, 0) }}>Feature one</div> <div style={{ ...chipBase, top: '56%', left: 'calc(50% + 86px)', ...chipStyle(0.4, 1.8) }}>Feature detail</div>三个手感要点:
- outBack 的过冲量是"弹出"的全部质感:
E.outBack(s = 1.70158)会让 scale 先超过 1 再回落,这一下过冲就是"啪地弹出来";换成 outCubic 就平了,读作"普通放大"。缓动表定义见 demos/_fixtures/Motion.tsx。 - 错峰(左 0.22 / 右 0.40)是叙事:同时出现读作两个标签(静态并列),错开约 0.6s 才有"一个一个说给你听"的节奏。
- 悬浮是渐入的:
fl的计算里,正弦幅度 3px 乘上seg(t, t0+0.12, t0+0.3)这个渐入包络——pop 落位后 0.18s(约 0.3−0.12)内悬浮才逐步生效。若一落位就开始飘,chip 会显得"没站稳",抢掉 pop 的落定感。
参数表:完整数值与调节手感
以下参数表完整继承自卡片文档,并补充了源码中对应的常量位置:
| 参数 | 典型值 | 调节手感 |
|---|---|---|
| 同心圆层数/尺寸 | 4 层 560/440/320/210px | 3 层撑不满画面,5 层以上最外层被裁掉只剩色带 |
| 呼吸幅度 | scale 1±0.06,1.5 周期/全片 | 0.06 已是上限;到 0.1 就读作"脉冲动画"而非水波 |
| 相位差 | 相邻层 1.7 rad | 相位全同 = 整块放大缩小;差 1.7 才有波从中心荡开的错觉 |
| 手机投影 | 0 24px 50px rgba(58,64,74,.35) | 投影是手机"浮在波上"的唯一依据,去掉就贴平了 |
| 自动滚屏 | translateY 0→−150px,t 0.08→0.98 匀速 | 加 ease 立刻读作"有人在滑";匀速才是自动播放 |
| chip pop | outBack、0.12 时长、scale 0.8→1 | outBack 的过冲量是"弹出"的全部质感,换 outCubic 就平了 |
| chip 时序 | 左 0.22 / 右 0.40(≈0.6s 差) | 同时出现读作两个标签;错开才有"一个一个说"的节奏 |
| chip 悬浮 | ±3px、2 周期,pop 后 0.18 内渐入 | 幅度超过 5px 就和同心圆的呼吸抢戏 |
表中的数值全部在480×270 设计坐标系下标定:DesignStage容器(demos/_fixtures/Motion.tsx)以 480×270 作画、等比放大到合成分辨率(默认transform: scale合成期放大,文字密集场景可换raster="zoom"布局期放大)。因此改合成分辨率(如 1920×1080)不需要动任何参数,这是 Motion 系 demo 与普通 demo 的关键差异。
源码级实现细节:骨架卡、确定性随机与全局 t 驱动
feed 骨架卡的生成
feed 里 8 张骨架卡并非手写,而是由数组映射生成(RadialRipplePhoneChips.tsx):
const CARDS = Array.from({ length: 8 }, (_, i) => ({ imgGrad: `linear-gradient(120deg,rgba(${ACCENT_RGB},${(0.5 - i * 0.04).toFixed(2)}),rgba(${ACCENT_RGB},${(0.8 - i * 0.05).toFixed(2)}))`, l1w: `${62 + rand(i) * 28}%`, l2w: `${34 + rand(i + 40) * 30}%`, }));每张卡 = 一张强调色渐变图占位 + 两条伪随机宽度的文字条(l1w62%–90%、l2w34%–64%)。随机必须是确定性的:这里用的rand(seed)是 Motion.tsx 中的确定性伪随机(Math.sin(seed * 127.1 + 311.7) * 43758.5453取小数部分),同一种子跨帧、跨渲染结果完全一致,满足 Remotion 逐帧确定性渲染的要求——这也解释了为什么 8 张卡的"随机"宽度在每一帧、每一次渲染都一样。
全局归一化时间 t
所有动画都由useT()提供的全局归一化进度驱动(Motion.tsx):t = frame / (durationInFrames - 1),末帧恰为 1。seg(t, t0, t1, ease)把 t 在[t0, t1]窗口内归一化并套用缓动,越界钳位——这是全片所有时间轴的统一原语,让"0.22 起、0.12 时长、outBack"这类描述可以直接映射成代码。
box-sizing 的还原细节
手机 mockup 有个值得注意的实现细节:Remotion 会注入* { box-sizing: border-box },而原样片的渲染管线没有全局 border-box,因此参考实现里显式还原了content-box(boxSizing: 'content-box',源码注释说明 132px 是内容宽、7px padding 外扩),否则手机尺寸与样片对不上。这类"跨渲染管线对齐"的注释是该仓库 demo 的通用惯例——每张卡都经过与原样片的全帧比对验收。
已知坑:四类必须规避的翻车点
卡片文档"已知坑"一节列出的问题全部有源码佐证,逐一展开:
chip 定位的 86px 硬编码:chip 用
calc(50% + 86px)贴着手机边缘定位(左 chip 在右侧right: calc(50% + 86px)、右 chip 在左侧left: calc(50% + 86px))。改手机宽度(132px)时必须同步改这个 86px,否则 chip 会压到 mockup 上。86px ≈ 手机半宽 66px + 20px 安全间距。feed 高度必须溢出屏高:屏内 feed 是 8 张骨架卡组成的占位内容,滚动位移 150px。落地换真实截图时,feed 总高必须大于「150px + 屏高」,否则滚到底会露白。骨架卡里每张
margin: 8px 8px 0+ 7px padding + 34px 图 + 两条文字条,8 张累计高度天然满足条件,但换成真实内容后要重新核算。实色圆叠放的层序:同心圆是实色叠放(不是描边圆环),层序必须由大到小 append(560 → 440 → 320 → 210)。顺序反了,小圆盖在大圆上面,就只看得见最大那层(或者只能看见最后一层),"波从中心荡开"的层次感全部丢失。源码中
RINGS数组正是按RSZ从大到小映射,RINGS.map渲染顺序即层序。换肤只需改一个变量:
ACCENT_RGB(默认'122,134,153'中性灰蓝,即#7a8699)只作用于屏内缩略图渐变(imgGrad的rgba()值)。换项目品牌色时只改这一个变量即可完成换肤,其他所有颜色(浅灰底、圆层灰阶、白色 chip、深色机身)都是中性骨架,不需要动。
落地使用:把这张卡装进你的 Remotion 项目
卡片"参考实现"一节指向 demos/effects/radial-ripple-phone-chips/(RadialRipplePhoneChips.tsx)。按 demos/README.md 的说明,Motion 系 demo 的使用方式是:copy 需要的.tsx进你的 Remotion 项目(30fps / 1920×1080),把共享依赖_fixtures/Motion.tsx一并带上并改 import 路径,然后注册成 Composition:
import { RadialRipplePhoneChips, RADIAL_RIPPLE_PHONE_CHIPS_DURATION } from './effects/radial-ripple-phone-chips/RadialRipplePhoneChips'; <Composition id="RadialRipplePhoneChips" component={RadialRipplePhoneChips} durationInFrames={RADIAL_RIPPLE_PHONE_CHIPS_DURATION} // 168f fps={30} width={1920} height={1080} />组件同时导出了时长常量RADIAL_RIPPLE_PHONE_CHIPS_DURATION = 168(5600ms @ 30fps),注册时直接引用即可,无需手写帧数。
落地后做换肤/换文案时,改动面很小:改ACCENT_RGB换品牌色,改两处 chip 的>Feature one/>Feature detail文案,把屏内骨架卡换成真实产品截图(记得保持 feed 总高 > 150px + 屏高)。动画逻辑一行都不用动。
验证手段:渲染冒烟
仓库提供了一键渲染冒烟脚本 assets/scripts/smoke-render-demos.py(见 demos/README.md),会扫描所有带时长导出(_DURATION)的 demo、自动生成注册文件、逐个remotion still渲染首帧并断言输出非空。可以对整张卡做快速验证:
# 需要 template 依赖(CI 里临时装 motion-blur,本卡不依赖它) cd template && npm ci cd .. && python3 assets/scripts/smoke-render-demos.py --subset RadialRipplePhoneChips该脚本--subset指向不存在的 demo 时会以退出码 1 明确报错;需要真实 mp4 素材的 demo 会被跳过并报告,不阻塞全量。工作区中还保留了一份等价的镜像实现 workbench/demosrc/effects/radial-ripple-phone-chips/RadialRipplePhoneChips.tsx,与 demos 下源码逐行一致,可供对照。
小结:一张卡讲清"低能量定格镜头"的完整语法
radial-ripple-phone-chips的价值不在于单点技巧,而在于它示范了一套可复用的产品定格镜头配方:氛围层(同心圆错相呼吸)负责不冷场,证据层(匀速自动滚屏)负责"产品活着",语义层(chip 错峰 pop + 渐入悬浮)负责信息递进——三层各自极慢、互不抢戏,叠加后画面没有任何一帧是静止的。配合 480×270 设计坐标系(改分辨率不动参数)、确定性随机(同帧跨渲染可复现)和单变量换肤(ACCENT_RGB),它是"用最少的动作把产品稳稳放在画面里"的标准答案;卡片文档中的参数表、已知坑与参考实现三者合起来,就是可以直接照抄的施工图。
- AI 技能
- 媒体生成
- 视频
【免费下载链接】video-shotcraft
AI video skill for Claude Code & Codex — cinematic product videos with Remotion: 152 shot recipe cards, 209 motion previews, a production-ready template
相关推荐
Radial Ripple Phone Chips:基于 Remotion 的同心波纹手机定格动效实现与调参指南
Radial Ripple Phone Chips:基于 Remotion 的同心波纹手机定格动效实现与调参指南 导读 本指南围绕 video shotcraf
AI 技能媒体生成视频用 Remotion 复刻「取景括号 + 扫描光带」:video-shotcraft ScanBracketSweep 镜头卡全拆解
用 Remotion 复刻「取景括号 + 扫描光带」:video shotcraft ScanBracketSweep 镜头卡全拆解 本篇基于 video sh
AI 技能媒体生成视频用 Remotion 把 CLI 演示拍成 3D 空间叙事:video-shotcraft Terminal3D 镜头卡拆解与复刻指南
用 Remotion 把 CLI 演示拍成 3D 空间叙事:video shotcraft Terminal3D 镜头卡拆解与复刻指南 本指南以 video s
AI 技能媒体生成视频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考