<canvas id="canvas"></canvas>
body {
  overflow: hidden;
}
(function () {
  function Particles(el) {
    var opts = arguments[1] || {};
    this.colors = opts.colors || ["255,255,255", "255,99,71", "19,19,19"];
    this.minRadius = opts.radius ? Math.min.apply(null, opts.radius) : 5;
    this.maxRadius = opts.radius ? Math.max.apply(null, opts.radius) : 35;
    this.minOpacity = opts.opacity ? Math.min.apply(null, opts.opacity) : 0.005;
    this.maxOpacity = opts.opacity ? Math.max.apply(null, opts.opacity) : 0.5;
    this.minSpeed = opts.speed ? Math.min.apply(null, opts.speed) : 0.005;
    this.maxSpeed = opts.speed ? Math.max.apply(null, opts.speed) : 0.5;
    this.numPartilce = opts.numPartilce || 75;
    this.canvas = document.querySelector(el);
    this.ctx = this.canvas.getContext("2d");
  }

  Particles.prototype = {
    init() {
      this.render();
      this.createCircle();
    },
    _rand(min, max) {
      return Math.random() * (max - min) + min;
    },
    render() {
      var self = this,
        wWidth = $(window).width(),
        wHeight = $(window).height();

      self.canvas.height = wHeight;
      self.canvas.width = wWidth;
    },

    createCircle() {
      var particle = [],
        self = this;
      for (var i = 0; i < this.numPartilce; i++) {
        particle[i] = {
          radius: self._rand(self.minRadius, self.maxRadius),
          xPos: self._rand(0, self.canvas.width),
          yPos: self._rand(0, self.canvas.height),
          xVelocity: self._rand(self.minSpeed, self.maxSpeed),
          yVelocity: self._rand(self.minSpeed, self.maxSpeed),
          color:
            "rgba(" +
            self.colors[parseInt(self._rand(0, 3))] +
            ", " +
            self._rand(self.minOpacity, self.maxOpacity) +
            ")"
        };
        self.draw(particle, i);
      }
      self.animate(particle);
    },
    draw(particle, i) {
      var self = this,
        ctx = self.ctx,
        item = particle[i];

      var grd = ctx.createRadialGradient(
        item.xPos,
        item.yPos,
        item.radius,
        item.xPos,
        item.yPos,
        item.radius / 1.25
      );
      grd.addColorStop(0, item.color);
      grd.addColorStop(1, "transparent");

      ctx.fillStyle = grd;

      ctx.beginPath();
      ctx.arc(item.xPos, item.yPos, item.radius, 0, 2 * Math.PI, false);
      ctx.fill();
    },
    animate(particle) {
      var self = this,
        ctx = self.ctx;
      setInterval(function () {
        ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
        for (var i = 0; i < particle.length; i++) {
          var item = particle[i];

          item.xPos += item.xVelocity;
          item.yPos -= item.yVelocity;

          if (
            item.xPos > self.canvas.width + item.radius ||
            item.yPos > self.canvas.height + item.radius
          ) {
            self.resetParticle(particle, i);
          } else {
            self.draw(particle, i);
          }
        }
      }, 1000 / 60);
    },
    resetParticle(particle, i) {
      var self = this,
        random = self._rand(0, 1),
        item = particle[i];
      if (random < 0.5) {
        item.xPos = 0;
        item.yPos = self._rand(0, self.canvas.height);
      } else {
        item.yPos = self._rand(0, self.canvas.width);
        item.xPos = self.canvas.height;
      }
      self.draw(particle, i);
    }
  };

  window.Particles = Particles;
})();

new Particles("#canvas").init();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js