| 5 | import { cn } from '@/lib/utils' |
| 6 | |
| 7 | export function BackgroundBeams({ className }: { className?: string }) { |
| 8 | const containerRef = useRef<HTMLDivElement>(null) |
| 9 | |
| 10 | useEffect(() => { |
| 11 | const container = containerRef.current |
| 12 | if (!container) return |
| 13 | |
| 14 | const updateMousePosition = (ev: MouseEvent) => { |
| 15 | if (!container) return |
| 16 | const rect = container.getBoundingClientRect() |
| 17 | const x = ev.clientX - rect.left |
| 18 | const y = ev.clientY - rect.top |
| 19 | container.style.setProperty('--beam-x', `${x}px`) |
| 20 | container.style.setProperty('--beam-y', `${y}px`) |
| 21 | } |
| 22 | |
| 23 | window.addEventListener('mousemove', updateMousePosition) |
| 24 | return () => window.removeEventListener('mousemove', updateMousePosition) |
| 25 | }, []) |
| 26 | |
| 27 | return ( |
| 28 | <div |
| 29 | ref={containerRef} |
| 30 | className={cn( |
| 31 | 'absolute inset-0 overflow-hidden [--beam-x:50%] [--beam-y:50%]', |
| 32 | className, |
| 33 | )} |
| 34 | > |
| 35 | {/* Mouse-following glow */} |
| 36 | <div |
| 37 | className="absolute left-[--beam-x] top-[--beam-y] h-px w-px" |
| 38 | style={{ |
| 39 | boxShadow: |
| 40 | '0 0 150px 80px rgba(124, 255, 63, 0.08), 0 0 300px 150px rgba(124, 255, 63, 0.04)', |
| 41 | transform: 'translate(-50%, -50%)', |
| 42 | }} |
| 43 | /> |
| 44 | </div> |
| 45 | ) |
| 46 | } |