{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "LiquidChrome-TS-TW",
	"title": "LiquidChrome",
	"description": "Liquid metallic chrome shader with flowing reflective surface.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:component",
			"path": "LiquidChrome/LiquidChrome.tsx",
			"content": "import React, { useRef, useEffect } from 'react';\nimport { Renderer, Program, Mesh, Triangle } from 'ogl';\n\ninterface LiquidChromeProps extends React.HTMLAttributes<HTMLDivElement> {\n  baseColor?: [number, number, number];\n  speed?: number;\n  amplitude?: number;\n  frequencyX?: number;\n  frequencyY?: number;\n  interactive?: boolean;\n}\n\nexport const LiquidChrome: React.FC<LiquidChromeProps> = ({\n  baseColor = [0.1, 0.1, 0.1],\n  speed = 0.2,\n  amplitude = 0.5,\n  frequencyX = 3,\n  frequencyY = 2,\n  interactive = true,\n  ...props\n}) => {\n  const containerRef = useRef<HTMLDivElement | null>(null);\n\n  useEffect(() => {\n    if (!containerRef.current) return;\n\n    const container = containerRef.current;\n    const renderer = new Renderer({ antialias: true });\n    const gl = renderer.gl;\n    gl.clearColor(1, 1, 1, 1);\n\n    const vertexShader = `\n      attribute vec2 position;\n      attribute vec2 uv;\n      varying vec2 vUv;\n      void main() {\n        vUv = uv;\n        gl_Position = vec4(position, 0.0, 1.0);\n      }\n    `;\n\n    const fragmentShader = `\n      precision highp float;\n      uniform float uTime;\n      uniform vec3 uResolution;\n      uniform vec3 uBaseColor;\n      uniform float uAmplitude;\n      uniform float uFrequencyX;\n      uniform float uFrequencyY;\n      uniform vec2 uMouse;\n      varying vec2 vUv;\n\n      vec4 renderImage(vec2 uvCoord) {\n          vec2 fragCoord = uvCoord * uResolution.xy;\n          vec2 uv = (2.0 * fragCoord - uResolution.xy) / min(uResolution.x, uResolution.y);\n\n          for (float i = 1.0; i < 10.0; i++){\n              uv.x += uAmplitude / i * cos(i * uFrequencyX * uv.y + uTime + uMouse.x * 3.14159);\n              uv.y += uAmplitude / i * cos(i * uFrequencyY * uv.x + uTime + uMouse.y * 3.14159);\n          }\n\n          vec2 diff = (uvCoord - uMouse);\n          float dist = length(diff);\n          float falloff = exp(-dist * 20.0);\n          float ripple = sin(10.0 * dist - uTime * 2.0) * 0.03;\n          uv += (diff / (dist + 0.0001)) * ripple * falloff;\n\n          vec3 color = uBaseColor / abs(sin(uTime - uv.y - uv.x));\n          return vec4(color, 1.0);\n      }\n\n      void main() {\n          vec4 col = vec4(0.0);\n          int samples = 0;\n          for (int i = -1; i <= 1; i++){\n              for (int j = -1; j <= 1; j++){\n                  vec2 offset = vec2(float(i), float(j)) * (1.0 / min(uResolution.x, uResolution.y));\n                  col += renderImage(vUv + offset);\n                  samples++;\n              }\n          }\n          gl_FragColor = col / float(samples);\n      }\n    `;\n\n    const geometry = new Triangle(gl);\n    const program = new Program(gl, {\n      vertex: vertexShader,\n      fragment: fragmentShader,\n      uniforms: {\n        uTime: { value: 0 },\n        uResolution: {\n          value: new Float32Array([gl.canvas.width, gl.canvas.height, gl.canvas.width / gl.canvas.height])\n        },\n        uBaseColor: { value: new Float32Array(baseColor) },\n        uAmplitude: { value: amplitude },\n        uFrequencyX: { value: frequencyX },\n        uFrequencyY: { value: frequencyY },\n        uMouse: { value: new Float32Array([0, 0]) }\n      }\n    });\n    const mesh = new Mesh(gl, { geometry, program });\n\n    function resize() {\n      const scale = 1;\n      renderer.setSize(container.offsetWidth * scale, container.offsetHeight * scale);\n      const resUniform = program.uniforms.uResolution.value as Float32Array;\n      resUniform[0] = gl.canvas.width;\n      resUniform[1] = gl.canvas.height;\n      resUniform[2] = gl.canvas.width / gl.canvas.height;\n    }\n    window.addEventListener('resize', resize);\n    resize();\n\n    function handleMouseMove(event: MouseEvent) {\n      const rect = container.getBoundingClientRect();\n      const x = (event.clientX - rect.left) / rect.width;\n      const y = 1 - (event.clientY - rect.top) / rect.height;\n      const mouseUniform = program.uniforms.uMouse.value as Float32Array;\n      mouseUniform[0] = x;\n      mouseUniform[1] = y;\n    }\n\n    function handleTouchMove(event: TouchEvent) {\n      if (event.touches.length > 0) {\n        const touch = event.touches[0];\n        const rect = container.getBoundingClientRect();\n        const x = (touch.clientX - rect.left) / rect.width;\n        const y = 1 - (touch.clientY - rect.top) / rect.height;\n        const mouseUniform = program.uniforms.uMouse.value as Float32Array;\n        mouseUniform[0] = x;\n        mouseUniform[1] = y;\n      }\n    }\n\n    if (interactive) {\n      container.addEventListener('mousemove', handleMouseMove);\n      container.addEventListener('touchmove', handleTouchMove);\n    }\n\n    let animationId: number;\n    function update(t: number) {\n      animationId = requestAnimationFrame(update);\n      program.uniforms.uTime.value = t * 0.001 * speed;\n      renderer.render({ scene: mesh });\n    }\n    animationId = requestAnimationFrame(update);\n\n    container.appendChild(gl.canvas);\n\n    return () => {\n      cancelAnimationFrame(animationId);\n      window.removeEventListener('resize', resize);\n      if (interactive) {\n        container.removeEventListener('mousemove', handleMouseMove);\n        container.removeEventListener('touchmove', handleTouchMove);\n      }\n      if (gl.canvas.parentElement) {\n        gl.canvas.parentElement.removeChild(gl.canvas);\n      }\n      gl.getExtension('WEBGL_lose_context')?.loseContext();\n    };\n  }, [baseColor, speed, amplitude, frequencyX, frequencyY, interactive]);\n\n  return <div ref={containerRef} className=\"w-full h-full\" {...props} />;\n};\n\nexport default LiquidChrome;\n"
		}
	],
	"registryDependencies": [],
	"dependencies": [
		"ogl@^1.0.11"
	]
}