Motion · Tipografia

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.

1920×108016:930 fps5.5s · 165 quadrosremotionLicença: Apache-2.0#shotcraft#remotion#typography

Fonte: video-shotcraft (Vincent Wei) ↗ · Apache-2.0 · Composição Remotion (React/TSX) — vídeo de prévia, sem player no navegador

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×3px、词宽 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.

Tudo nesta página também é legível por máquina. Aponte seu agente para o JSON ou adicione o servidor MCP do gimgs e peça para buscar templates de motion.

  1. Baixe o JSON — contém a receita do plano (timing, easing, tabela de parâmetros, armadilhas) e o código TSX completo.
  2. Clone o repositório video-shotcraft; o componente importa fixtures de demos/_fixtures e helpers de assets/lib.
  3. Registre o componente como <Composition> em um projeto Remotion e renderize com `npx remotion render`, ou reimplemente a receita no seu próprio engine.
curl -s https://gimgs.net/motion/vertical-word-roll-blur-cycle.json
git clone https://github.com/Vincentwei1021/video-shotcraft
# component: demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx
npx remotion render <CompositionId> out.mp4
claude mcp add --transport http gimgs https://gimgs.net/mcp
# then: search_motion_templates / get_motion_template("vertical-word-roll-blur-cycle")

Prompt

Use the video-shotcraft shot recipe "Vertical word-roll cycle" (Remotion composition, Apache-2.0) published on gimgs.net.
Recipe JSON (prompt = timing/easing/parameter table/pitfalls, files = TSX source): https://gimgs.net/motion/vertical-word-roll-blur-cycle.json
Raw TSX: https://gimgs.net/motion/vertical-word-roll-blur-cycle/template.html
Repository: https://github.com/Vincentwei1021/video-shotcraft  (component: demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx; imports demos/_fixtures and assets/lib)
Spec: 1920x1080, 30 fps, 5.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).

JSON · Markdown · llms.txt

3,557 chars · Apache-2.0Abrir template bruto ↗
// ===== demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx =====
// vertical-word-roll-blur-cycle — Word Roll 竖向词条滚轮(motion-lab 定稿转原生 Remotion)
// 标语后半词用竖向滚轮循环 Apps→Teams→Data→Everyone:中心词清晰上色,相邻行浅灰带
// 垂直 blur(滚轮景深),每步 outQuint 前快后慢带轻微过冲,落定瞬间中心词从灰染成强调色。
// 设计坐标 480×270(DesignStage 等比放大),参数表数值以此坐标系标定。
import React from 'react';
import { DesignStage, E, seg, useT } from '../../_fixtures/Motion';

export const VERTICAL_WORD_ROLL_BLUR_CYCLE_DURATION = 150; // 5000ms @30fps

const ROW = 44;
const WORDS = ['Apps', 'Teams', 'Data', 'Everyone'];
// 3 次换词,每次 0.11(≈0.55s)
const STEPS = [0.16, 0.36, 0.56];

const ACCENT = '#4B4BF5';
const ACCENT_DIM = '#B9B9BE';
const clamp01 = (v: number) => Math.max(0, Math.min(1, v));
// 十六进制颜色按 k 混合(与原 effect.js 的 mixHex 等价)
const mixHex = (a: string, b: string, k: number) => {
  k = clamp01(k);
  const pa = [1, 3, 5].map((i) => parseInt(a.slice(i, i + 2), 16));
  const pb = [1, 3, 5].map((i) => parseInt(b.slice(i, i + 2), 16));
  const c = pa.map((v, i) => Math.round(v + (pb[i] - v) * k));
  return `rgb(${c[0]},${c[1]},${c[2]})`;
};

export const VerticalWordRollBlurCycle: React.FC = () => {
  const t = useT();

  // 滚轮进度 p:每步 0.7·outQuint + 0.3·outBack(前快后极慢 + 轻微过冲回落)
  let p = 0;
  for (const s of STEPS) {
    const u = seg(t, s, s + 0.11);
    p += 0.7 * E.outQuint(u) + 0.3 * E.outBack(u);
  }

  return (
    <DesignStage bg="#F7F7FA">
      <div
        style={{
          position: 'absolute',
          inset: 0,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          fontFamily: '-apple-system,system-ui,sans-serif',
        }}
      >
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: 14,
            // 结束整组淡出
            opacity: 1 - seg(t, 0.9, 0.985) * 0.999,
          }}
        >
          <div
            style={{
              fontSize: 30,
              fontWeight: 800,
              color: '#0B0B0C',
              letterSpacing: -0.5,
            }}
          >
            Built for
          </div>
          {/* 三行高的遮罩窗口,滚轮列在其中滑动,中心行 = 第二行 */}
          <div style={{ position: 'relative', height: ROW * 3, width: 190, overflow: 'hidden' }}>
            <div
              style={{
                position: 'absolute',
                left: 0,
                top: 0,
                transform: `translateY(${ROW - p * ROW}px)`,
              }}
            >
              {WORDS.map((w, i) => {
                const d = Math.abs(i - p);
                // 相邻行方向 blur:距中心 1 行内线性 0→3px,更远 3→5px
                const blur = d < 1 ? 3 * d : 3 + 2 * Math.min(d - 1, 1);
                const op = d < 1 ? 1 - 0.65 * d : Math.max(0.1, 0.35 - 0.23 * (d - 1));
                return (
                  <div
                    key={w}
                    style={{
                      height: ROW,
                      display: 'flex',
                      alignItems: 'center',
                      fontSize: 30,
                      fontWeight: 800,
                      letterSpacing: -0.5,
                      filter: `blur(${blur.toFixed(2)}px)`,
                      opacity: op,
                      // 落定染色:中心词灰→强调色(d 越小越彩)
                      color: mixHex(ACCENT_DIM, ACCENT, clamp01(1 - d * 2.4)),
                    }}
                  >
                    {w}
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>
    </DesignStage>
  );
};


  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.
paramtypedefaultdescription
—

Mais nesta categoria