<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();
This Pen doesn't use any external JavaScript resources.