{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "glass-code-walk",
  "title": "Glass Code Walk",
  "description": "A camera that scans a glass code block top to bottom as it types, then pulls back to a centered hold.",
  "dependencies": ["remotion"],
  "registryDependencies": ["@remocn/glass-code-block"],
  "files": [
    {
      "path": "registry/remocn/glass-code-walk/index.tsx",
      "content": "\"use client\";\n\nimport { AbsoluteFill, Easing, interpolate, useCurrentFrame } from \"remotion\";\n\nimport { GlassCodeBlock } from \"@/components/remocn/glass-code-block\";\n\nexport interface GlassCodeWalkProps {\n  code?: string;\n  title?: string;\n  width?: number;\n  height?: number;\n  fontSize?: number;\n  staggerFrames?: number;\n  zoom?: number;\n  speed?: number;\n  className?: string;\n}\n\nconst STAGE_WIDTH = 1280;\nconst STAGE_HEIGHT = 720;\nconst RING = 1;\nconst CHROME_HEIGHT = 40;\nconst BODY_PADDING_TOP = 20;\nconst BODY_PADDING_LEFT = 24;\nconst LINE_GAP = 4;\nconst ANCHOR_SCREEN_X = 110;\nconst TARGET_Y = 360;\nconst PULL_BACK_FRAMES = 24;\n\nconst DEFAULT_CODE = `import { AbsoluteFill } from \"remotion\";\nimport { Typewriter } from \"@/components/remocn\";\n\nexport function Intro() {\n  return (\n    <AbsoluteFill>\n      <Typewriter text=\"Ship it\" />\n    </AbsoluteFill>\n  );\n}`;\n\nexport function GlassCodeWalk({\n  code = DEFAULT_CODE,\n  title = \"scene.tsx\",\n  width = 880,\n  height = 420,\n  fontSize = 18,\n  staggerFrames = 10,\n  zoom = 2.6,\n  speed = 1,\n  className,\n}: GlassCodeWalkProps) {\n  const frame = useCurrentFrame();\n\n  const lines = code.split(\"\\n\");\n  const lineCount = lines.length;\n\n  const blockLeft = (STAGE_WIDTH - width) / 2;\n  const blockTop = (STAGE_HEIGHT - height) / 2;\n  const bodyTop = blockTop + RING + CHROME_HEIGHT + BODY_PADDING_TOP;\n\n  const lineHeightOf = (line: string) =>\n    line.trim() === \"\" ? fontSize * 0.8 : fontSize * 1.55;\n\n  const lineCenters: number[] = [];\n  let walk = bodyTop;\n  for (const line of lines) {\n    const h = lineHeightOf(line);\n    lineCenters.push(walk + h / 2);\n    walk += h + LINE_GAP;\n  }\n\n  const anchorWorldX = blockLeft + RING + BODY_PADDING_LEFT;\n  const scanStagger = staggerFrames / speed;\n  const scanEnd = (lineCount - 1) * scanStagger;\n\n  const linePosition = interpolate(frame, [0, scanEnd], [0, lineCount - 1], {\n    extrapolateLeft: \"clamp\",\n    extrapolateRight: \"clamp\",\n  });\n  const lower = Math.floor(linePosition);\n  const upper = Math.min(lower + 1, lineCount - 1);\n  const trackedY =\n    lineCenters[lower] +\n    (lineCenters[upper] - lineCenters[lower]) * (linePosition - lower);\n\n  const pinnedX = ANCHOR_SCREEN_X - zoom * anchorWorldX;\n  const pinnedY = TARGET_Y - zoom * trackedY;\n\n  const pullBack = interpolate(\n    frame,\n    [scanEnd, scanEnd + PULL_BACK_FRAMES / speed],\n    [0, 1],\n    {\n      extrapolateLeft: \"clamp\",\n      extrapolateRight: \"clamp\",\n      easing: Easing.inOut(Easing.cubic),\n    },\n  );\n\n  const scale = zoom + pullBack * (1 - zoom);\n  const tx = (1 - pullBack) * pinnedX;\n  const ty = (1 - pullBack) * pinnedY;\n\n  return (\n    <AbsoluteFill className={className} style={{ overflow: \"hidden\" }}>\n      <div\n        style={{\n          position: \"absolute\",\n          left: 0,\n          top: 0,\n          width: STAGE_WIDTH,\n          height: STAGE_HEIGHT,\n          translate: `${tx}px ${ty}px`,\n          scale: `${scale}`,\n          transformOrigin: \"0 0\",\n        }}\n      >\n        <GlassCodeBlock\n          code={code}\n          title={title}\n          width={width}\n          height={height}\n          fontSize={fontSize}\n          staggerFrames={staggerFrames}\n          speed={speed}\n        />\n      </div>\n    </AbsoluteFill>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/glass-code-walk.tsx"
    }
  ],
  "type": "registry:component"
}
