DEV Community

0 seconds of 0 secondsVolume 90%
Press shift question mark to access a list of keyboard shortcuts
00:00
00:00
00:00
 
Prince
Prince

Posted on

1 1

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)

Image of PulumiUP 2025

Explore What’s Next in DevOps, IaC, and Security

Join us for demos, and learn trends, best practices, and lessons learned in Platform Engineering & DevOps, Cloud and IaC, and Security.

Save Your Spot