From 6b263f340e469f5263838eeb1a676ffc13e5bf2d Mon Sep 17 00:00:00 2001 From: Mariia Shabelnik Date: Mon, 5 May 2025 20:45:28 +0200 Subject: [PATCH] added bg --- src/App.jsx | 6 +- src/components/AnimatedBackground.jsx | 97 +++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/components/AnimatedBackground.jsx diff --git a/src/App.jsx b/src/App.jsx index e7a1b18..9411451 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -5,12 +5,14 @@ import ExperianceDetail from "./pages/ExperienceDetail"; import FullPage from "./pages/FullPage"; import { RecoilRoot } from "recoil"; import ScrollToAnchor from "./components/ScrollToAnchor"; +import AnimatedBackground from "./components/AnimatedBackground"; function App() { return ( -
+
+ -
+
diff --git a/src/components/AnimatedBackground.jsx b/src/components/AnimatedBackground.jsx new file mode 100644 index 0000000..3971cfc --- /dev/null +++ b/src/components/AnimatedBackground.jsx @@ -0,0 +1,97 @@ +import { useEffect, useRef } from 'react'; + +const AnimatedBackground = () => { + const canvasRef = useRef(null); + + useEffect(() => { + const canvas = canvasRef.current; + const ctx = canvas.getContext('2d'); + let animationFrameId; + let lastScrollY = 0; + + // Set canvas size + const resizeCanvas = () => { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + }; + resizeCanvas(); + window.addEventListener('resize', resizeCanvas); + + // Create dots + const dots = []; + const dotCount = 80; // Reduced from 100 for smoother performance + for (let i = 0; i < dotCount; i++) { + dots.push({ + x: Math.random() * canvas.width, + y: Math.random() * canvas.height, + size: Math.random() * 2 + 1, + speed: Math.random() * 0.3 + 0.1, // Reduced speed for smoother movement + }); + } + + // Animation loop + const animate = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // Draw dots + ctx.fillStyle = 'rgba(150, 150, 150, 0.3)'; // Increased from 0.2 + dots.forEach(dot => { + ctx.beginPath(); + ctx.arc(dot.x, dot.y, dot.size * 1.2, 0, Math.PI * 2); // Increased size + ctx.fill(); + }); + + // Draw connections + ctx.strokeStyle = 'rgba(150, 150, 150, 0.15)'; // Increased from 0.1 + ctx.lineWidth = 1; // Increased from 0.8 + dots.forEach((dot1, i) => { + dots.slice(i + 1).forEach(dot2 => { + const dx = dot1.x - dot2.x; + const dy = dot1.y - dot2.y; + const distance = Math.sqrt(dx * dx + dy * dy); + if (distance < 180) { // Increased connection distance + ctx.beginPath(); + ctx.moveTo(dot1.x, dot1.y); + ctx.lineTo(dot2.x, dot2.y); + ctx.stroke(); + } + }); + }); + + animationFrameId = requestAnimationFrame(animate); + }; + + // Handle scroll + const handleScroll = () => { + const scrollY = window.scrollY; + const scrollDiff = scrollY - lastScrollY; + + dots.forEach(dot => { + dot.y += scrollDiff * dot.speed * 0.15; // Reduced movement speed + if (dot.y > canvas.height) dot.y = 0; + if (dot.y < 0) dot.y = canvas.height; + }); + + lastScrollY = scrollY; + }; + + window.addEventListener('scroll', handleScroll); + animate(); + + // Cleanup + return () => { + window.removeEventListener('resize', resizeCanvas); + window.removeEventListener('scroll', handleScroll); + cancelAnimationFrame(animationFrameId); + }; + }, []); + + return ( + + ); +}; + +export default AnimatedBackground; \ No newline at end of file