# Vertical word-roll cycle

The sentence's last word cycles on a vertical roller, 3 swaps at 0.55s each, fast then very slow with a slight overshoot; neighboring rows carry vertical blur and grayscale by distance, the centered word snapping from gray to accent color as it lands.

- Category: typography · Tags: shotcraft, remotion, typography
- Spec: 1920×1080 @ 30 fps · 5.5s (16:9)
- License: Apache-2.0 · Tier: free
- JSON: https://gimgs.net/motion/vertical-word-roll-blur-cycle.json
- Kind: remotion
- Source (TSX): https://gimgs.net/motion/vertical-word-roll-blur-cycle/template.html
- Repo: https://github.com/Vincentwei1021/video-shotcraft
- Credits: video-shotcraft (Vincent Wei) — https://github.com/Vincentwei1021/video-shotcraft
- Page: https://gimgs.net/motion/vertical-word-roll-blur-cycle.html

## Params

_No params._

Default params (base64url for `?p=`): `e30`

## Prompt

## When to use

A one-line pitch like "Built for ___" followed by an enumerated audience/object; a clean beat for light-background brand films

## Intention

The best solution for swapping the sentence's last word is a roller, not a cross-fade: a roller has its own built-in **direction** (flipping upward), telling the viewer "there's another one coming." This card's two identity marks are the neighboring rows' **vertical blur** (roller depth of field, simulating a mechanical drum's defocus) and the landing word's **color shift** (gray to accent color, "this one is the answer"). The sentence stem "Built for" never moves for the entire shot — the eye stays locked on the roller; if the stem wobbled, the sense of enumeration would fall apart.

## Duration & energy

- Duration: ~5.0s (150f@30fps: hold → 3 word swaps → group fades out at the tail)
- Energy: Medium (a steady three-beat, no peak)

## Shot recipe (original Chinese — timing, easing, parameter table, known pitfalls)

## 意图
句尾换词的最优解是滚轮而不是淡入淡出：滚轮自带**方向**（往上翻页），
观众知道"还有下一个"。这卡的两个身份记号是相邻行的**垂直 blur**
（滚轮景深，模拟机械转筒的失焦）和落定时的**染色**（灰→强调色，
"这个才是答案"）。句干 `Built for` 全程纹丝不动——眼睛钉在滚轮上，
句干一晃列举感就散。

## 动效核心
- 位置量 `p` 由 3 段窗累加：`STEPS = [0.16, 0.36, 0.56]`，每段窗 0.11
  （≈16f，约 0.55s），段间留 0.09 静置给观众读词
- 每段缓动是**混合曲线**：`0.7·E.outQuint(u) + 0.3·E.outBack(u)`——
  outQuint 给"前快后极慢"的机械减速，outBack 那三成给落定的微过冲回落
- reel 定位 `translateY(ROW - p·ROW)`，ROW=44px，mask 高 `ROW·3`=132px
  （露三行）——中心行恒定是 mask 第二行
- 距离驱动的三通道，`d = |i - p|`：
  - blur：`d<1` 时 `3d`，`d≥1` 时 `3 + 2·min(d-1,1)`（最远 5px）
  - opacity：`d<1` 时 `1 - 0.65d`，否则 `max(0.1, 0.35 - 0.23(d-1))`
  - 颜色：`mixHex(ACCENT_DIM, ACCENT, clamp01(1 - 2.4d))` —— **d>0.42 就完全
    是暗色**，所以只有真正落定的那一刻才是强调色，滚动中途全程灰
- 收尾 `seg(t, 0.9, 0.985)` 整组（句干 + 滚轮）淡出，不留残影给下一镜

