Files
SerpentRace/SerpentRace_Frontend/src/assets/backgrounds/Background.jsx
T

102 lines
3.7 KiB
React
Executable File

import React, { useEffect, useState } from "react";
import { motion } from "framer-motion";
const Background = () => {
const [gridSize, setGridSize] = useState({ cols: 12, rows: 6 });
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
const [path, setPath] = useState([]);
useEffect(() => {
const updateGrid = () => {
const width = window.innerWidth;
const height = window.innerHeight;
const cols = Math.max(8, Math.floor(width / 100)); // 100px-es cellák
const rows = Math.max(5, Math.floor(height / 100)); // 100px-es cellák
setGridSize({ cols, rows });
};
const handleMouseMove = (e) => {
setMousePos({ x: e.clientX, y: e.clientY });
};
updateGrid();
window.addEventListener("resize", updateGrid);
window.addEventListener("mousemove", handleMouseMove);
return () => {
window.removeEventListener("resize", updateGrid);
window.removeEventListener("mousemove", handleMouseMove);
};
}, []);
useEffect(() => {
const interval = setInterval(() => {
const newCol = Math.floor(Math.random() * gridSize.cols);
const newRow = Math.floor(Math.random() * gridSize.rows);
setPath((prevPath) => {
const newPath = [...prevPath, { col: newCol, row: newRow, opacity: 1 }]; // Új pont hozzáadása
if (newPath.length > 10) {
newPath.shift(); // Max 10 pont az útvonalon
}
return newPath;
});
}, 500); // Új pont hozzáadása minden 500ms-ben
// Az útvonal pontjainak fokozatos eltűnése
const fadeInterval = setInterval(() => {
setPath((prevPath) =>
prevPath.map((point) => ({
...point,
opacity: Math.max(0, point.opacity - 0.05), // Fokozatosan csökkentjük az opacity-t
})).filter((point) => point.opacity > 0) // Eltávolítjuk a teljesen eltűnt pontokat
);
}, 100); // Opacity frissítése minden 100ms-ben
return () => {
clearInterval(interval);
clearInterval(fadeInterval);
};
}, [gridSize]);
return (
<div className="relative w-full h-screen bg-background flex items-center justify-center overflow-hidden">
<div
className="absolute inset-0 grid gap-2 opacity-20"
style={{
gridTemplateColumns: `repeat(${gridSize.cols}, 1fr)`,
gridTemplateRows: `repeat(${gridSize.rows}, 1fr)`,
}}
>
{[...Array(gridSize.cols * gridSize.rows)].map((_, i) => {
const col = i % gridSize.cols;
const row = Math.floor(i / gridSize.cols);
const cellX = (col + 0.5) * (window.innerWidth / gridSize.cols);
const cellY = (row + 0.5) * (window.innerHeight / gridSize.rows);
const dx = cellX - mousePos.x;
const dy = cellY - mousePos.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const distanceFactor = Math.max(0, 1 - distance / 300); // Egér hatótávolsága
// Az útvonalban lévő pontok opacitása
const pathPoint = path.find((p) => p.col === col && p.row === row);
const pathOpacity = pathPoint ? pathPoint.opacity : 0;
return (
<motion.div
key={i}
className="w-full h-full bg-white rounded-lg"
animate={{
opacity: 0.05 + distanceFactor * 0.2 + pathOpacity * 0.5, // Kombinált opacitás
scale: 1 + distanceFactor * 0.05 + pathOpacity * 0.1, // Kombinált skálázás
}}
transition={{ duration: 0.5, ease: "easeOut" }} // Lassú és sima átmenet
/>
);
})}
</div>
</div>
);
};
export default Background;