import React, { useEffect, useRef } from 'react'; const Background: React.FC<{ theme: 'light' | 'dark' }> = ({ theme }) => { const canvasRef = useRef(null); useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext('2d'); if (!ctx) return; let animationFrameId: number; let time = 0; const resize = () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }; window.addEventListener('resize', resize); resize(); const points: { x: number; y: number; z: number }[] = []; const numPoints = 50; // Reduced count slightly const size = 300; // Create a cube of dots for (let i = 0; i < numPoints; i++) { points.push({ x: (Math.random() - 0.5) * size, y: (Math.random() - 0.5) * size, z: (Math.random() - 0.5) * size, }); } const draw = () => { // Varied, slower speed time += 0.001 + Math.sin(Date.now() * 0.0005) * 0.0005; ctx.clearRect(0, 0, canvas.width, canvas.height); const cx = canvas.width / 2; const cy = canvas.height / 2; // Much lower opacity for better contrast with content const color = theme === 'dark' ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.05)'; const connectionColor = theme === 'dark' ? 'rgba(255, 255, 255, 0.02)' : 'rgba(0, 0, 0, 0.02)'; ctx.fillStyle = color; ctx.strokeStyle = connectionColor; // Rotate points const rotatedPoints = points.map(p => { // Rotate Y let x = p.x * Math.cos(time) - p.z * Math.sin(time); let z = p.x * Math.sin(time) + p.z * Math.cos(time); // Rotate X let y = p.y * Math.cos(time * 0.5) - z * Math.sin(time * 0.5); z = p.y * Math.sin(time * 0.5) + z * Math.cos(time * 0.5); // Perspective projection const scale = 800 / (800 + z); return { x: cx + x * scale, y: cy + y * scale, scale }; }); // Draw connections ctx.beginPath(); for (let i = 0; i < rotatedPoints.length; i++) { for (let j = i + 1; j < rotatedPoints.length; j++) { const dx = rotatedPoints[i].x - rotatedPoints[j].x; const dy = rotatedPoints[i].y - rotatedPoints[j].y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 120) { ctx.moveTo(rotatedPoints[i].x, rotatedPoints[i].y); ctx.lineTo(rotatedPoints[j].x, rotatedPoints[j].y); } } } ctx.stroke(); // Draw points rotatedPoints.forEach(p => { ctx.beginPath(); ctx.arc(p.x, p.y, 2 * p.scale, 0, Math.PI * 2); ctx.fill(); }); animationFrameId = requestAnimationFrame(draw); }; draw(); return () => { window.removeEventListener('resize', resize); cancelAnimationFrame(animationFrameId); }; }, [theme]); return ( ); }; export default Background;