## 参数表
| 参数 | 典型值 | 调节手感 |
|------|--------|----------|
| 词表 | 4 词（Apps→Teams→Data→Everyone），3 次换词 | 末词是结论（最宽那个词），前三个是例子；>5 词观众开始数，<3 词读不出"列举" |
| 拍点 | `[0.16, 0.36, 0.56]`，窗 0.11（≈16f） | 段间 0.09（≈13f）静置是给读词的，读不完的拍子等于没换；窗 >0.18 新旧同屏太久 |
| 缓动配方 | `0.7·outQuint + 0.3·outBack` | outQuint 是机械减速的来源；outBack 那三成给落定"咔"一下，纯 outQuint 读作电子屏滑动 |
| 行高/视窗 | ROW 44px、mask `44×3`px、词宽 190px | 露三行才有滚筒感（露一行读作淡入淡出）；宽度写死 190 是为不挤句干，词更长要同步加 |
| 相邻行 blur | 邻行 3px，最远 5px，**仅垂直向感知** | blur 是"滚筒景深"的身份证，删了退化成词条平移；>8px 邻行糊成灰条看不出是字 |
| 落定染色 | `1 - 2.4d` 映射 ACCENT_DIM→ACCENT | 系数 2.4 让染色只发生在落定瞬间；<1.5 滚动中途就上色，答案感散掉 |
| 字号字重 | 句干与滚轮同为 30px/800、`letter-spacing:-.5px` | 必须完全一致——滚轮词比句干大就读作两个元素，不是一句话 |
| 收尾淡出 | `seg(t, 0.9, 0.985)` 整组 | 末词落定后约 40f 静置再淡出；不 hold 等于白列举 |

## 已知坑
- demo 在灰阶/占位素材上调校通过——参数是调校起点非实战定稿，
  首次实战须以真实素材回验
- **mask 宽度写死 190px**：换词表时最长词（demo `Everyone`）必须能装进去，
  否则被裁字；反之词都很短则右侧留大片空白，句子重心偏左——换词表必须
  重量一次宽度
- 词长差别不宜过大：mask 宽度是固定的（本卡不做宽度自适应，那是
  pill-chip-slot-cycle-handled 的活），词长差 >2 倍时短词在框里显得孤立
- 句干必须钉死：demo 用 `flex + gap:14px` 是因为 mask 宽度恒定不会推挤
  句干——一旦改成宽度自适应的滚轮，就必须换成绝对定位锚左端，
  否则句干随词宽左右甩
- `p` 是三段窗**累加**出来的，所以三段窗不能重叠：重叠会让 p 在一帧内
  跨越一整行，滚轮"跳格"
- 与 pill-chip-slot-cycle-handled 分工：那卡是深色胶囊 + 宽度自适应挤开
  （词是徽章），本卡是裸词滚轮（词是句子成分）——同片只留一个
- 声音：每次落定是一个节奏点，配轻机械/开关音；三连发要交替双样本
  防机枪感，配法纪律见 sound-design.md

## 参考实现
demos/typography/vertical-word-roll-blur-cycle/
（VerticalWordRollBlurCycle.tsx）

## Reference implementation (Remotion)

- demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx

The component imports shared fixtures from `demos/_fixtures` and helpers from `assets/lib` in the repo; SKILL.md there documents the render workflow.


## Flow

1. **Read the recipe**
   Prompt = when to use, intention, parameter table with typical values and how each one feels, known pitfalls. Treat values as calibrated starting points.
2. **Get the code** — tool: git
   `git clone https://github.com/Vincentwei1021/video-shotcraft && cd video-shotcraft && npm install`
3. **Register + render** — tool: remotion
   `npx remotion render <CompositionId> out.mp4   # component: demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx`
4. **Or re-implement**
   Port the timing/easing from the recipe to HTML + WAAPI (gimgs motion contract) or any engine; keep the same segment windows and easing.

## Render

Clone https://github.com/Vincentwei1021/video-shotcraft (npm install). The component lives under demos/{category}/{name}/ and imports shared fixtures from demos/_fixtures and helpers from assets/lib. Copy it (with those imports) into a Remotion project, register a <Composition> with the template's width/height/fps/duration in Root.tsx, then `npx remotion render <CompositionId> out.mp4`. SKILL.md in the repo documents the full Claude Code / Codex workflow. The prompt below is the shot recipe (timing, easing, parameter table, pitfalls) — enough to re-implement the shot in HTML/WAAPI or another engine if you prefer.

## Contract

React/Remotion composition (TSX) from the open-source video-shotcraft library (Apache-2.0). It is not a browser-playable template: clone the repo, register the component in a Remotion project and render with `npx remotion render`. The recipe (prompt) describes timing, easing and parameters so you can also re-implement the shot in any engine.
