{
  "slug": "hatch-depth",
  "title": "Hatch to real data",
  "tagline": "Diagonal-hatched placeholder bars wipe-extend, then the hatching fades as a solid accent-colored layer fades in with values popping up, the placeholder chart turning into a real bar chart.",
  "description": "Diagonal-hatched placeholder bars wipe-extend, then the hatching fades as a solid accent-colored layer fades in with values popping up, the placeholder chart ",
  "category": "data",
  "tags": [
    "shotcraft",
    "remotion",
    "data"
  ],
  "tier": "free",
  "license": "Apache-2.0",
  "spec": {
    "width": 1920,
    "height": 1080,
    "fps": 30,
    "duration": 4.9,
    "aspect": "16:9"
  },
  "kind": "remotion",
  "params_schema": {
    "type": "object",
    "properties": {}
  },
  "default_params": {},
  "preview": {
    "poster": "https://gimgs.net/motion/media/hatch-depth/poster-bb7feec5857a.jpg",
    "video": "https://gimgs.net/motion/media/hatch-depth/video-d0c177fc77eb.mp4"
  },
  "variants": [
    {
      "key": "hatch-depth",
      "label": "hatch-depth · Hatch to real data",
      "description": "Diagonal-hatched placeholder bars wipe-extend, then the hatching fades as a solid accent-colored layer fades in with values popping up, the placeholder chart turning into a real bar chart.",
      "use": "",
      "video": "https://gimgs.net/motion/media/hatch-depth/video-d0c177fc77eb.mp4",
      "poster": "https://gimgs.net/motion/media/hatch-depth/poster-bb7feec5857a.jpg"
    }
  ],
  "credits": {
    "author": "video-shotcraft (Vincent Wei)",
    "url": "https://github.com/Vincentwei1021/video-shotcraft"
  },
  "page_url": "https://gimgs.net/motion/hatch-depth.html",
  "json_url": "https://gimgs.net/motion/hatch-depth.json",
  "template_url": "https://gimgs.net/motion/hatch-depth/template.html",
  "play_url": null,
  "markdown_url": "https://gimgs.net/motion/hatch-depth.md",
  "updated_at": "2026-09-24T07:40:01.455Z",
  "prompt": "## When to use\n\nThe \"from draft to real data\" narrative beat; a dashboard/report feature intro, or a segment emphasizing real-time data.\n\n## Intention\n\nShoot the product moment of \"a placeholder becoming real data\" as a visible material transformation: first, 45° diagonal-hatched bars sketch the sense of \"data will go here\", then a solid color layer replaces them in place — the geometry never moves, only the skin changes — what the audience reads is \"the same thing came alive\".\n\n## Duration & energy\n\n- Duration: About 4.4s (132f@30fps; growth 0–1.7s · transformation 2.2–3.4s · a settling micro-tremor)\n- Energy: Medium (progressive information, no explosive peak; the material transition itself creates the \"it's live\" moment)\n\n## Shot recipe (original Chinese — timing, easing, parameter table, known pitfalls)\n\n## 意图\n把\"占位符变成真数据\"这个产品瞬间拍成看得见的材质转换：先用 45° 斜纹条画出\"这里将有数据\"的草稿感，再让实心色层原位替换——几何完全不动、只换皮肤，观众读到的是\"同一样东西活了\"。\n\n## 动效核心\n- 5 条横柱按 `0.06 + i*0.05` 错峰生长，各 0.22 时长 `outCubic` wipe 伸长到目标宽度（0.4–0.95 归一化）\n- 生长阶段斜纹层（`repeating-linear-gradient 45°` + 同色描边）与实心层同宽同步长，但实心层 opacity=0——蜕变只是交叉淡化，宽度曲线共用，保证几何零跳变\n- t=0.5 起按 `0.5 + i*0.03` 逐条蜕变（0.14 时长）：斜纹 `1-morph` 淡出、实心 `morph` 淡入，标签同拍从灰变暗灰（视觉重心让给数据）\n- 数值文字 `w*420 K` 挂在柱端 `left: calc(w% + 8px)`，随蜕变淡入\n- t=0.7–0.85 全体柱宽乘 `1 + sin(t*30 + i*2.1)*0.02` 微颤——\"活数据在呼吸\"的暗示\n- 表头 METRICS ● LIVE 行 t=0.62–0.78 从上方 30px 滑入，宣告蜕变完成\n\n## 参数表\n| 参数 | 典型值 | 调节手感 |\n|------|--------|----------|\n| 错峰间隔 | 生长 0.05/条、蜕变 0.03/条 | 生长间隔可到 0.08 增强\"逐条点亮\"；蜕变间隔别超 0.05，拖长会读作故障闪烁 |\n| 生长时长 | 0.22（outCubic） | 缩到 0.15 更利落；配合错峰保证末条 ≤0.5 长完，给蜕变留窗口 |\n| 蜕变窗口 | 0.5 起、每条 0.14 交叉淡化 | 这是卡点位——BGM 重音应压在首条蜕变（t=0.5）上 |\n| 柱宽数据 | [0.85, 0.55, 0.95, 0.4, 0.7] | 换成真实数据比例即可；最长条 ≥0.9 保证画面有满幅锚点 |\n| 微颤幅度 | ±2%，t=0.7–0.85 | >4% 读作抖动 bug；不想要\"呼吸感\"可归零，但收尾会偏死板 |\n| 强调色 | `ACCENT='#5B8DEF'` / `ACCENT_HI='#8FB2F7'` | 双常量整体换肤；HI 用于数值文字，保持同族但更亮 |\n\n## 已知坑\n- 斜纹层和实心层宽度必须共用同一条 `grow` 曲线——分开算会在蜕变瞬间产生 1–2px 宽度跳变，\"原位换皮\"的错觉立刻穿帮\n- 标签（SERIES_A 等）是占位词，换项目真实指标名时注意 70px 定宽标签列，超长会被裁\n- 数值 `w*420` 是演示映射，接真数据时换成实际数值格式化函数，但保持\"随 grow 滚动\"（终值 ×grow）的读数感\n- 微颤用全局 t 驱动（`sin(t*30)`），改动画总时长 dur 会改变颤动频率，需重新目检\n\n## 参考实现\ndemos/data/hatch-depth/\n（HatchDepth.tsx）\n\n## Reference implementation (Remotion)\n\n- demos/data/hatch-depth/HatchDepth.tsx — https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/data/hatch-depth/HatchDepth.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/data/hatch-depth/HatchDepth.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/data/hatch-depth/HatchDepth.tsx",
      "url": "https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/data/hatch-depth/HatchDepth.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": 147,
    "repo": "https://github.com/Vincentwei1021/video-shotcraft",
    "files": [
      "https://raw.githubusercontent.com/Vincentwei1021/video-shotcraft/main/demos/data/hatch-depth/HatchDepth.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/data/hatch-depth/HatchDepth.tsx =====\n// hatch-depth — Hatch → Depth Chart 斜纹柱实体化（motion-lab 定稿转原生 Remotion）\n// 标签下的斜纹条逐条 wipe 伸长（保持 45° 斜纹占位质感），随后斜纹层淡出、强调色\n// 实心层淡入，蜕变为数据横柱条形图——几何无跳变、只换纹理与颜色，讲\"占位变真数据\"的隐喻。\n// 设计坐标 480×270（DesignStage 等比放大），参数表数值以此坐标系标定。\nimport React from 'react';\nimport { DesignStage, E, seg, useT } from '../../_fixtures/Motion';\n\nexport const HATCH_DEPTH_DURATION = 132; // 4400ms @30fps\n\nconst ACCENT = '#5B8DEF'; // 模板强调色，可按项目替换\nconst ACCENT_HI = '#8FB2F7'; // 同族高亮（数值文字）\n\nconst ROWS = [\n  { label: 'SERIES_A', w: 0.85 },\n  { label: 'SERIES_B', w: 0.55 },\n  { label: 'GROUP_C', w: 0.95 },\n  { label: 'GROUP_D', w: 0.4 },\n  { label: 'OTHER_E', w: 0.7 },\n];\n\n// 头部信息条里的 &nbsp;&nbsp;（连续普通空格在 JSX 会被折叠，须用不换行空格）\nconst NBSP2 = '  ';\n\nexport const HatchDepth: React.FC = () => {\n  const t = useT();\n  // 头部信息条：下滑入场\n  const headIn = seg(t, 0.62, 0.78, E.outCubic);\n  return (\n    <DesignStage bg=\"#0a0a0c\">\n      <div\n        style={{\n          position: 'absolute',\n          inset: 0,\n          background: '#0a0a0c',\n          padding: '36px 60px',\n          display: 'flex',\n          flexDirection: 'column',\n          justifyContent: 'center',\n          gap: 13,\n          // 原栈 SF Mono 对无头 Chrome 不可见，真实 Chrome 落到 macOS 默认\n          // 等宽字体 Courier（衬线打字机形）；显式补 Courier 兜底对齐原片\n          fontFamily: '\"SF Mono\",Courier,monospace',\n        }}\n      >\n        {ROWS.map(({ label, w }, i) => {\n          // 逐条 wipe 伸长 → 斜纹淡出/实心淡入 → 末段轻微 wiggle\n          const grow = seg(t, 0.06 + i * 0.05, 0.06 + i * 0.05 + 0.22, E.outCubic);\n          const morph = seg(t, 0.5 + i * 0.03, 0.5 + i * 0.03 + 0.14);\n          const wiggle = 1 + Math.sin(t * 30 + i * 2.1) * 0.02 * seg(t, 0.7, 0.85);\n          const wPct = grow * w * 100 * wiggle;\n          return (\n            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 14, height: 26 }}>\n              <span\n                style={{\n                  color: morph > 0.5 ? '#5c626f' : '#8b91a3',\n                  fontSize: 11,\n                  width: 70,\n                  flex: 'none',\n                  textAlign: 'right',\n                }}\n              >\n                {label}\n              </span>\n              <div style={{ position: 'relative', height: '100%', flex: 1 }}>\n                {/* 斜纹占位层 */}\n                <div\n                  style={{\n                    position: 'absolute',\n                    left: 0,\n                    top: 0,\n                    height: '100%',\n                    width: `${wPct}%`,\n                    borderRadius: 3,\n                    background: 'repeating-linear-gradient(45deg,#565860 0 4px,transparent 4px 9px)',\n                    border: '1px solid #565860',\n                    // 原渲染无全局 border-box：宽高为内容尺寸，1px 边框外扩\n                    // （斜纹相位随元素尺寸变化，box-sizing 不还原相位就对不上）\n                    boxSizing: 'content-box',\n                    opacity: 1 - morph,\n                  }}\n                />\n                {/* 强调色实心层 */}\n                <div\n                  style={{\n                    position: 'absolute',\n                    left: 0,\n                    top: 0,\n                    height: '100%',\n                    width: `${wPct}%`,\n                    borderRadius: 3,\n                    background: `linear-gradient(90deg,${ACCENT},${ACCENT_HI})`,\n                    opacity: morph,\n                  }}\n                />\n                {/* 柱端数值 */}\n                <span\n                  style={{\n                    position: 'absolute',\n                    top: '50%',\n                    transform: 'translateY(-50%)',\n                    color: ACCENT_HI,\n                    fontSize: 10,\n                    left: `calc(${wPct}% + 8px)`,\n                    opacity: morph,\n                  }}\n                >\n                  {Math.round(w * 420 * grow)}K\n                </span>\n              </div>\n            </div>\n          );\n        })}\n        {/* 头部信息条 */}\n        <div\n          style={{\n            position: 'absolute',\n            top: 20,\n            left: 60,\n            fontWeight: 600,\n            fontSize: 12,\n            fontFamily: '\"SF Mono\",Courier,monospace', // 同上：Courier 兜底\n            letterSpacing: 1,\n            transform: `translateY(${-30 + headIn * 30}px)`,\n            opacity: headIn,\n          }}\n        >\n          <span style={{ color: '#e8eaf0', fontWeight: 700 }}>METRICS</span>\n          {NBSP2}\n          <span style={{ color: '#67d17c' }}>● LIVE</span>\n          {NBSP2}\n          <span style={{ color: '#8b91a3' }}>TOTAL 875K{NBSP2}AVG 1.02M</span>\n        </div>\n      </div>\n    </DesignStage>\n  );\n};\n\n\n"
}