<div class="wrapper">
  <canvas id="canvas"></canvas>
</div>
html,
body {
  margin: 0;
  width: 100%;
  height: 100%;
  background: #222222;
}

.wrapper {
  width: 100%;
  height: 100%;
}
const canvas = document.getElementById("canvas");
const outputContainer = document.getElementsByClassName("wrapper")[0];
const ctx = canvas.getContext("2d");
const ratio = window.devicePixelRatio || 1;
let width = outputContainer.offsetWidth;
let height = outputContainer.offsetHeight;
canvas.width = width * ratio;
canvas.height = height * ratio;
canvas.style.width = width + "px";
canvas.style.height = height + "px";
ctx.scale(ratio, ratio);

let canvasPadding = 100;
let amountOfDots = 8;

draw();

function draw() {
  ctx.fillStyle = "#222222";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.lineWidth = 1;

  for (let i = 0; i < amountOfDots; i++) {
    drawCircle();
  }
}

function drawCircle() {
  let circleMovement = 30;
  let circleSize = randomNum(20, 200);
  let x = randomNum(0 + canvasPadding, width - canvasPadding);
  let y = randomNum(0 + canvasPadding, height - canvasPadding);

  ctx.beginPath();
  ctx.save();

  ctx.strokeStyle = `rgb(${randomNum(0, 255)}, ${randomNum(
    0,
    255
  )}, ${randomNum(0, 255)})`;

  ctx.arc(x, y, circleSize, 0, 2 * Math.PI);
  ctx.clip();

  for (let i = 0; i < 70; i++) {
    ctx.arc(
      randomNum(x - circleSize, x + circleSize),
      randomNum(y - circleSize, y + circleSize),
      circleSize,
      0,
      2 * Math.PI
    );
    ctx.stroke();
  }

  ctx.restore();
}

function randomNum(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}

document.addEventListener("click", () => {
  requestAnimationFrame(draw);
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.