{
  "slug": "scramble",
  "title": "Scramble decode text",
  "tagline": "A monospace line of characters scrambles rapidly, then locks left to right into real letters one by one with a blue-white flash.",
  "description": "A monospace line of characters scrambles rapidly, then locks left to right into real letters one by one with a blue-white flash.",
  "category": "typography",
  "tags": [
    "shotcraft",
    "remotion",
    "typography"
  ],
  "tier": "free",
  "license": "Apache-2.0",
  "spec": {
    "width": 1920,
    "height": 1080,
    "fps": 30,
    "duration": 3.7,
    "aspect": "16:9"
  },
  "kind": "remotion",
  "params_schema": {
    "type": "object",
    "properties": {}
  },
  "default_params": {},
  "preview": {
    "poster": "https://gimgs.net/motion/media/scramble/poster-dd5720b503b5.jpg",
    "video": "https://gimgs.net/motion/media/scramble/video-86e29850cfb5.mp4"
  },
  "variants": [
    {
      "key": "scramble",
      "label": "scramble",
      "description": "A monospace line of characters first scrambles at high speed every 2 frames, then locks left to right one by one into real characters, with a blue-white highlight flash the instant each locks — a seed-driven, reproducible decryption feel.",
      "use": "",
      "video": "https://gimgs.net/motion/media/scramble/video-86e29850cfb5.mp4",
      "poster": "https://gimgs.net/motion/media/scramble/poster-dd5720b503b5.jpg"
    }
  ],
  "credits": {
    "author": "video-shotcraft (Vincent Wei)",
    "url": "https://github.com/Vincentwei1021/video-shotcraft"
  },
  "page_url": "https://gimgs.net/motion/scramble.html",
  "json_url": "https://gimgs.net/motion/scramble.json",
  "template_url": "https://gimgs.net/motion/scramble/template.html",
  "play_url": null,
  "markdown_url": "https://gimgs.net/motion/scramble.md",
  "updated_at": "2026-09-24T07:40:20.386Z",
  "prompt": "## When to use\n\nA technical opening title; a version number/codename reveal; a machine-voiced beat like \"system ready\" or \"data unlocked\"\n\n## Intention\n\nOf the three \"lettering\" techniques for the same title, typewriter feels like a person writing, flip-card feels like a machine broadcasting, and scramble-lock feels like **a machine computing** — first full-screen noise signals \"not decoded yet,\" then it locks in real characters one by one left to right. It naturally carries a hacker/decryption tone, suited to a technical product's opening; but it's also the most demanding on copy, since each character gets called out individually, so the character count is the beat count.\n\n## Duration & energy\n\n- Duration: About 3.2s (96f@30fps)\n- Energy: Medium-high (continuous high-frequency character-swapping visual noise, no single impact point)\n\n## Shot recipe (original Chinese — timing, easing, parameter table, known pitfalls)\n\n## 意图\n同一句标题的三种\"造字\"手法里，打字机是人在写、翻牌是机器在播报，\n乱码锁定是**机器在算**——先满屏噪声表示\"还没解出来\"，再左→右一个个\n咬定真字符。它天然带黑客/解密腔，适合技术产品的开场；但也最挑文案：\n字符是被逐个点名的，字数就是节拍数。\n\n## 动效核心\n- 全字符同时跳乱码，字池 47 个大写字母+数字+符号；**每 2 帧换一次字**\n  （`bucket = floor(frame/2)`，96f 全片约 48 次重掷）\n- 锁定点按字序线性铺开：`lockAt = 0.25 + (i/n)·0.6 + rand(i·7)·0.06`\n  ——第 24f 起第一个字定，第 82f 末字定，每字再叠 ≤6f 随机抖动破掉机械等分\n- 锁定瞬间闪光：`flash = 1 - seg(t, lockAt, lockAt+0.1)`，flash>0.4 时字色\n  从 #e8eaf0 提到 #dff3ff，同时打 `0 0 flash·18px` 蓝白光晕，约 3f 内衰完\n- 起手 6f 全空（`t < 0.06` 输出空格）——先给一拍空屏，噪声才是\"开始运算\"\n  而不是\"一直在闪\"\n- 乱码字符与闪光抖动全走种子哈希 `rand(seed)`，**禁 Math.random**，\n  同一帧号永远同一画面\n- 未锁定字色压到 #3d4560（近背景），锁定后才提亮——亮度差本身就是进度条\n\n## 参数表\n| 参数 | 典型值 | 调节手感 |\n|------|--------|----------|\n| 占位文案 | `TEMPLATE MOTION DEMO`，20 字符 | 字符数直接决定 stagger 密度：<10 字锁定太快读不出\"逐个\"，>30 字末字等到片尾 |\n| 锁定窗 | 全局 0.25→0.85（24f→82f） | 起点早于 0.2 噪声段太短没建立感；终点晚于 0.9 没有静置收尾 |\n| 锁定抖动 | `rand(i·7)·0.06`（≤6f） | 去掉就是完美等分，读作进度条而非\"逐个咬定\"；>0.12 顺序会乱 |\n| 跳字频率 | 每 2 帧（15 次/秒） | 1 帧一换糊成灰带；4 帧以上读作\"慢慢翻\"不是高速运算 |\n| 锁定闪光 | 窗 0.1（约 3f），光晕 18px 峰值 | 这一闪是\"咬定\"的画面体，删了只剩换字；>30px 相邻字光晕连成一片 |\n| 字体字距 | SF Mono/Menlo 34px、`letter-spacing:2px`、槽宽 `min-width:0.62em` | 等宽 + 固定槽宽是刚需，比例字体会随乱码字符宽度整行抖动 |\n| 起手空屏 | `t < 0.06`（前 6f） | 直接开噪声读作故障闪烁；>12f 空屏在剪辑里成了黑场 |\n\n## 已知坑\n- demo 在灰阶/占位素材上调校通过——参数是调校起点非实战定稿，\n  首次实战须以真实素材回验\n- **换成项目文案时字符数要贴近 20**：lockAt 是按 `i/n` 归一化铺开的，\n  字数变了锁定间隔跟着缩放——8 字标题会在半秒内全锁完（读不出解密过程），\n  40 字标题末字要等到 82f 才定（前面早锁的字已经\"凉了\"）\n- 必须等宽字体：槽宽写死 `0.62em`，比例字体下 `#`/`W`/`I` 宽度不一，\n  整行会随每次重掷左右抽动\n- 空格字符被显式跳过（永不参与乱码），所以词间隙全程保持——文案里\n  空格位置就是节奏的呼吸点，把长标题拆成 3–4 词比一整串更好读\n- 与 split-flap-title / 打字机类分工：那两个是**机械/人工**造字，本卡是\n  **算法**解字；一支片里同类\"造字\"手法只留一次，重复即贬值\n\n## 参考实现\ndemos/typography/scramble/\n（Scramble.tsx）\n\n## Reference implementation (Remotion)\n\n- demos/typography/scramble/Scramble.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/typography/scramble/Scramble.tsx\n\nThe component imports shared fixtures from `demos/_fixtures` and helpers from `assets/lib` in the repo; SKILL.md there documents the render workflow.\n",
  "flow": [
    {
      "step": "Read the recipe",
      "note": "Prompt = when to use, intention, parameter table with typical values and how each one feels, known pitfalls. Treat values as calibrated starting points."
    },
    {
      "step": "Get the code",
      "tool": "git",
      "cmd": "git clone https://github.com/Vincentwei1021/video-shotcraft && cd video-shotcraft && npm install"
    },
    {
      "step": "Register + render",
      "tool": "remotion",
      "cmd": "npx remotion render <CompositionId> out.mp4   # component: demos/typography/scramble/Scramble.tsx"
    },
    {
      "step": "Or re-implement",
      "note": "Port the timing/easing from the recipe to HTML + WAAPI (gimgs motion contract) or any engine; keep the same segment windows and easing."
    }
  ],
  "files": [
    {
      "path": "demos/typography/scramble/Scramble.tsx",
      "url": "https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/typography/scramble/Scramble.tsx"
    }
  ],
  "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.",
  "render": {
    "engine": "remotion",
    "frames": 111,
    "repo": "https://github.com/Vincentwei1021/video-shotcraft",
    "files": [
      "https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/typography/scramble/Scramble.tsx"
    ],
    "note": "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."
  },
  "source": "// ===== demos/typography/scramble/Scramble.tsx =====\n// scramble — Scramble Decode 乱码锁定（motion-lab 定稿转原生 Remotion）\n// 每个字符先高速随机跳字（种子驱动、可复现），再从左到右逐个\"锁定\"为真字符，\n// 锁定瞬间闪一下高亮辉光。与 typewriter 的顺序打字完全不同的质感——黑客/解密感。\n// 设计坐标 480×270（DesignStage 等比放大），参数表数值以此坐标系标定。\nimport React from 'react';\nimport { DesignStage, rand, seg, useT } from '../../_fixtures/Motion';\n\nexport const SCRAMBLE_DURATION = 96; // 3200ms @30fps\n\nconst TEXT = 'TEMPLATE MOTION DEMO';\nconst POOL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#$%&*+=<>/\\\\';\nconst CHARS = [...TEXT];\n\nexport const Scramble: React.FC = () => {\n  const t = useT();\n  const frame = Math.floor(t * 96);\n  return (\n    <DesignStage bg=\"#07080c\">\n      <div\n        style={{\n          position: 'absolute',\n          inset: 0,\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'center',\n          background: '#07080c',\n          fontFamily: '\"SF Mono\",Menlo,monospace',\n          fontSize: 34,\n          letterSpacing: 2,\n        }}\n      >\n        {CHARS.map((ch, i) => {\n          let content: string = ch;\n          let color = '#3d4560';\n          let textShadow = 'none';\n          if (ch !== ' ') {\n            // 锁定时刻：从左到右基础 stagger + 种子微扰\n            const lockAt = 0.25 + (i / CHARS.length) * 0.6 + rand(i * 7) * 0.06;\n            if (t < 0.06) {\n              content = ' '; // 开场短暂空白\n            } else if (t < lockAt) {\n              // 高速跳字：每 2 帧换一个随机字符\n              content = POOL[Math.floor(rand(i * 131 + Math.floor(frame / 2)) * POOL.length)];\n            } else {\n              // 锁定为真字符，锁定瞬间闪高亮辉光后回落\n              const flash = 1 - seg(t, lockAt, lockAt + 0.1);\n              color = flash > 0.4 ? '#dff3ff' : '#e8eaf0';\n              textShadow = `0 0 ${flash * 18}px rgba(120,200,255,${flash})`;\n            }\n          }\n          return (\n            <span\n              key={i}\n              style={{ minWidth: '0.62em', textAlign: 'center', color, textShadow }}\n            >\n              {content === ' ' ? ' ' : content}\n            </span>\n          );\n        })}\n      </div>\n    </DesignStage>\n  );\n};\n\n\n"
}