const barWidth = 10;
const cornerRadius = barWidth * 2 + 8;
const polyRadius = 100;
const inset = 1;
const barRadius = polyRadius - barWidth * inset;
var progress = 0.0;
const approxLineLen = barRadius * Math.PI * 2;
const hexBar = polygon(6, barRadius);
const hexPoly = polygon(6, polyRadius);
const hexPolyInner = polygon(6, polyRadius - barWidth * 2 * inset);
const ctx = canvas.getContext("2d");
ctx.setLineDash([approxLineLen]);
loop()
function point(x,y) { return {x, y} }
function polygon(sides, radius, rot = 0) {
var i = 0;
const step = Math.PI * 2 / sides, path = [];
while (i < sides) {
path.push(point(Math.cos(i * step + rot) * radius, Math.sin((i++) * step + rot) * radius));
}
return path;
}
function roundedPath(path, radius) {
var i = 0, p1 = path[i++], p2 = path[i];
const len = path.length
ctx.moveTo((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
while (i <= len) {
p1 = p2;
p2 = path[(++i) % len];
ctx.arcTo(p1.x, p1.y, (p1.x + p2.x) / 2, (p1.y + p2.y) / 2, radius);
}
}
function strokeRoundedPath(cx, cy, path, radius, style, width) {
ctx.setTransform(1,0,0,1,cx,cy);
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.strokeStyle = style;
ctx.beginPath();
roundedPath(path, radius);
ctx.closePath();
ctx.stroke();
}
function fillRoundedPath(cx, cy, path, radius, style) {
ctx.setTransform(1,0,0,1,cx,cy);
ctx.fillStyle = style;
ctx.beginPath();
roundedPath(path, radius);
ctx.fill();
}
function loop() {
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,canvas.width,canvas.height);
fillRoundedPath(polyRadius, polyRadius, hexPoly, cornerRadius, "#000");
fillRoundedPath(polyRadius, polyRadius, hexPolyInner, cornerRadius - barWidth * inset * 2, "#F80");
ctx.lineDashOffset = approxLineLen - (progress % 1) * approxLineLen;
strokeRoundedPath(polyRadius, polyRadius, hexBar, cornerRadius - barWidth * inset, "#09C", barWidth);
progress += 0.005;
requestAnimationFrame(loop);
}
<canvas id="canvas" width = "210" height="210"></canvas>