>_htmlhub
library/celebration/fizzy-sparks

Fizzy Sparks

Live previewPerformance varies by device
fizzy-sparks.html

No account needed to copy or download. Check dependencies and thelicense status before publishing.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Fizzy Sparks</title>
    <style>
      /*
        Fizzy Sparks
        ------------
        This interactive canvas spawns small, glowing sparks wherever the
        user moves or clicks the mouse.  Each spark travels in a random
        direction and fades out over time.  The effect approximates the
        original CodePen's fizzy sparks animation using only plain
        JavaScript and the Canvas API.
      */
      html, body {
        margin: 0;
        padding: 0;
        height: 100%;
        overflow: hidden;
        background: #000;
        cursor: crosshair;
      }
      canvas {
        display: block;
      }
    </style>
  </head>
  <body>
    <canvas id="sparks"></canvas>
    <script>
      (function() {
        const canvas = document.getElementById('sparks');
        const ctx    = canvas.getContext('2d');
        function resize() {
          canvas.width  = window.innerWidth;
          canvas.height = window.innerHeight;
        }
        window.addEventListener('resize', resize);
        resize();
        // Particle class representing a single spark.
        class Spark {
          constructor(x, y) {
            this.x     = x;
            this.y     = y;
            const angle= Math.random() * Math.PI * 2;
            const speed= 2 + Math.random() * 3;
            this.vx    = Math.cos(angle) * speed;
            this.vy    = Math.sin(angle) * speed;
            this.life  = 40 + Math.floor(Math.random() * 20);
            this.age   = 0;
            this.radius= 2 + Math.random() * 3;
            // Choose a bright, random colour.
            const hue = Math.floor(Math.random() * 360);
            this.colour = `hsl(${hue}, 80%, 60%)`;
          }
          update() {
            this.x += this.vx;
            this.y += this.vy;
            // Apply a small amount of friction.
            this.vx *= 0.98;
            this.vy *= 0.98;
            // Gravity to pull sparks downwards.
            this.vy += 0.05;
            this.age++;
          }
          draw(ctx) {
            const alpha = 1 - this.age / this.life;
            ctx.fillStyle = this.colour;
            ctx.globalAlpha = alpha;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
            ctx.fill();
            ctx.globalAlpha = 1;
          }
          isDead() {
            return this.age >= this.life;
          }
        }
        const sparks = [];
        function spawn(x, y, count) {
          for (let i = 0; i < count; i++) {
            sparks.push(new Spark(x, y));
          }
        }
        // Spawn sparks on mouse movement and clicks.
        let lastSpawn = 0;
        document.addEventListener('mousemove', (e) => {
          const now = Date.now();
          if (now - lastSpawn > 50) {
            spawn(e.clientX, e.clientY, 5);
            lastSpawn = now;
          }
        });
        document.addEventListener('click', (e) => {
          spawn(e.clientX, e.clientY, 20);
        });
        function animate() {
          // Draw a translucent black rectangle to create trails.
          ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          // Update and draw each spark.
          for (let i = sparks.length - 1; i >= 0; i--) {
            const s = sparks[i];
            s.update();
            s.draw(ctx);
            if (s.isDead()) {
              sparks.splice(i, 1);
            }
          }
          requestAnimationFrame(animate);
        }
        animate();
      })();
    </script>
</body>
</html>

About this animation

Rising bubbles and sparks, great for success states.

Source Code
Copied to clipboard