{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "novatrix-background",
  "title": "novatrix-background",
  "description": "A novatrix background component.",
  "dependencies": [
    "react",
    "ogl"
  ],
  "files": [
    {
      "path": "registry/eldoraui/novatrix-background.tsx",
      "content": "\"use client\"\n\nimport { useEffect, useRef } from \"react\"\nimport { Color, Mesh, Program, Renderer, Triangle } from \"ogl\"\n\nconst vertexShader = `\nattribute vec2 uv;\nattribute vec2 position;\n\nvarying vec2 vUv;\n\nvoid main() {\n  vUv = uv;\n  gl_Position = vec4(position, 0, 1);\n}\n`\n\nconst fragmentShader = `\nprecision highp float;\n\nuniform float uTime;\nuniform vec3 uColor;\nuniform vec3 uResolution;\nuniform vec2 uMouse;\nuniform float uAmplitude;\nuniform float uSpeed;\n\nvarying vec2 vUv;\n\nvoid main() {\n  float mr = min(uResolution.x, uResolution.y);\n  vec2 uv = (vUv.xy * 2.0 - 1.0) * uResolution.xy / mr;\n\n  uv += (uMouse - vec2(0.5)) * uAmplitude;\n\n  float d = -uTime * 0.5 * uSpeed;\n  float a = 0.0;\n  for (float i = 0.0; i < 8.0; ++i) {\n    a += cos(i - d - a * uv.x);\n    d += sin(uv.y * i + a);\n  }\n  d += uTime * 0.5 * uSpeed;\n  vec3 col = vec3(cos(uv * vec2(d, a)) * 0.6 + 0.4, cos(a + d) * 0.5 + 0.5);\n  col = cos(col * cos(vec3(d, a, 2.5)) * 0.5 + 0.5) * uColor;\n  gl_FragColor = vec4(col, 1.0);\n}\n`\n\ninterface NovatrixProps {\n  color?: [number, number, number]\n  speed?: number\n  amplitude?: number\n  mouseReact?: boolean\n}\n\nexport default function Novatrix({\n  color = [1, 1, 1],\n  speed = 1.0,\n  amplitude = 0.1,\n  mouseReact = false,\n  ...rest\n}: NovatrixProps) {\n  const ctnDom = useRef<HTMLDivElement>(null)\n  const mousePos = useRef({ x: 0.5, y: 0.5 })\n\n  useEffect(() => {\n    if (!ctnDom.current) return\n    const ctn = ctnDom.current\n    const renderer = new Renderer()\n    const gl = renderer.gl\n    gl.clearColor(1, 1, 1, 1)\n\n    // eslint-disable-next-line prefer-const\n    let program: Program\n\n    function resize() {\n      const scale = 1\n      renderer.setSize(ctn.offsetWidth * scale, ctn.offsetHeight * scale)\n      if (program) {\n        program.uniforms.uResolution.value = new Color(\n          gl.canvas.width,\n          gl.canvas.height,\n          gl.canvas.width / gl.canvas.height\n        )\n      }\n    }\n    window.addEventListener(\"resize\", resize, false)\n    resize()\n\n    const geometry = new Triangle(gl)\n    program = new Program(gl, {\n      vertex: vertexShader,\n      fragment: fragmentShader,\n      uniforms: {\n        uTime: { value: 0 },\n        uColor: { value: new Color(...color) },\n        uResolution: {\n          value: new Color(\n            gl.canvas.width,\n            gl.canvas.height,\n            gl.canvas.width / gl.canvas.height\n          ),\n        },\n        uMouse: {\n          value: new Float32Array([mousePos.current.x, mousePos.current.y]),\n        },\n        uAmplitude: { value: amplitude },\n        uSpeed: { value: speed },\n      },\n    })\n\n    const mesh = new Mesh(gl, { geometry, program })\n    let animateId: number\n\n    function update(t: number) {\n      animateId = requestAnimationFrame(update)\n      program.uniforms.uTime.value = t * 0.001\n      renderer.render({ scene: mesh })\n    }\n    animateId = requestAnimationFrame(update)\n    ctn.appendChild(gl.canvas)\n\n    function handleMouseMove(e: MouseEvent) {\n      const rect = ctn.getBoundingClientRect()\n      const x = (e.clientX - rect.left) / rect.width\n      const y = 1.0 - (e.clientY - rect.top) / rect.height\n      mousePos.current = { x, y }\n      program.uniforms.uMouse.value[0] = x\n      program.uniforms.uMouse.value[1] = y\n    }\n    if (mouseReact) {\n      ctn.addEventListener(\"mousemove\", handleMouseMove)\n    }\n\n    return () => {\n      cancelAnimationFrame(animateId)\n      window.removeEventListener(\"resize\", resize)\n      if (mouseReact) {\n        ctn.removeEventListener(\"mousemove\", handleMouseMove)\n      }\n      ctn.removeChild(gl.canvas)\n      gl.getExtension(\"WEBGL_lose_context\")?.loseContext()\n    }\n  }, [color, speed, amplitude, mouseReact])\n\n  return <div ref={ctnDom} className=\"h-full w-full\" {...rest} />\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}