JSFiddle - React, Tailwind, and code Playground

by soulwire

HTML

<canvas id="canvas" width="400" height="400"></canvas>

JavaScript

var ctx = canvas.getContext('2d');

function loop() {
    requestAnimationFrame(loop);
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    
    draw( 
            200, 200,
            (Math.sin(Date.now()/800)+1)/2*50 + 5,
            (Math.cos(Date.now()/1203)+1)/2*100 + 10,
            (Math.sin(Date.now()/531)+1)/2*100 + 5
        );
    
}

loop();

function draw(x, y, r1, r2, r3) {
    
    var a = r1+r2;
    var b = r2+r3;
    var c = r3+r1;
    
    var A = Math.acos((b*b+c*c-a*a)/(2*b*c));
    var B = Math.acos((c*c+a*a-b*b)/(2*c*a));
    var C = Math.PI - B - A;
    
    var A1 = Math.PI - B/2 - C/2;
    var cc = Math.sin(C/2)*a/Math.sin(A1);
    
    var cx = Math.cos(B/2)*cc;
    var cy = Math.sin(B/2)*cc;
    
    ctx.save();
    ctx.translate(x - cx, y - cy);
    ctx.lineWidth = 0.5;
    ctx.fillStyle = 'red';
    
    circle(0, 0, r1);
    circle(a, 0, r2);
    circle(Math.cos(B)*c, Math.sin(B)*c, r3);
    


    
    line(0, 0, a, 0);
    line(Math.cos(B)*c, Math.sin(B)*c, 0, 0);
    line(Math.cos(B)*c, Math.sin(B)*c, a, 0);

    
    
    ctx.restore();
    
}

function circle(x, y, r) {
    ctx.beginPath();
    ctx.arc(x, y, r, 0, Math.PI*2, false);
    ctx.fill();
}

function line(x, y, a, b) {
    ctx.beginPath();
    ctx.moveTo(a, b);
    ctx.lineTo(x, y);
    ctx.stroke();
}