{ "name": "hero-geometric", "type": "registry:ui", "dependencies": [ "framer-motion", "lucide-react", "three", "@react-three/fiber", "@react-three/drei" ], "registryDependencies": [], "description": "A geometric hero section with a shader background and premium typography.", "files": [ { "path": "components/ui/hero-geometric.tsx", "content": "\"use client\";\n\n/* eslint-disable react/no-unknown-property */\nimport { useRef, useMemo } from \"react\";\nimport { Canvas, useFrame, ThreeElements } from \"@react-three/fiber\";\nimport * as THREE from \"three\";\nimport { motion } from \"framer-motion\";\n\nimport { cn } from \"../lib/utils\";\n\n/* eslint-disable @typescript-eslint/no-namespace */\ndeclare module \"react\" {\n namespace JSX {\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n interface IntrinsicElements extends ThreeElements { }\n }\n}\n/* eslint-enable @typescript-eslint/no-namespace */\n\n// --- Shader Code ---\nconst vertexShader = `\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst fragmentShader = `\nuniform float uTime;\nuniform vec2 uResolution;\nuniform vec3 uColor1;\nuniform vec3 uColor2;\nvarying vec2 vUv;\n\nvec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }\n\nfloat snoise(vec2 v){\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy) );\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n + i.x + vec3(0.0, i1.x, 1.0 ));\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\nfloat bayerDither4x4(vec2 uv) {\n int x = int(mod(uv.x, 4.0));\n int y = int(mod(uv.y, 4.0));\n \n int matrix[16];\n matrix[0] = 0; matrix[1] = 8; matrix[2] = 2; matrix[3] = 10;\n matrix[4] = 12; matrix[5] = 4; matrix[6] = 14; matrix[7] = 6;\n matrix[8] = 3; matrix[9] = 11; matrix[10] = 1; matrix[11] = 9;\n matrix[12] = 15; matrix[13] = 7; matrix[14] = 13; matrix[15] = 5;\n \n return float(matrix[y * 4 + x]) / 16.0;\n}\n\nvoid main() {\n vec2 uv = vUv;\n vec2 coord = gl_FragCoord.xy;\n \n // Enhanced noise with time\n float noise = snoise(uv * 1.5 + vec2(uTime * 0.05, uTime * 0.03)) * 0.25;\n \n // Diagonal gradient from bottom-left to top-right\n float diagonal = (uv.x + uv.y) * 0.5;\n \n // Combine for gradient - emphasize corners\n float gradient = diagonal * 1.2 + noise;\n \n // Interpolate colors based on gradient\n vec3 deepBlue = uColor1;\n vec3 paleBlue = uColor2;\n vec3 softBlue = mix(deepBlue, paleBlue, 0.33);\n vec3 lightBlue = mix(deepBlue, paleBlue, 0.66);\n \n // Map to colors with more distinct steps\n vec3 color;\n if (gradient < 0.3) {\n color = deepBlue;\n } else if (gradient < 0.55) {\n color = softBlue;\n } else if (gradient < 0.8) {\n color = lightBlue;\n } else {\n color = paleBlue;\n }\n \n // Enhanced dithering at boundaries\n float dither = bayerDither4x4(coord);\n float threshold = fract(gradient * 4.0);\n \n if (gradient < 0.3 && threshold > dither * 0.5) {\n color = softBlue;\n } else if (gradient >= 0.3 && gradient < 0.55 && threshold > dither * 0.5) {\n color = lightBlue;\n } else if (gradient >= 0.55 && gradient < 0.8 && threshold > dither * 0.5) {\n color = paleBlue;\n }\n \n // Softer fade to white - only at extreme bottom-left\n vec2 cornerDist = vec2(uv.x, uv.y);\n float fadeMask = smoothstep(0.0, 0.25, length(cornerDist));\n color = mix(vec3(1.0), color, fadeMask);\n \n // Add subtle vignette to emphasize corners\n float vignette = smoothstep(1.2, 0.3, length(uv - 0.5));\n color = mix(color, color * 0.95, (1.0 - vignette) * 0.3);\n \n gl_FragColor = vec4(color, 1.0);\n}\n`;\n\nconst GradientPlane = ({\n color1,\n color2,\n speed = 1\n}: {\n color1: string;\n color2: string;\n speed?: number\n}) => {\n const meshRef = useRef(null);\n const uniforms = useMemo(\n () => ({\n uTime: { value: 0 },\n uResolution: { value: new THREE.Vector2(1000, 1000) },\n uColor1: { value: new THREE.Color(color1) },\n uColor2: { value: new THREE.Color(color2) },\n }),\n [color1, color2]\n );\n\n useFrame((state) => {\n const { clock, size } = state;\n uniforms.uTime.value = clock.getElapsedTime() * speed;\n uniforms.uResolution.value.set(size.width, size.height);\n uniforms.uColor1.value.set(color1);\n uniforms.uColor2.value.set(color2);\n });\n\n return (\n \n \n \n \n );\n};\n\n// --- Main Component ---\n\ninterface HeroGeometricProps {\n title1?: string;\n title2?: string;\n description?: string;\n className?: string; // Explicitly included\n color1?: string;\n color2?: string;\n speed?: number;\n}\n\nexport default function HeroGeometric({\n title1,\n title2,\n description,\n color1 = \"#3B82F6\", // Default soft blue\n color2 = \"#F0F9FF\", // Default pale blue\n speed = 1,\n className,\n}: HeroGeometricProps) {\n return (\n \n {/* Background Shader */}\n
\n \n \n \n
\n\n {/* Content */}\n {(title1 || title2 || description) && (\n
\n
\n {/* Headline */}\n
\n {title1 && (\n
\n \n \n {title1}\n \n \n
\n )}\n {title2 && (\n
\n \n {title2}\n \n
\n )}\n
\n\n {/* Subheadline */}\n {description && (\n
\n \n {description}\n \n
\n )}\n
\n
\n )}\n \n );\n}\n", "type": "registry:ui" } ] }