Components
Loading preview...
import React, { useEffect, useRef } from 'react';
/**
* MatrixBackground Component
* Renders a high-performance Digital Rain background using HTML5 Canvas.
*/
const MatrixBackground: React.FC = () => {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let width: number;
let height: number;
let columns: number;
let drops: number[] = [];
const fontSize = 16;
const characters = "アカサタナハマヤラワガザダバパイキシチニヒミリヰギジヂビピウクスツヌフムユルグズヅブプエケセテネヘメレヱゲゼデベペオコソトノホモヨロヲゴゾドボポ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const initCanvas = () => {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
columns = Math.floor(width / fontSize);
drops = [];
for (let i = 0; i < columns; i++) {
// Initialize drops with random negative values to create a natural staggered entrance
drops[i] = Math.random() * -100;
}
};
const draw = () => {
// Draw semi-transparent background to create trail effect
ctx.fillStyle = "rgba(0, 0, 0, 0.08)";
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = "#00FF41"; // Classic Matrix Green
ctx.font = `${fontSize}px "Courier New", Courier, monospace`;
for (let i = 0; i < drops.length; i++) {
const text = characters.charAt(Math.floor(Math.random() * characters.length));
// Slightly brighten the lead character occasionally
if (Math.random() > 0.98) {
ctx.fillStyle = "#FFFFFF";
} else {
ctx.fillStyle = "#00FF41";
}
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
// Reset drop to top if it goes off screen
if (drops[i] * fontSize > height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
};
initCanvas();
const interval = setInterval(draw, 35);
const handleResize = () => {
initCanvas();
};
window.addEventListener('resize', handleResize);
return () => {
clearInterval(interval);
window.removeEventListener('resize', handleResize);
};
}, []);
return (
<canvas
ref={canvasRef}
className="fixed inset-0 w-full h-full pointer-events-none z-[-1] bg-black"
aria-hidden="true"
/>
);
};
export default MatrixBackground;