Files
netrunner-landing/components/sections/MatrixBackground.tsx
T
2026-04-19 16:05:05 +10:00

111 lines
3.3 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
export default function MatrixBackground({
isSecure,
theme,
}: {
isSecure: boolean;
theme?: string;
}) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let width = (canvas.width = window.innerWidth);
let height = (canvas.height = window.innerHeight);
const fontSize = 16;
const columns = Math.floor(width / fontSize);
const drops = Array(columns).fill(1);
const isDark = theme === "dark";
const draw = () => {
// Контрастный фон: в темной теме делаем глубокий черный
ctx.fillStyle = isDark
? "rgba(0, 0, 0, 0.08)" // Чистый черный для контраста
: "rgba(250, 250, 250, 0.05)";
ctx.fillRect(0, 0, width, height);
const gradient = ctx.createRadialGradient(
width / 2,
height / 2,
0,
width / 2,
height / 2,
Math.sqrt(width ** 2 + height ** 2) / 2,
);
if (isSecure) {
if (isDark) {
gradient.addColorStop(0, "#00F0FF"); // Центр: Ядовитый циановый
gradient.addColorStop(0.4, "#0080FF");
gradient.addColorStop(1, "rgba(0, 20, 40, 0)"); // Края уходят в прозрачность
} else {
gradient.addColorStop(0, "rgba(2, 132, 199, 1)");
gradient.addColorStop(1, "rgba(2, 85, 199, 0.2)");
}
} else {
if (isDark) {
gradient.addColorStop(0, "#7000FF"); // Центр: Яркий фиолетовый
gradient.addColorStop(0.4, "#400099");
gradient.addColorStop(1, "rgba(20, 0, 40, 0)");
} else {
gradient.addColorStop(0, "rgba(217, 40, 217, 1)");
gradient.addColorStop(1, "rgba(61, 40, 217, 0.2)");
}
}
ctx.fillStyle = gradient;
ctx.font = `bold ${fontSize}px monospace`; // Сделали шрифт bold для четкости
// Добавляем эффект свечения только для темной темы
if (isDark) {
ctx.shadowBlur = 8;
ctx.shadowColor = isSecure ? "#00F0FF" : "#7000FF";
} else {
ctx.shadowBlur = 0;
}
for (let i = 0; i < drops.length; i++) {
const text = Math.random() > 0.5 ? "1" : "0";
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
};
const interval = setInterval(draw, 33);
const handleResize = () => {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
window.addEventListener("resize", handleResize);
return () => {
clearInterval(interval);
window.removeEventListener("resize", handleResize);
};
}, [isSecure, theme]);
return (
<canvas
ref={canvasRef}
// opacity-100 для темной темы, чтобы не гасить яркость, и opacity-30 для светлой
className={`absolute inset-0 -z-20 transition-opacity duration-1000 ${
theme === "dark" ? "opacity-100" : "opacity-30"
}`}
/>
);
}