DEV Community

Cover image for Creating a Mesmerizing Particle Animation with JavaScript
Sohrab zia
Sohrab zia

Posted on • Originally published at sohrabzia.github.io

Creating a Mesmerizing Particle Animation with JavaScript

This is what we are going to create, move you mouse over the particles to see the effect.

In this article, I'll walk you through the process of creating a captivating particle animation using JavaScript and HTML5 canvas. This project not only enhances your web page's aesthetics but also serves as a fantastic opportunity to delve into some interesting coding concepts. Let’s dive in!

Project Overview

The animation features particles that move in a circular pattern around a center point. When the mouse hovers over the canvas, the particles are attracted to the cursor, creating a dynamic and engaging effect. We’ll utilize the Simplex Noise library to introduce some randomness and make the motion of particles more organic and visually appealing.

Technologies Used

  • HTML5 Canvas: For rendering the animation.
  • JavaScript: For managing the animation logic.
  • CSS: For styling and layout.
  • Simplex Noise: To add randomness to the particle movement.

Setting Up the Environment

To get started, create an HTML file and include the Simplex Noise library using the following script tag:

<script src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.4.0/simplex-noise.min.js"></script>

JavaScript Implementation

Here’s the core part of our animation in JavaScript. We'll define the configuration for the particles and set up the canvas to draw them.

'use strict'; // Enables strict mode to enforce stricter parsing and error handling in JavaScript

// Configuration object for particle system
const config = {
    particleCount: 100,                  // Total number of particles in the system
    particlePropCount: 9,                // Number of properties each particle has
    baseTTL: 1,                          // Base time-to-live for each particle (in seconds)
    rangeTTL: 2,                         // Range of time-to-live variation (in seconds)
    baseSpeed: 0.001,                    // Base speed of particle movement
    rangeSpeed: 0.002,                   // Variation in particle speed
    circularSpeed: 0.001,                // Speed of particles' circular motion
    baseRadius: 2,                       // Minimum radius of particles
    rangeRadius: 3,                      // Maximum variation in particle radius
    baseHue: 220,                        // Base hue (color) of particles
    rangeHue: 120,                       // Variation in hue for particle colors
    backgroundColor: '#111827',          // Color of the background
    circleRadius: 250,                   // Radius of the circular area in which particles move
    glowStrength: 10,                    // Strength of the glow effect around particles
    randomnessFactor: 4,                 // Factor to introduce randomness in particle behavior
    trailLength: 10.2,                   // Length of the trail left by particles
    mouseForce: 2,                       // Increased mouse attraction force to pull particles
    mouseRadius: 200                      // Radius within which mouse influence affects particles
};

// Additional JavaScript code goes here...

Enter fullscreen mode Exit fullscreen mode

In the above code, we configure various properties for our particles, including their count, speed, radius, color (hue), and the background color of the canvas.

Initializing Particles

We initialize the particles in a circular pattern and assign them random properties:

function initParticles() {
    particleProps = new Float32Array(config.particleCount * config.particlePropCount);
    const angleIncrement = TAU / config.particleCount;

    for (let i = 0; i < config.particleCount; i++) {
        initParticle(i * config.particlePropCount, i * angleIncrement);
    }
}

function initParticle(i, angleOffset) {
    const radius = config.baseRadius + rand(config.rangeRadius);
    const hue = config.baseHue + rand(config.rangeHue);

    particleProps.set([
        Math.cos(angleOffset) * config.circleRadius + canvas.a.width / 2,
        Math.sin(angleOffset) * config.circleRadius + canvas.a.height / 2,
        0, 0, 0,
        config.baseTTL + rand(config.rangeTTL),
        config.baseSpeed + rand(config.rangeSpeed),
        radius, hue
    ], i);
}

Enter fullscreen mode Exit fullscreen mode

Drawing Particles

The core animation logic is handled in the draw function, where we update and render the particles continuously:

function draw() {
    tick++;
    ctx.a.clearRect(0, 0, canvas.a.width, canvas.a.height);
    ctx.b.fillStyle = config.backgroundColor;
    ctx.b.fillRect(0, 0, canvas.a.width, canvas.a.height);

    drawParticles();
    renderGlow();
    renderToScreen();
    requestAnimationFrame(draw);
}



Enter fullscreen mode Exit fullscreen mode

CSS Styling

To ensure our animation looks polished, we’ll use some CSS for styling the body and canvas:

body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh; /* Full viewport height */
    margin: 0;
    background: #000; /* Optional: background color */
}

.content--canvas {
    position: absolute; 
    top: 0;
    z-index: 1;
    width: 100vw; /* Full viewport width */
    height: 100vh; /* Full viewport height */
}

canvas {
    display: block; 
}

Enter fullscreen mode Exit fullscreen mode

Feel free to experiment with the particle properties in the configuration object to create your unique animation! Check out the live demo on CodePen and share your thoughts or enhancements in the comments below.

Top comments (0)