{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "Radar-JS-TW",
	"title": "Radar",
	"description": "Radar sweep effect with concentric rings, radial spokes, and a rotating beam.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:component",
			"path": "Radar/Radar.jsx",
			"content": "import { Renderer, Program, Mesh, Triangle } from 'ogl';\nimport { useEffect, useRef } from 'react';\n\nfunction hexToVec3(hex) {\n  const h = hex.replace('#', '');\n  return [\n    parseInt(h.slice(0, 2), 16) / 255,\n    parseInt(h.slice(2, 4), 16) / 255,\n    parseInt(h.slice(4, 6), 16) / 255\n  ];\n}\n\nconst vertexShader = `\nattribute vec2 uv;\nattribute vec2 position;\nvarying vec2 vUv;\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 uResolution;\nuniform float uSpeed;\nuniform float uScale;\nuniform float uRingCount;\nuniform float uSpokeCount;\nuniform float uRingThickness;\nuniform float uSpokeThickness;\nuniform float uSweepSpeed;\nuniform float uSweepWidth;\nuniform float uSweepLobes;\nuniform vec3 uColor;\nuniform vec3 uBgColor;\nuniform bool uLightMode;\nuniform float uFalloff;\nuniform float uBrightness;\nuniform vec2 uMouse;\nuniform float uMouseInfluence;\nuniform bool uEnableMouse;\n\n#define TAU 6.28318530718\n#define PI 3.14159265359\n\nvoid main() {\n  vec2 st = gl_FragCoord.xy / uResolution.xy;\n  st = st * 2.0 - 1.0;\n  st.x *= uResolution.x / uResolution.y;\n\n  if (uEnableMouse) {\n    vec2 mShift = (uMouse * 2.0 - 1.0);\n    mShift.x *= uResolution.x / uResolution.y;\n    st -= mShift * uMouseInfluence;\n  }\n\n  st *= uScale;\n\n  float dist = length(st);\n  float theta = atan(st.y, st.x);\n  float t = uTime * uSpeed;\n\n  float ringPhase = dist * uRingCount - t;\n  float ringDist = abs(fract(ringPhase) - 0.5);\n  float ringGlow = 1.0 - smoothstep(0.0, uRingThickness, ringDist);\n\n  float spokeAngle = abs(fract(theta * uSpokeCount / TAU + 0.5) - 0.5) * TAU / uSpokeCount;\n  float arcDist = spokeAngle * dist;\n  float spokeGlow = (1.0 - smoothstep(0.0, uSpokeThickness, arcDist)) * smoothstep(0.0, 0.1, dist);\n\n  float sweepPhase = t * uSweepSpeed;\n  float sweepBeam = pow(max(0.5 * sin(uSweepLobes * theta + sweepPhase) + 0.5, 0.0), uSweepWidth);\n\n  float fade = smoothstep(1.05, 0.85, dist) * pow(max(1.0 - dist, 0.0), uFalloff);\n\n  float intensity = max((ringGlow + spokeGlow + sweepBeam) * fade * uBrightness, 0.0);\n  vec3 signal = uColor * intensity;\n  vec3 col;\n  if (uLightMode) {\n    vec3 mapped = vec3(1.0) - exp(-max(signal, vec3(0.0)) * 1.45);\n    float energy = clamp(max(mapped.r, max(mapped.g, mapped.b)), 0.0, 1.0);\n    vec3 hue = mapped / max(energy, 0.0001);\n    hue = pow(clamp(hue, 0.0, 1.0), vec3(1.2));\n    col = mix(uBgColor, hue, smoothstep(0.015, 0.8, energy) * 0.96);\n    gl_FragColor = vec4(col, 1.0);\n  } else {\n    col = signal + uBgColor;\n    float alpha = clamp(length(col), 0.0, 1.0);\n    gl_FragColor = vec4(col, alpha);\n  }\n}\n`;\n\nexport default function Radar({\n  speed = 1.0,\n  scale = 0.5,\n  ringCount = 10.0,\n  spokeCount = 10.0,\n  ringThickness = 0.05,\n  spokeThickness = 0.01,\n  sweepSpeed = 1.0,\n  sweepWidth = 2.0,\n  sweepLobes = 1.0,\n  color = '#9f29ff',\n  backgroundColor = '#000000',\n  falloff = 2.0,\n  brightness = 1.0,\n  enableMouseInteraction = true,\n  mouseInfluence = 0.1,\n  lightMode = false\n}) {\n  const containerRef = useRef(null);\n\n  useEffect(() => {\n    if (!containerRef.current) return;\n    const container = containerRef.current;\n    const renderer = new Renderer({ alpha: true, premultipliedAlpha: false });\n    const gl = renderer.gl;\n    gl.clearColor(0, 0, 0, 0);\n\n    let program;\n    let currentMouse = [0.5, 0.5];\n    let targetMouse = [0.5, 0.5];\n\n    function handleMouseMove(e) {\n      const rect = gl.canvas.getBoundingClientRect();\n      targetMouse = [\n        (e.clientX - rect.left) / rect.width,\n        1.0 - (e.clientY - rect.top) / rect.height\n      ];\n    }\n\n    function handleMouseLeave() {\n      targetMouse = [0.5, 0.5];\n    }\n\n    function resize() {\n      renderer.setSize(container.offsetWidth, container.offsetHeight);\n      if (program) {\n        program.uniforms.uResolution.value = [gl.canvas.width, gl.canvas.height, gl.canvas.width / gl.canvas.height];\n      }\n    }\n    window.addEventListener('resize', resize);\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        uResolution: { value: [gl.canvas.width, gl.canvas.height, gl.canvas.width / gl.canvas.height] },\n        uSpeed: { value: speed },\n        uScale: { value: scale },\n        uRingCount: { value: ringCount },\n        uSpokeCount: { value: spokeCount },\n        uRingThickness: { value: ringThickness },\n        uSpokeThickness: { value: spokeThickness },\n        uSweepSpeed: { value: sweepSpeed },\n        uSweepWidth: { value: sweepWidth },\n        uSweepLobes: { value: sweepLobes },\n        uColor: { value: hexToVec3(color) },\n        uBgColor: { value: hexToVec3(backgroundColor) },\n        uLightMode: { value: lightMode },\n        uFalloff: { value: falloff },\n        uBrightness: { value: brightness },\n        uMouse: { value: new Float32Array([0.5, 0.5]) },\n        uMouseInfluence: { value: mouseInfluence },\n        uEnableMouse: { value: enableMouseInteraction }\n      }\n    });\n\n    const mesh = new Mesh(gl, { geometry, program });\n    container.appendChild(gl.canvas);\n\n    if (enableMouseInteraction) {\n      gl.canvas.addEventListener('mousemove', handleMouseMove);\n      gl.canvas.addEventListener('mouseleave', handleMouseLeave);\n    }\n\n    let animationFrameId;\n\n    function update(time) {\n      animationFrameId = requestAnimationFrame(update);\n      program.uniforms.uTime.value = time * 0.001;\n\n      if (enableMouseInteraction) {\n        currentMouse[0] += 0.05 * (targetMouse[0] - currentMouse[0]);\n        currentMouse[1] += 0.05 * (targetMouse[1] - currentMouse[1]);\n        program.uniforms.uMouse.value[0] = currentMouse[0];\n        program.uniforms.uMouse.value[1] = currentMouse[1];\n      } else {\n        program.uniforms.uMouse.value[0] = 0.5;\n        program.uniforms.uMouse.value[1] = 0.5;\n      }\n\n      renderer.render({ scene: mesh });\n    }\n    animationFrameId = requestAnimationFrame(update);\n\n    return () => {\n      cancelAnimationFrame(animationFrameId);\n      window.removeEventListener('resize', resize);\n      if (enableMouseInteraction) {\n        gl.canvas.removeEventListener('mousemove', handleMouseMove);\n        gl.canvas.removeEventListener('mouseleave', handleMouseLeave);\n      }\n      container.removeChild(gl.canvas);\n      gl.getExtension('WEBGL_lose_context')?.loseContext();\n    };\n  }, [speed, scale, ringCount, spokeCount, ringThickness, spokeThickness, sweepSpeed, sweepWidth, sweepLobes, color, backgroundColor, falloff, brightness, enableMouseInteraction, mouseInfluence, lightMode]);\n\n  return <div ref={containerRef} className=\"w-full h-full\" />;\n}\n"
		}
	],
	"registryDependencies": [],
	"dependencies": [
		"ogl@^1.0.11"
	]
}