JSFiddle - React, Tailwind, and code Playground

by Darby Rathbone

CSS

canvas {
    position:absolute;
    display:block;
    top:0px;
    right:0px;
    bottom:0px;
    left:0px;
}
html, body {
    height:100%;
}
span {
    border:groove 3px;
    cursor: url(https://mail.google.com/mail/images/2/openhand.cur) 8 8, move;
    background:rgb(150, 225, 255);
    padding:5px;
    font-size:18px;
    position:absolute;
    display:block;
    min-width:10px;
    min-height:10px;
    -moz-border-radius: 25px;
    -webkit-border-radius: 25px;
    border-radius: 25px;
}

JavaScript

var dimensions = document.body.getBoundingClientRect();
var can = document.createElement('canvas');
document.body.appendChild(can);
can.width = dimensions.width;
can.setAttribute('width', dimensions.width);
can.setAttribute('height', dimensions.height);
can.height = dimensions.height;
var c = can.getContext('2d');
var nodes = [];

function randomxy() {

    var e = document.createElement('span');
    document.body.appendChild(e);
    return {x:Math.random() * 500,y: Math.random() * 500,obj: e};
}
var count = 5;
nodes.push([]);
while (count--) {
    nodes[0].push(randomxy())
    nodes[0][nodes.length - 1].obj.textContent = "B : " + nodes.length;
    nodes.push(randomxy());
    nodes[nodes.length - 1].obj.textContent = "A : " + nodes.length;
    if((nodes.length-1)%2)
        nodes[0].push(nodes[nodes.length-1]);

}
var Drawer = function Drawer() {
    nodes.forEach(function eachnode(e,i,a) {if (Array.isArray(e)){e.forEach(eachnode);}
                                        else{
        var size = e.obj.getBoundingClientRect();
        e.obj.style.left = e.x- (size.width / 2) + "px";
        e.obj.style.top = e.y - (size.height / 2) + "px";
                                        }
        a.forEach(function everynode (b) {
            if (b !== e) {
                c.beginPath();
                c.moveTo(e.x, e.y);
                c.lineTo(b.x, b.y);
                c.stroke();
            }
        });
    });
};
nodes.forEach(function eventnodes(n, i,a) {
    if (Array.isArray(n)){n.forEach(eventnodes);return true;}
    n.obj.addEventListener('mousedown', function (e) {
        
        n.obj.setAttribute('style',"cursor: url(https://mail.google.com/mail/images/2/closedhand.cur) 8 8, move;");
        e.preventDefault();
        var mousemover = function mousemover(m) {
            a[i] = {x:m.pageX, y:m.pageY,obj: n.obj};
        };
        var mouseuper = function mouseuper(m) {
            a[i] = {x:m.pageX, y:m.pageY,obj: n.obj};
           ...