import { useEffect, useRef } from 'react'; interface MatrixRainProps { color?: string; } const MatrixRain = ({ color = '#00FF00' }: MatrixRainProps) => { const canvasRef = useRef(null); const colorRef = useRef(color); useEffect(() => { colorRef.current = color; }, [color]); useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext('2d'); if (!ctx) return; const fontSize = 16; let columns: number; let rainDrops: number[] = []; const katakana = 'アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッン'; const latin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const nums = '0123456789'; const alphabet = katakana + latin + nums; const init = () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; columns = Math.floor(canvas.width / fontSize); rainDrops = []; for (let x = 0; x < columns; x++) { rainDrops[x] = Math.random() * canvas.height / fontSize; } }; init(); const draw = () => { ctx.fillStyle = 'rgba(0, 0, 0, 0.04)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = colorRef.current; ctx.font = `${fontSize}px monospace`; for (let i = 0; i < rainDrops.length; i++) { const text = alphabet.charAt(Math.floor(Math.random() * alphabet.length)); ctx.fillText(text, i * fontSize, rainDrops[i] * fontSize); if (rainDrops[i] * fontSize > canvas.height && Math.random() > 0.975) { rainDrops[i] = 0; } rainDrops[i]++; } }; const interval = setInterval(draw, 30); const handleResize = () => init(); window.addEventListener('resize', handleResize); return () => { clearInterval(interval); window.removeEventListener('resize', handleResize); }; }, []); return ( ); }; export default MatrixRain;