JSFiddle - React, Tailwind, and code Playground

by Jon Fuller

HTML

<div class="progress-circle">
    <svg id="svg" width="100%" height="100%" viewbox="-1 -1 141 141" shape-rendering="geometricPrecision">
        <defs>
            <clippath id="clip-path">
                <path d="M70,70 v-50 a50,50 0 1,0 0,100 a50,50 0 1,0 0,-100 v-20 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" />
            </clippath>
        </defs>
        <g clip-path="url(#clip-path)">
            <path id="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#DD1111" />
            <path id="dark" fill="#710000" />
        </g>
        <path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="none" />
        <text id="perc" x="70" y="69" font-size="30px" fill="black" text-anchor="middle">12%</text>        <text id="title" x="70" y="89" font-size="20px" fill="black" text-anchor="middle">test</text>
    </svg>
</div>

CSS

body,
html {
    height: 100%;
    margin: 0;
    font-family: sans-serif;
}

.progress-circle {
    width: 100%;
    height: 100%;
}

JavaScript

var dark = document.getElementById('dark'),
    t = 5,
    percentage = parseInt(document.getElementById('perc').innerHTML.slice(0, -1), 10),
    theta = 0,
    maxTheta = (180 * percentage) / 50,
    radius = document.getElementById('svg').getBBox().width / 2;
dark.setAttribute('transform', 'translate(' + radius + ',' + radius + ')');

var animate = setInterval(function() {
    theta += 0.5;
    var d = 'M0,0 v' + -radius + 'A' + radius + ' ' + radius + ' 1 ' + ((theta > 180) ? 1 : 0) + ' 1 ' + Math.sin(theta * Math.PI / 180) * radius + ' ' + Math.cos(theta * Math.PI / 180) * -radius + 'z';
    dark.setAttribute('d', d);
    if (theta > maxTheta) {
        clearInterval(animate);
    }
}, t);