Motion · Rhythm
Rhythm interrupt moves
Two rhythm-breaking techniques: jump-cut-punch-in, a three-step jump-cut push-in, and strobe-black-frames, strobing black frames.
Source: video-shotcraft (Vincent Wei) ↗ · Apache-2.0 · Remotion composition (React/TSX) — preview video, no in-browser player
Variants
transform-origin is pinned to the target's center, scale jumps through three steps with zero tweening, each jump getting a 2f deepening pulse as a tick.
Closing in on a core metric step by step; a documentary-style stare
Full-screen black frames flash according to a hardcoded frame-number table (2f each, intervals tightening from 8f down to 3f), and the last flash lifts straight into a hard-cut scale-up landing.
The countdown build-up before the film's highest climax
When to use
Using "breaking continuity" itself as a rhythm device: a jolting push-in (B), a suffocating approach (C); complements beat-cut-moves (cut-point layout) and montage-rhythm (section breathing)
Intention
The library's other rhythm cards all handle "how to cut, how densely"; these two handle how to break: the viewer expects continuity, and you break it on purpose — the way you break it is the message. B breaks in space — the same composition jumps three times with no in-between (1x→1.6x→2.6x), a Godard-style jump-cut jolt, with more of a "look here, closer, that's it" command than a smooth push-in; C breaks in existence — the image and pure black alternate in a strobe with tightening intervals, a suffocating countdown before a climax. Choose by use case: forced focus on a metric uses B, building pressure before a climax uses C.
Duration & energy
- Duration: B ~4.5s / C ~4.5s
- Energy: B Medium / C High
Shot recipe (original Chinese — timing, easing, parameter table, known pitfalls)
意图
库内节奏卡管的都是"怎么切、切多密";这两式管怎么断——观众预期 连续,你偏打断,打断方式即表达:B 是空间断——同构图三次无补间跳大 (1x→1.6x→2.6x),戈达尔跳切的顿挫,比连续推近更有"看这里、再近点、 就是它"的指令感;C 是存在断——画面与纯黑交替频闪且间隔收紧, 高潮前的窒息倒数。选型:强制聚焦指标用 B,高潮前蓄压用 C。
两式选型
| 式 | 做法 | 适用 | |----|------|------| | B jump-cut-punch-in | transform-origin 钉目标中心,三档 scale 阶梯跳变(零补间),每跳 2f 加深脉冲当 tick | 逐级逼近核心指标;纪录片式盯住 | | C strobe-black-frames | 全屏黑帧按写死帧号表闪现(每次 2f,间隔 8f→3f 收敛),末闪掀开即硬切放大落定 | 全片最高潮前的倒数蓄压 |
参数表
| 参数 | 典型值 | 调节手感 | |------|--------|----------| | B 跳挡 | 1.0→1.6→2.6,各 hold ≥35f | 挡差 <1.5× 读作画面抖了一下 | | B tick | 跳变帧起 2f brightness 0.92 全画面脉冲 | 无 tick 的跳切读作丢帧 | | C 帧号表 | [40,48,55,61,66,70,73,76,79] 各 2f 纯黑 | 间隔必须收敛;等距频闪只是闪没有"逼近" | | C 落锤 | 末闪掀开一帧到位 scale 1.35 + 2f 加深脉冲 | 掀开后还在原构图,频闪就白憋了 | | 收尾 | B 末挡 ≥45f / C 硬切后 ≥50f 真静止 | 打断系事后 hold 从重给 |
已知坑
- demo 在灰阶/占位素材上调校通过——参数是调校起点非实战定稿,
首次实战须以真实素材回验
- 两式与 speed-ramp-freeze 都动"时间轴",同一镜头只能有一个时间
操纵者
- C 式光敏警示:频闪画面需注意光敏性癫痫观众提示;且必须配乐
渐强同步(无声频闪读作信号故障),全片 ≤1 次
- B 式三挡构图必须同 origin(钉死目标中心)——每挡重新构图就是
三个镜头,不是跳切
- 声音强依赖:B 每跳一声 tick、C 每闪一声打点(sound-design §4.5)
参考实现
demos/rhythm/rhythm-interrupt-moves/ (JumpCutPunchIn.tsx / StrobeBlackFrames.tsx)
Reference implementation (Remotion)
- demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx
- demos/rhythm/rhythm-interrupt-moves/StrobeBlackFrames.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/rhythm/rhythm-interrupt-moves/StrobeBlackFrames.tsx
The component imports shared fixtures from demos/_fixtures and helpers from assets/lib in the repo; SKILL.md there documents the render workflow.
Everything on this page is also machine-readable. Point your agent at the JSON, or add the gimgs MCP server and ask it to search motion templates.
- Fetch the JSON — it holds the shot recipe (timing, easing, parameter table, pitfalls) and the full TSX source.
- Clone the video-shotcraft repo; the component imports shared fixtures from demos/_fixtures and helpers from assets/lib.
- Register the component as a <Composition> in a Remotion project and render with `npx remotion render`, or re-implement the recipe in your own engine.
curl -s https://gimgs.net/motion/rhythm-interrupt-moves.jsongit clone https://github.com/Vincentwei1021/video-shotcraft
# component: demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx, demos/rhythm/rhythm-interrupt-moves/StrobeBlackFrames.tsx
npx remotion render <CompositionId> out.mp4claude mcp add --transport http gimgs https://gimgs.net/mcp
# then: search_motion_templates / get_motion_template("rhythm-interrupt-moves")Prompt
Use the video-shotcraft shot recipe "Rhythm interrupt moves" (Remotion composition, Apache-2.0) published on gimgs.net. Recipe JSON (prompt = timing/easing/parameter table/pitfalls, files = TSX source): https://gimgs.net/motion/rhythm-interrupt-moves.json Raw TSX: https://gimgs.net/motion/rhythm-interrupt-moves/template.html Repository: https://github.com/Vincentwei1021/video-shotcraft (component: demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx, demos/rhythm/rhythm-interrupt-moves/StrobeBlackFrames.tsx; imports demos/_fixtures and assets/lib) Spec: 1920x1080, 30 fps, 4.54s 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/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx =====
// 三级跳切推近(jump-cut-punch-in)——节奏剪辑|戈达尔跳切/纪录片 punch-in。
// FakeDashboard A 固定构图,transform-origin 钉在第 2 行中间卡中心
// (1070px, 817px)。三次无补间硬切逐级放大:刻意零 interpolate,
// 切换帧一帧到位。每次跳切帧叠 2f 整画面 brightness 0.92 加深脉冲当 tick。
// 关键帧:0–34 scale 1.0 hold → 帧 35 直跳 1.6(35–36 加深脉冲)→ hold →
// 帧 70 直跳 2.6(70–71 加深脉冲)→ 72–134 全静止(63f ≥45f)。
import React from 'react';
import { useCurrentFrame } from 'remotion';
import { G, FakeDashboard, TitleBlock } from '../../_fixtures/Fixtures';
// 目标卡片(3×2 网格第 2 行中间卡)几何:
// 侧栏 220 + 内边距 36;卡宽 (1920-220-72-56)/3 = 524.67,卡高 (1080-72-72-28)/2 = 454
const CARD_L = 220 + 36 + 524.67 + 28; // ≈808.67
const CARD_T = 72 + 36 + 454 + 28; // 590
const CARD_W = 524.67;
const CARD_H = 454;
const ORIGIN_X = CARD_L + CARD_W / 2; // ≈1071
const ORIGIN_Y = CARD_T + CARD_H / 2; // 817
// 三级硬切:零补间,帧 35 / 帧 70 一帧到位
const scaleAt = (f: number): number => (f < 35 ? 1.0 : f < 70 ? 1.6 : 2.6);
// 跳切帧 2f 加深脉冲(整画面 brightness 0.92)
const pulseAt = (f: number): number =>
(f >= 35 && f <= 36) || (f >= 70 && f <= 71) ? 0.92 : 1;
export const JumpCutPunchIn: React.FC = () => {
const frame = useCurrentFrame();
const s = scaleAt(frame);
const b = pulseAt(frame);
return (
<div
style={{
width: 1920,
height: 1080,
background: G.bg,
position: 'relative',
overflow: 'hidden',
filter: `brightness(${b})`,
}}
>
<div
style={{
position: 'absolute',
inset: 0,
transform: `scale(${s})`,
transformOrigin: `${ORIGIN_X}px ${ORIGIN_Y}px`,
}}
>
<FakeDashboard variant="A" />
{/* 目标卡片标记:随构图一起缩放,提示 punch-in 落点 */}
<div
style={{
position: 'absolute',
left: CARD_L - 10,
top: CARD_T - 10,
width: CARD_W + 20,
height: CARD_H + 20,
border: `3px dashed ${G.mid}`,
borderRadius: 20,
boxSizing: 'border-box',
}}
/>
</div>
{/* 标签不随缩放,固定左上角 */}
<div style={{ position: 'absolute', left: 260, top: 20 }}>
<TitleBlock text="JUMP CUT PUNCH-IN" size={54} />
</div>
</div>
);
};
// ===== demos/rhythm/rhythm-interrupt-moves/StrobeBlackFrames.tsx =====
// 频闪黑帧(strobe-black-frames)——节奏剪辑|VJ strobe / 剪映闪黑。
// FakeDashboard A 全程缓慢推近蓄张力(scale 1.0→1.05,Easing.in(quad),
// 越到后段越快)。40–80f 频闪窗:全屏纯黑 #0c0c0c 按写死帧号表闪现,
// 每次持续 2f,间隔从 8f 收敛到 3f,窒息感逐渐逼近。最后一闪盖住 79–80,
// 帧 81 掀开时构图已硬切到 scale 1.35 对准第 2 行中间卡(零补间一帧到位),
// 叠 2f brightness 0.88 加深脉冲当落锤。
// 关键帧:0–78 推近 1.0→~1.05 → 黑闪 [40,48,55,61,66,70,73,76,79](各 2f)→
// 79–80 全黑 → 帧 81 硬切 scale 1.35(81–82 加深脉冲)→ 83–134 全静止(52f ≥50f)。
// 光敏警示:实战建议配乐渐强使用。
import React from 'react';
import { useCurrentFrame, interpolate, Easing } from 'remotion';
import { G, FakeDashboard, TitleBlock } from '../../_fixtures/Fixtures';
// punch-in 落点:3×2 网格第 2 行中间卡中心(同 JumpCutPunchIn 几何)
// 侧栏 220 + 内边距 36;卡宽 (1920-220-72-56)/3 ≈ 524.67,卡高 (1080-72-72-28)/2 = 454
const CARD_L = 220 + 36 + 524.67 + 28; // ≈808.67
const CARD_T = 72 + 36 + 454 + 28; // 590
const CARD_W = 524.67;
const CARD_H = 454;
const ORIGIN_X = CARD_L + CARD_W / 2; // ≈1071
const ORIGIN_Y = CARD_T + CARD_H / 2; // 817
// 黑闪帧号表(写死):间隔 8→7→6→5→4→3→3→3,每次持续 2f(f0 与 f0+1)
const FLASHES = [40, 48, 55, 61, 66, 70, 73, 76, 79];
const isBlack = (f: number): boolean =>
FLASHES.some((f0) => f >= f0 && f <= f0 + 1);
// 帧 81 前缓慢推近(Easing.in 蓄力),81 起零补间硬切 1.35 定住
const scaleAt = (f: number): number =>
f < 81
? interpolate(f, [0, 80], [1.0, 1.05], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.in(Easing.quad),
})
: 1.35;
// 落锤:81–82 两帧整画面加深脉冲
const pulseAt = (f: number): number => (f >= 81 && f <= 82 ? 0.88 : 1);
export const StrobeBlackFrames: React.FC = () => {
const frame = useCurrentFrame();
const s = scaleAt(frame);
const b = pulseAt(frame);
const black = isBlack(frame);
return (
<div
style={{
width: 1920,
height: 1080,
background: G.bg,
position: 'relative',
overflow: 'hidden',
filter: `brightness(${b})`,
}}
>
<div
style={{
position: 'absolute',
inset: 0,
transform: `scale(${s})`,
transformOrigin: `${ORIGIN_X}px ${ORIGIN_Y}px`,
}}
>
<FakeDashboard variant="A" />
{/* 落点卡片标记:随构图一起缩放,提示硬切对准的核心卡 */}
<div
style={{
position: 'absolute',
left: CARD_L - 10,
top: CARD_T - 10,
width: CARD_W + 20,
height: CARD_H + 20,
border: `3px dashed ${G.mid}`,
borderRadius: 20,
boxSizing: 'border-box',
}}
/>
</div>
{/* 标签不随缩放,固定顶栏位置 */}
<div style={{ position: 'absolute', left: 260, top: 20 }}>
<TitleBlock text="STROBE BLACK FRAMES" size={54} />
</div>
{/* 全屏黑闪层:盖住一切(含标签),每次 2f */}
{black && (
<div
style={{
position: 'absolute',
inset: 0,
background: '#0c0c0c',
zIndex: 10,
}}
/>
)}
</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/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx, demos/rhythm/rhythm-interrupt-moves/StrobeBlackFrames.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 |
|---|---|---|---|
| — | |||
More in this category

Trailer grammar: three beats
Three trailer-grammar moves — trailer-bumper, a fast-cut hook up front; card-footage-cadence, text cards interleaved with dialogue footage; smash-cut, a slam into stillness.

Speed ramp and freeze-annotate
Two frame-remap pacing moves — speed-ramp (fast → 0.2x gaze → fast) and freeze-annotate (flowing → freeze with a circled callout → unfreeze).

Spectrum-morph underline
Spectrum UI morph — the title underline splits into vertical bars that pulse like a spectrum for two bars, then closes back into a straight line; music visualization living inside the UI.

Smear-frame afterimages
Afterimage smear — a card drags 4 crisp, countable clones while panning fast, merging into one on landing; an animated take on motion blur.