DEV Community

Play Button Pause Button
Prince
Prince

Posted on

Magnetic effect illusions with the html css and javascript

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Magnetic Particle Effect</title> <style> body { margin: 0; overflow: hidden; background-color: #0f0f1e; font-family: 'Arial', sans-serif; } canvas { display: block; } .info { position: absolute; bottom: 30px; left: 30px; color: white; font-size: 18px; text-shadow: 0 0 5px rgba(0,0,0,0.5); pointer-events: none; } .info h1 { margin: 0 0 10px 0; font-size: 28px; color: #00ffaa; } .tag { position: absolute; top: 30px; right: 30px; color: #00ffaa; font-size: 24px; font-weight: bold; text-shadow: 0 0 5px rgba(0,0,0,0.5); pointer-events: none; } </style> </head> <body> <canvas id="canvas"></canvas> <div class="info"> <h1>Magnetic Particles</h1> <p>Move your cursor to control the particle flow</p> </div> <div class="tag">@prince_codes1</div> <script> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; // Configuration const particleCount = 300; const particleBaseRadius = 2; const particleVariance = 1.5; const baseSpeed = 0.5; const colorPalette = ['#00ffaa', '#00ccff', '#ff00aa', '#ffcc00']; let mouseX = canvas.width / 2; let mouseY = canvas.height / 2; let mouseRadius = 150; let mouseStrength = 10; // Particle class class Particle { constructor() { this.reset(); // Start particles at random positions this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; } reset() { // For new particles entering the canvas this.x = Math.random() < 0.5 ? 0 : canvas.width; this.y = Math.random() * canvas.height; this.size = particleBaseRadius + Math.random() * particleVariance; this.color = colorPalette[Math.floor(Math.random() * colorPalette.length)]; // Set velocity toward center of screen with some randomness const angle = Math.atan2(canvas.height/2 - this.y, canvas.width/2 - this.x); const speed = baseSpeed + Math.random() * 0.5; this.vx = Math.cos(angle) * speed; this.vy = Math.sin(angle) * speed; this.originalSize = this.size; this.growFactor = 1 + Math.random() * 0.3; } update() { // Calculate distance to mouse const dx = this.x - mouseX; const dy = this.y - mouseY; const distance = Math.sqrt(dx * dx + dy * dy); // Apply force if within mouse radius if (distance < mouseRadius) { const force = (mouseRadius - distance) / mouseRadius; const angle = Math.atan2(dy, dx); const fx = Math.cos(angle) * force * mouseStrength; const fy = Math.sin(angle) * force * mouseStrength; this.vx += fx * 0.02; this.vy += fy * 0.02; // Grow particles near the mouse this.size = this.originalSize * (1 + force * this.growFactor); } else { // Gradually return to original size this.size = this.originalSize + (this.size - this.originalSize) * 0.95; } // Apply velocity this.x += this.vx; this.y += this.vy; // Slow down over time (friction) this.vx *= 0.98; this.vy *= 0.98; // Check if particle is out of bounds if (this.x < -50 || this.x > canvas.width + 50 || this.y < -50 || this.y > canvas.height + 50) { this.reset(); } } draw() { ctx.fillStyle = this.color; ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fill(); // Add glow effect ctx.shadowBlur = 10; ctx.shadowColor = this.color; } } // Create particles const particles = []; for (let i = 0; i < particleCount; i++) { particles.push(new Particle()); } // Animation loop function animate() { // Clear with semi-transparent background for trail effect ctx.fillStyle = 'rgba(15, 15, 30, 0.2)'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Update and draw particles ctx.shadowBlur = 0; // Reset shadow before drawing particles particles.forEach(particle => { particle.update(); particle.draw(); }); // Animation pulse effect for mouse area const time = Date.now() * 0.001; mouseRadius = 150 + Math.sin(time) * 50; requestAnimationFrame(animate); } // Start animation animate(); // Handle mouse movement window.addEventListener('mousemove', (event) => { mouseX = event.clientX; mouseY = event.clientY; }); // Handle touch for mobile window.addEventListener('touchmove', (event) => { event.preventDefault(); mouseX = event.touches[0].clientX; mouseY = event.touches[0].clientY; }, { passive: false }); // Handle window resize window.addEventListener('resize', () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }); // Create automatic movement when no user interaction let inactivityTimer = null; function startInactivityTimer() { clearInterval(inactivityTimer); inactivityTimer = setInterval(() => { const time = Date.now() * 0.0005; mouseX = canvas.width/2 + Math.sin(time) * (canvas.width/3); mouseY = canvas.height/2 + Math.cos(time * 1.3) * (canvas.height/3); }, 50); } // Start automatic movement by default startInactivityTimer(); // Stop automatic movement when user interacts window.addEventListener('mousemove', () => { clearInterval(inactivityTimer); // Restart after 5 seconds of inactivity setTimeout(startInactivityTimer, 5000); }); </script> </body> </html> 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)