<body>
  <svg width="500" height="500" viewBox="">
    <rect id="bg" x="0" y="0" width="" height="" fill="white" stroke="black" stroke-width="2" />
    <g id="holder">
    </g>
  </svg>
circle {
  stroke: #212121;
  stroke-width: 5;
  transition-property: stroke-width;
  transition-duration: 200ms;
  transition-timing-function: ease-in-out
}

circle:hover {
  stroke-width: 20;
}
const svg = document.querySelector("svg");
const holder = document.querySelector("#holder");
let dragging = false;
let draggedElement = null;
const draggables = [];
const num = 10;
const w = 1000;
const h = 1000;
const maxRadius = 75;
const minRadius = 25;
const namespace = "http://www.w3.org/2000/svg";

function init() {
  initSVG();
  initDraggables();
  initListeners();
}

function initSVG() {
  const viewboxString = `0 0 ${w} ${h}`;
  svg.setAttribute("viewBox", viewboxString);
  const bg = document.querySelector("#bg");
  bg.setAttribute("width", w);
  bg.setAttribute("height", h);
}

function initDraggables() {
  for(let i = 0; i < num; i++){
    const x = maxRadius + Math.random()*(w-2*maxRadius);
    const y = maxRadius + Math.random()*(h-2*maxRadius);
    const r = minRadius + Math.random()*(maxRadius-minRadius);
    const fill = getRandomColor();
    const g = document.createElementNS(namespace, "g");
    g.setAttribute("transform", `translate(${x} ${y})`);
    const circ = document.createElementNS(namespace, "circle");
    circ.setAttribute("cx", 0);
    circ.setAttribute("cy", 0);
    circ.setAttribute("r", r);
    circ.setAttribute("fill", fill);
    g.appendChild(circ);
    holder.appendChild(g);
    draggables.push(g);
  }
}

function initListeners() {
  draggables.forEach((draggable)=>{
    draggable.addEventListener("mousedown", (e)=>{
      startDrag(e);
    });
  })
  svg.addEventListener("mousemove", drawDrag);
  svg.addEventListener("mouseup", stopDrag);
  svg.addEventListener("mouseout", stopDrag);
}

function startDrag(e) {
  draggedElement = e.currentTarget;
  // bring dragged element to top
  holder.removeChild(draggedElement);
  holder.appendChild(draggedElement);
  dragging = true;
}

function stopDrag() {
  draggedElement = null;
  dragging = false;
}

function drawDrag(mouseEvent) {
  if (!dragging) return;
  const svgPoint = toSVGPoint(mouseEvent.clientX, mouseEvent.clientY, svg);
  draggedElement.setAttribute("transform", `translate(${svgPoint.x} ${svgPoint.y})`);
}

function toSVGPoint(x, y, theSVG) {
  let p = new DOMPoint(x, y);
  return p.matrixTransform(theSVG.getScreenCTM().inverse());
}

function getRandomColor() {
  return `hsl(${Math.round(Math.random() * 360)} 100% 50%)`;
}

init();
Run Pen

External CSS

  1. https://codepen.io/aokorodu/pen/poBNOgp.css

External JavaScript

This Pen doesn't use any external JavaScript resources.