{"version":1,"id":"flow-shader-background","framework":"next","kind":"block","files":[{"path":"src/blocks/gfa/flow-shader-background.tsx","content":"\"use client\";\n\nimport { Canvas, useFrame, useThree } from \"@react-three/fiber\";\nimport { useMemo, useRef } from \"react\";\nimport * as THREE from \"three\";\nimport { cn } from \"@/lib/utils\";\n\nconst vertexShader = /* glsl */ `\nvarying vec2 vUv;\n\nvoid main() {\n  vUv = uv;\n  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst fragmentShader = /* glsl */ `\nprecision highp float;\n\nuniform float uTime;\nuniform vec2 uResolution;\nuniform vec3 uColor1;\nuniform vec3 uColor2;\nuniform vec3 uColor3;\nuniform float uSpeed;\nuniform float uScale;\nuniform float uWarpStrength;\n\nvarying vec2 vUv;\n\nfloat hash(vec2 p) {\n  return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n}\n\nfloat noise(vec2 p) {\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);\n\n  float a = hash(i);\n  float b = hash(i + vec2(1.0, 0.0));\n  float c = hash(i + vec2(0.0, 1.0));\n  float d = hash(i + vec2(1.0, 1.0));\n\n  return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\n\nfloat fbm(vec2 p) {\n  float v = 0.0;\n  float a = 0.5;\n  mat2 rot = mat2(0.8, 0.6, -0.6, 0.8);\n\n  for (int i = 0; i < 4; i++) {\n    v += a * noise(p);\n    p = rot * p * 2.02;\n    a *= 0.5;\n  }\n  return v;\n}\n\nvoid main() {\n  vec2 uv = (gl_FragCoord.xy - 0.5 * uResolution.xy) / min(uResolution.x, uResolution.y);\n  uv *= uScale;\n\n  float t = uTime * uSpeed;\n\n  vec2 q = vec2(\n    fbm(uv + vec2(0.0, 0.0) + t * 0.15),\n    fbm(uv + vec2(5.2, 1.3) + t * 0.12)\n  );\n\n  vec2 r = vec2(\n    fbm(uv + q * uWarpStrength + vec2(1.7, 9.2) + t * 0.18),\n    fbm(uv + q * uWarpStrength + vec2(8.3, 2.8) + t * 0.14)\n  );\n\n  float f = fbm(uv + r * uWarpStrength);\n\n  vec3 color = mix(uColor1, uColor2, smoothstep(0.2, 0.65, f));\n  color = mix(color, uColor3, smoothstep(0.55, 0.85, f) * 0.7);\n\n  float vignette = 1.0 - smoothstep(0.6, 1.5, length(uv * 0.7));\n  color *= vignette * 0.92 + 0.08;\n\n  color += (hash(uv + t) - 0.5) * 0.015;\n\n  gl_FragColor = vec4(color, 1.0);\n}\n`;\n\nexport type FlowShaderBackgroundProps = {\n  className?: string;\n  color1?: string;\n  color2?: string;\n  color3?: string;\n  speed?: number;\n  scale?: number;\n  warpStrength?: number;\n};\n\nfunction FlowShaderMesh({\n  color1 = \"#05050a\",\n  color2 = \"#0f172a\",\n  color3 = \"#22d3ee\",\n  speed = 0.28,\n  scale = 1.8,\n  warpStrength = 1.35,\n}: Omit<FlowShaderBackgroundProps, \"className\">) {\n  const materialRef = useRef<THREE.ShaderMaterial>(null);\n  const { size, viewport, gl } = useThree();\n\n  const uniforms = useMemo(\n    () => ({\n      uTime: { value: 0 },\n      uResolution: { value: new THREE.Vector2(1, 1) },\n      uColor1: { value: new THREE.Color(color1) },\n      uColor2: { value: new THREE.Color(color2) },\n      uColor3: { value: new THREE.Color(color3) },\n      uSpeed: { value: speed },\n      uScale: { value: scale },\n      uWarpStrength: { value: warpStrength },\n    }),\n    [],\n  );\n\n  useFrame((state) => {\n    const mat = materialRef.current;\n    if (!mat) return;\n    const dpr = gl.getPixelRatio();\n    mat.uniforms.uTime.value = state.clock.elapsedTime;\n    mat.uniforms.uResolution.value.set(size.width * dpr, size.height * dpr);\n    mat.uniforms.uColor1.value.set(color1);\n    mat.uniforms.uColor2.value.set(color2);\n    mat.uniforms.uColor3.value.set(color3);\n    mat.uniforms.uSpeed.value = speed;\n    mat.uniforms.uScale.value = scale;\n    mat.uniforms.uWarpStrength.value = warpStrength;\n  });\n\n  return (\n    <mesh scale={[viewport.width, viewport.height, 1]}>\n      <planeGeometry args={[1, 1]} />\n      <shaderMaterial\n        ref={materialRef}\n        vertexShader={vertexShader}\n        fragmentShader={fragmentShader}\n        uniforms={uniforms}\n        depthWrite={false}\n      />\n    </mesh>\n  );\n}\n\nexport function FlowShaderBackground({\n  className,\n  ...props\n}: FlowShaderBackgroundProps) {\n  return (\n    <div\n      data-slot=\"flow-shader-background\"\n      className={cn(\"overflow-hidden bg-[#05050a]\", className)}\n      aria-hidden\n    >\n      <Canvas\n        dpr={[1, 1.75]}\n        gl={{\n          antialias: false,\n          alpha: false,\n          powerPreference: \"high-performance\",\n        }}\n        camera={{ position: [0, 0, 1], fov: 50, near: 0.1, far: 10 }}\n        style={{ width: \"100%\", height: \"100%\", display: \"block\" }}\n      >\n        <FlowShaderMesh {...props} />\n      </Canvas>\n    </div>\n  );\n}\n\n/** @deprecated Prefer FlowShaderBackground */\nexport const GFAFlowBackground = FlowShaderBackground;\n\nexport { FlowShaderBackground as FlowShaderBackgroundBlock };\n"}],"meta":{"studioName":"GFA Development & Design Studio","siteUrl":"https://ui.gkhn.dev"}}