JSFiddle - React, Tailwind, and code Playground

by Shriken

HTML

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

CSS

canvas {
    border-style: solid;
    border-color: black;
    border-width: 1px;
}

JavaScript

var arc = function(ctx, a, b, o, r) {
    var t1 = Math.atan2(a[1] - o[1], a[0] - o[0]);
    var t2 = Math.atan2(b[1] - o[1], b[0] - o[0]);
    
    ctx.beginPath();
    ctx.arc(o[0], o[1], r, t1, t2);
    ctx.stroke();
};

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(255,0,0)";

var STEPS = 100;

var CNTPT = [100, 80];
var ancpt = [100, 20];
var varpt = [160, 80];
var R = 60;

var animate = function(i) {
    ctx.clearRect(0,0, 200,200);
    
    var t = i * Math.PI * 2 / STEPS;
    var cntpt = null;
    var r = null;
    
    varpt = [CNTPT[0] + Math.cos(t) * R, CNTPT[1] + Math.sin(t) * R];
    if (t > Math.PI * 2 / 6 && t < Math.PI * 3 / 2) {
        var q = Math.sqrt(Math.pow(ancpt[0] - varpt[0], 2) +
                          Math.pow(ancpt[1] - varpt[1], 2));
        r = (q/2) / Math.sin(Math.PI * 2 / 6);
        
        var dir = [(varpt[1] - ancpt[1]) / q, (ancpt[0] - varpt[0]) / q];
        var avg = [(ancpt[0] + varpt[0]) / 2, (ancpt[1] + varpt[1]) / 2];
        cntpt = [avg[0] - Math.sqrt(r*r - q*q/4) * dir[0],
                 avg[1] - Math.sqrt(r*r - q*q/4) * dir[1]];
    }
    
    arc(ctx, ancpt, varpt, cntpt == null ? CNTPT : cntpt, r == null ? R : r);
    setTimeout(function(){animate((i+1) % STEPS)}, 30);
}

animate(0);