const canvas = document.getElementById('matrix-rain'); if (canvas && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) { const ctx = canvas.getContext('2d'); const chars = 'アカサタナハマヤラワ01アイウエオカキク'; const fontSize = 16; let columns = 0; let drops = []; let frameCount = 0; function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; columns = Math.floor(canvas.width / fontSize); drops = new Array(columns).fill(0).map(() => Math.random() * -50); } function draw() { ctx.fillStyle = 'rgba(3, 5, 3, 0.12)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.font = `${fontSize}px monospace`; for (let i = 0; i < drops.length; i++) { const text = chars[Math.floor(Math.random() * chars.length)]; const isHead = Math.random() > 0.92; ctx.shadowColor = 'rgba(100, 255, 160, 1)'; ctx.shadowBlur = isHead ? 12 : 2; ctx.fillStyle = isHead ? 'rgba(210, 255, 225, 1)' : 'rgba(80, 255, 140, 1)'; ctx.fillText(text, i * fontSize, drops[i] * fontSize); if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) { drops[i] = 0; } drops[i] += 0.4; } ctx.shadowBlur = 0; } function tick() { frameCount++; if (frameCount % 2 === 0) draw(); requestAnimationFrame(tick); } resize(); window.addEventListener('resize', resize); requestAnimationFrame(tick); }