JSFiddle - React, Tailwind, and code Playground

by jacomyal

HTML

<div id="container">
    <canvas id="stage"></canvas>
</div>

CSS

body {
    margin: 0;
    padding: 0;
    background: #ccc;
}
#container {
    position: absolute;
    top: 10px;
    left: 10px;
    right: 10px;
    bottom: 10px;
}
#stage {
    background: #fff;
}

JavaScript

var container = document.getElementById('container'),
    canvas = document.getElementById('stage'),
    ctx = canvas.getContext('2d');

// The actual count of items we have:
var N = 8;

function render() {
    // Generate sizes:
    var nodes = [],
        radius = 300;
    for (var i = 0; i < N; i++) {
        var size = 80 - 40 * (i / N),
            angle = Math.PI * 2 / N * i;

        nodes.push({
            x: (radius - size) * Math.cos(angle),
            y: (radius - size) * Math.sin(angle),
            radius: size
        });
    }
    
    function nextStep() {
        var mean = 0;
        
        // Find distances and mean:
        for (var i = 0; i < N; i++) {
            var n1 = nodes[i],
                n2 = nodes[(i + 1) % N],
                d = Math.sqrt(
                    Math.pow(n1.x - n2.x, 2) +
                    Math.pow(n1.y - n2.y, 2)
                ) - n1.radius - n2.radius;

            n1.rd = n2.ld = d;
            mean += d;
        }
        mean = mean / N;
        
        // Correct distances:
        var angle = 0;
        for (var i = 0; i < N; i++) {
            var n1 = nodes[i],
                n2 = nodes[(i + 1) % N];
            
            n1.x = (radius - n1.radius) * Math.cos(angle);
            n1.y = (radius - n1.radius) * Math.sin(angle);
            
            angle += 2 * Math.asin(
                (n1.radius + n2.radius + mean) /
                (2 * radius - n1.radius - n2.radius)
            );
        }
    }
    
    function renderNodes() {
        canvas.width = canvas.width;
    
        var w = canvas.offsetWidth,
            h = canvas.offsetHeight;
        
        ctx.translate(w / 2, h / 2);
        
        // Basic grid to identify the center:
        ctx.beginPath();
        ctx.moveTo(-w / 4, 0);
        ctx.lineTo(w / 4, 0);
        ctx.moveTo(0, -h / 4);
        ctx.lineTo(0, h / 4);
        ctx.closePath();
        ctx.strokeStyle = '#ccc';
        ctx.stroke();
        
        for...