// app/components/MatrixRain.tsx 'use client'; import { useEffect, useRef } from 'react'; interface MatrixRainProps { color?: string; fps?: number; } export default function MatrixRain({ color = '#84c0a0', fps = 15 }: MatrixRainProps) { const canvasRef = useRef(null); const lastWidth = useRef(0); useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext('2d'); if (!ctx) return; const fontSize = 16; let columns = 0; let drops: number[] = []; const setCanvasSize = () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight + 120; ctx.fillStyle = '#0d1117'; ctx.fillRect(0, 0, canvas.width, canvas.height); }; const initDrops = () => { columns = Math.floor(canvas.width / fontSize); drops = []; for (let x = 0; x < columns; x++) { drops[x] = Math.random() * -100; } }; lastWidth.current = window.innerWidth; setCanvasSize(); initDrops(); const draw = () => { ctx.fillStyle = 'rgba(13, 17, 23, 0.2)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.font = `bold ${fontSize}px monospace`; for (let i = 0; i < drops.length; i++) { const text = Math.random() > 0.5 ? '0' : '1'; ctx.fillStyle = color; ctx.fillText(text, i * fontSize, drops[i] * fontSize); if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) { drops[i] = 0; } drops[i]++; } }; const intervalId = setInterval(draw, 1000 / fps); const handleResize = () => { if (window.innerWidth !== lastWidth.current) { lastWidth.current = window.innerWidth; setCanvasSize(); initDrops(); } }; window.addEventListener('resize', handleResize); return () => { clearInterval(intervalId); window.removeEventListener('resize', handleResize); }; }, [color, fps]); return (
); }