Main pages
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
// 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<HTMLCanvasElement>(null);
|
||||
const lastWidth = useRef<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = canvasRef.current;
|
||||
if (!canvas) return;
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
let intervalId: NodeJS.Timeout;
|
||||
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]++;
|
||||
}
|
||||
};
|
||||
|
||||
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 (
|
||||
<div className="fixed inset-0 pointer-events-none w-screen h-[110vh] bg-[#0d1117]" style={{ zIndex: -1 }}>
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className="absolute inset-0 w-full h-full opacity-[0.15] blur-[0.5px]"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user