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);