interface Props { // Color of the first set of particles (default: Ultramarine) primaryColor?: string; // Color of the second set of particles (default: Aqua) secondaryColor?: string; // Radius of mouse interaction (default: 150px) mouseRadius?: number; // Background color or gradient (default: Dark gradient) backgroundColor?: string; } export default function ParticleBackground({ primaryColor = "rgba(68, 116, 255, 0.8)", // Ultramarine secondaryColor = "rgba(66, 249, 255, 0.8)", // Aqua mouseRadius = 150, backgroundColor = "linear-gradient(to bottom, rgba(0,0,0,0.95), rgba(0,0,0,1))" }: Props) { return { canvas: document.createElement("canvas"), mount(canvas: HTMLCanvasElement) { // Set up canvas styles canvas.style.position = "fixed"; canvas.style.top = "0"; canvas.style.left = "0"; canvas.style.width = "100%"; canvas.style.height = "100%"; canvas.style.zIndex = "-1"; canvas.style.background = backgroundColor; const ctx = canvas.getContext("2d"); if (!ctx) return; // Initialize variables let particles: Array<{ x: number; y: number; vx: number; vy: number; targetX: number; targetY: number; radius: number; color: string; }> = []; const mouse = { x: 0, y: 0, radius: mouseRadius }; let animationFrame: number; // Update canvas size function updateCanvasSize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } // Generate points in a circle pattern function generatePoints() { const points: [number, number][] = []; const centerX = canvas.width / 2; const centerY = canvas.height / 2; const size = Math.min(canvas.width, canvas.height) * 0.2; const gridSize = 15; for (let x = 0; x < canvas.width; x += gridSize) { for (let y = 0; y < canvas.height; y += gridSize) { const dx = x - centerX; const dy = y - centerY; const distance = Math.sqrt(dx * dx + dy * dy); if (distance > size) { points.push([x, y]); } } } return points; } // Initialize particles function initParticles() { const points = generatePoints(); particles = points.map(([targetX, targetY]) => { const angle = Math.random() * Math.PI * 2; const distance = Math.random() * 200; return { x: targetX + Math.cos(angle) * distance, y: targetY + Math.sin(angle) * distance, vx: (Math.random() - 0.5) * 2, vy: (Math.random() - 0.5) * 2, targetX, targetY, radius: Math.random() * 1.5 + 1, color: Math.random() < 0.5 ? primaryColor : secondaryColor }; }); } // Animation loop function animate() { if (!ctx) return; ctx.fillStyle = "rgba(0, 0, 0, 0.2)"; ctx.fillRect(0, 0, canvas.width, canvas.height); particles.forEach(particle => { // Mouse repulsion const dx = mouse.x - particle.x; const dy = mouse.y - particle.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < mouse.radius) { const force = (mouse.radius - distance) / mouse.radius; const angle = Math.atan2(dy, dx); particle.vx -= Math.cos(angle) * force * 2; particle.vy -= Math.sin(angle) * force * 2; } // Target attraction const tdx = particle.targetX - particle.x; const tdy = particle.targetY - particle.y; const targetDistance = Math.sqrt(tdx * tdx + tdy * tdy); if (targetDistance > 1) { particle.vx += (tdx / targetDistance) * 0.2; particle.vy += (tdy / targetDistance) * 0.2; } // Update position particle.x += particle.vx; particle.y += particle.vy; // Apply drag particle.vx *= 0.95; particle.vy *= 0.95; // Draw particle ctx.beginPath(); ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2); ctx.fillStyle = particle.color; ctx.fill(); }); animationFrame = requestAnimationFrame(animate); } // Event handlers function handleMouseMove(e: MouseEvent) { const rect = canvas.getBoundingClientRect(); mouse.x = e.clientX - rect.left; mouse.y = e.clientY - rect.top; } // Initialize updateCanvasSize(); initParticles(); animate(); // Add event listeners window.addEventListener("mousemove", handleMouseMove); window.addEventListener("resize", () => { updateCanvasSize(); initParticles(); }); // Cleanup function return () => { cancelAnimationFrame(animationFrame); window.removeEventListener("mousemove", handleMouseMove); window.removeEventListener("resize", updateCanvasSize); }; } }; }

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Harness the power of AI, making search engine optimization intuitive and effective for all skill levels.

Harness the power of AI, making search engine optimization intuitive and effective for all skill levels.

Harness the power of AI, making search engine optimization intuitive and effective for all skill levels.

Harness the power of AI, making search engine optimization intuitive and effective for all skill levels.