JSFiddle - React, Tailwind, and code Playground

by m1erickson

HTML

<button id="toShape">Animate to Shape</button>
<button id="toCircle">Animate to Circle</button><br>
<canvas id="canvas" width=300 height=300></canvas>

CSS

body{ background-color: ivory; }
canvas{border:1px solid red;}

JavaScript

// change sideCount to the # of poly sides desired
//
var sideCount = 3;


var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.lineWidth = 2;
ctx.fillStyle = randomColor();

var PI2 = Math.PI * 2;
var cx = 150;
var cy = 150;
var radius = 100;

var xx = function (a) {
    return (cx + radius * Math.cos(a));
}
var yy = function (a) {
    return (cy + radius * Math.sin(a));
}
var lerp = function (a, b, x) {
    return (a + x * (b - a));
}

var sides = [];
for (var i = 0; i < sideCount; i++) {
    sides.push(makeSide(i, sideCount));
}

var percent = 0;
var percentDirection = 0.50;

$("#toShape").click(function () {
    percentDirection = -0.50;
})

$("#toCircle").click(function () {
    percentDirection = 0.50;
})

animate();

// functions

function animate() {
    requestAnimationFrame(animate);
    drawSides(percent);
    percent += percentDirection;
    if (percent > 100) {
        percent = 100;
    }
    if (percent < 0) {
        percent = 0;
    }
}

function drawSides(pct, color) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if (pct == 100) {
        ctx.beginPath();
        ctx.arc(cx, cy, radius, 0, PI2);
        ctx.closePath();
        ctx.fill();
    } else {
        ctx.beginPath();
        ctx.moveTo(sides[0].x0, sides[0].y0);
        for (var i = 0; i < sideCount; i++) {
            var side = sides[i];
            var cpx = lerp(side.midX, side.cpX, pct / 100);
            var cpy = lerp(side.midY, side.cpY, pct / 100);
            ctx.quadraticCurveTo(cpx, cpy, side.x2, side.y2);
        }
        ctx.fill();
    }
}

function makeSide(n, sideCount) {
    var sweep = PI2 / sideCount;
    var sAngle = sweep * (n - 1);
    var eAngle = sweep * n;

    var x0 = xx(sAngle);
    var y0 = yy(sAngle);
    var x1 = xx((eAngle + sAngle) / 2);
    var y1 = yy((eAngle + sAngle) / 2);
    var x2 = xx(eAngle);
    var y2 = yy(eAngle);

    var dx = x2 - x1;
    var dy = y2 - y1;
    var a = Math.atan2(dy, dx);
   ...