JSFiddle - React, Tailwind, and code Playground
by Christian Sonne
HTML
<canvas id="c"></canvas>
CSS
html, body {
margin: 0;
padding: 0;
line-height: 0;
}
JavaScript
let labels = [];
function Label(y) {
this.y = this.anchor = y;
}
let W = c.width = window.innerWidth;
let H = c.height = window.innerHeight;
let ctx = c.getContext("2d");
ctx.textBaseline="middle";
c.addEventListener("click", function(e) {
labels.push(new Label(e.clientY));
}, false);
function mutate() {
for (let ia = 0; ia < labels.length -1 ; ia++) {
let a = labels[ia];
for (let ib = ia + 1; ib < labels.length; ib++) {
let b = labels[ib];
if (a != b) {
let dist = a.y - b.y;
if (dist == 0) {
a.y += 1;
}
if (Math.abs(dist) < 10) {
a.y += Math.sign(dist);
b.y -= Math.sign(dist);
}
if (
(a.anchor < b.anchor && a.y > b.y) ||
(a.anchor > b.anchor && a.y < b.y)) {
let t = a.anchor;
a.anchor = b.anchor;
b.anchor = t;
}
}
}
}
}
function draw() {
mutate();
ctx.clearRect(0, 0, W, H);
for (let label of labels) {
ctx.beginPath();
ctx.moveTo(0, label.anchor);
ctx.lineTo(18, label.y);
ctx.stroke();
ctx.fillText("Label at "+label.anchor, 20, label.y);
}
window.requestAnimationFrame(draw);
}
window.requestAnimationFrame(draw);