Our mission is to design websites that attract and engage customers.

However, we approach things a bit differently around here.

import React, { useEffect, useRef } from 'react'; const ParticleNetwork = () => { const canvasRef = useRef(null); useEffect(() => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); let particles = []; let animationFrameId; let mousePosition = { x: 0, y: 0 }; const resizeCanvas = () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }; class Particle { constructor() { this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.vx = (Math.random() - 0.5) * 0.4; this.vy = (Math.random() - 0.5) * 0.4; this.radius = Math.random() * 3; this.originalX = this.x; this.originalY = this.y; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.fillStyle = 'rgba(52, 148, 230, 0.6)'; ctx.fill(); } update() { const dx = mousePosition.x - this.x; const dy = mousePosition.y - this.y; const distance = Math.sqrt(dx * dx + dy * dy); const forceDirectionX = dx / distance; const forceDirectionY = dy / distance; const maxDistance = 150; const force = (maxDistance - distance) / maxDistance; const directionX = forceDirectionX * force * 0.7; const directionY = forceDirectionY * force * 0.7; if (distance < maxDistance) { this.vx += directionX; this.vy += directionY; } this.x += this.vx; this.y += this.vy; this.vx += (this.originalX - this.x) * 0.02; this.vy += (this.originalY - this.y) * 0.02; this.vx *= 0.95; this.vy *= 0.95; } } const initParticles = () => { particles = []; for (let i = 0; i < 200; i++) { particles.push(new Particle()); } }; const drawConnections = () => { ctx.strokeStyle = 'rgba(52, 148, 230, 0.2)'; ctx.lineWidth = 1; for (let i = 0; i < particles.length; i++) { for (let j = i + 1; j < particles.length; j++) { const dx = particles[i].x - particles[j].x; const dy = particles[i].y - particles[j].y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { ctx.beginPath(); ctx.moveTo(particles[i].x, particles[i].y); ctx.lineTo(particles[j].x, particles[j].y); ctx.stroke(); } } } }; const animate = () => { ctx.clearRect(0, 0, canvas.width, canvas.height); drawConnections(); particles.forEach(particle => { particle.update(); particle.draw(); }); animationFrameId = requestAnimationFrame(animate); }; const handleMouseMove = (event) => { mousePosition.x = event.clientX; mousePosition.y = event.clientY; }; resizeCanvas(); initParticles(); animate(); window.addEventListener('resize', () => { resizeCanvas(); initParticles(); }); window.addEventListener('mousemove', handleMouseMove); return () => { cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resizeCanvas); window.removeEventListener('mousemove', handleMouseMove); }; }, []); return ( ref={canvasRef} style={{ position: 'absolute', top: 0, left: 0, zIndex: -1, pointerEvents: 'none' }} /> ); }; export default ParticleNetwork;