{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "ai-generation-canvas", "title": "AI Generation Canvas", "description": "A prompt input transforms into a header, then a skeleton dashboard flips into populated cards.", "dependencies": [ "remotion" ], "files": [ { "path": "registry/remocn/ai-generation-canvas/index.tsx", "content": "\"use client\";\n\nimport { interpolate, spring, useCurrentFrame, useVideoConfig } from \"remotion\";\n\nexport interface AIGenerationCanvasProps {\n prompt?: string;\n accentColor?: string;\n cardCount?: number;\n speed?: number;\n className?: string;\n}\n\nconst FONT_FAMILY =\n \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\";\n\nfunction MiniBarChart({ accentColor }: { accentColor: string }) {\n const bars = [0.4, 0.7, 0.55, 0.85, 0.5, 0.95, 0.65];\n return (\n \n {bars.map((h, i) => (\n \n ))}\n \n );\n}\n\nfunction MiniRows() {\n return (\n \n {[0.9, 0.7, 0.85, 0.6].map((w, i) => (\n \n ))}\n \n );\n}\n\nfunction StatBlock({\n accentColor,\n value,\n}: {\n accentColor: string;\n value: string;\n}) {\n return (\n
\n \n {value}\n
\n \n +12.4% this week\n \n \n );\n}\n\nfunction CardContent({\n index,\n accentColor,\n}: {\n index: number;\n accentColor: string;\n}) {\n const titles = [\n \"Revenue\",\n \"Active Users\",\n \"Sessions\",\n \"Conversion\",\n \"Retention\",\n \"Latency\",\n ];\n const values = [\"$48.2k\", \"12,840\", \"9.1k\", \"3.8%\", \"76%\", \"142ms\"];\n const variant = index % 3;\n return (\n
\n \n {titles[index % titles.length]}\n
\n {variant === 0 ? (\n <>\n \n \n \n ) : variant === 1 ? (\n <>\n \n \n \n ) : (\n <>\n \n \n \n )}\n \n );\n}\n\nexport function AIGenerationCanvas({\n prompt = \"Generate a dashboard\",\n accentColor = \"#7c3aed\",\n cardCount = 4,\n speed = 1,\n className,\n}: AIGenerationCanvasProps) {\n const frame = useCurrentFrame() * speed;\n const { fps } = useVideoConfig();\n\n // Phase boundaries\n const P1_END = 40;\n const P2_END = 70;\n const P3_END = 100;\n\n // Phase 1: typewriter\n const charCount = Math.floor(\n interpolate(frame, [4, P1_END - 2], [0, prompt.length], {\n extrapolateLeft: \"clamp\",\n extrapolateRight: \"clamp\",\n }),\n );\n const typedText = prompt.substring(0, charCount);\n const cursorVisible = Math.floor(frame / 12) % 2 === 0;\n\n // Phase 2: input -> header transform\n const transformProgress = spring({\n frame: frame - P1_END,\n fps,\n config: { mass: 1, damping: 16, stiffness: 110 },\n durationInFrames: 30,\n });\n\n // Centered input dimensions\n const inputCenteredW = 640;\n const inputCenteredH = 80;\n const headerW = 1200;\n const headerH = 56;\n const inputW = interpolate(\n transformProgress,\n [0, 1],\n [inputCenteredW, headerW],\n );\n const inputH = interpolate(\n transformProgress,\n [0, 1],\n [inputCenteredH, headerH],\n );\n const inputTop = interpolate(transformProgress, [0, 1], [320, 40]);\n const inputRadius = interpolate(transformProgress, [0, 1], [16, 12]);\n const inputFontSize = interpolate(transformProgress, [0, 1], [24, 14]);\n\n // Phase 3: skeleton fade\n const skeletonOpacity = interpolate(frame, [P2_END, P3_END], [0, 1], {\n extrapolateLeft: \"clamp\",\n extrapolateRight: \"clamp\",\n });\n\n // Shimmer position\n const shimmerPos = ((frame * 1.5) % 200) - 50;\n\n // Phase 4: card flip reveal (after frame 100)\n const cards = Array.from({ length: cardCount });\n\n return (\n \n {/* subtle grid backdrop */}\n \n\n {/* Skeleton + content cards grid (Phase 3 onward) */}\n {frame > P2_END && (\n \n {cards.map((_, i) => {\n const cardStart = P3_END + i * 8;\n const flipProgress = spring({\n frame: frame - cardStart,\n fps,\n config: { mass: 0.9, damping: 14, stiffness: 100 },\n durationInFrames: 30,\n });\n const rotation = interpolate(flipProgress, [0, 1], [0, 180]);\n const showSkeleton = rotation < 90;\n\n return (\n \n \n {/* Skeleton face */}\n \n {/* shimmer overlay */}\n \n
\n \n \n \n
\n \n {/* Content face */}\n \n \n \n \n \n );\n })}\n \n )}\n\n {/* Prompt input — centered then transforms to header */}\n \n {/* sparkle icon */}\n \n \n \n \n \n \n {typedText}\n {frame < P1_END && cursorVisible && (\n \n )}\n \n {transformProgress > 0.6 && (\n \n \n \n Generating\n \n \n )}\n \n \n );\n}\n", "type": "registry:component", "target": "components/remocn/ai-generation-canvas.tsx" } ], "type": "registry:component" }