const SVG_NS = 'http://www.w3.org/2000/svg';
const CIRCUMFERENCE = base.getTotalLength()
const UNIT = CIRCUMFERENCE / 100;
let circles=[];//the array of circles
//create 100 circles each with a different fill color to create the illusion of a gradient
for(let i = 0; i<100; i++){
let pos = base.getPointAtLength(i*UNIT);
let o = {cx:pos.x,cy:pos.y,r:5.5,'fill-opacity':0,fill:`hsl(220,100%,${50 + (100-i)/2}%)`}
circles.push(drawCircle(o, progress__value));
}
progress();
control.addEventListener('input', progress);
function progress(){
let val = control.valueAsNumber;
for(let i = 0; i<circles.length; i++){
if(i<=val){
circles[i].setAttributeNS(null,'fill-opacity',1)
}else{
circles[i].setAttributeNS(null,'fill-opacity',0)
}
}
}
// a function to create a circle
function drawCircle(o, parent) {
var circle = document.createElementNS(SVG_NS, 'circle');
for (var name in o) {
if (o.hasOwnProperty(name)) {
circle.setAttributeNS(null, name, o[name]);
}
}
parent.appendChild(circle);
return circle;
}
svg{border:solid}
.demo {
flex-direction: column;
display: flex;
width: 120px;
}
.progress__meter{
fill: none;
}
.progress__meter {
stroke: grey;
}
<div class="demo">
<svg class="progress" viewBox="-2 -2 124 124">
<path class="progress__meter" id="base" d="M60,6A54,54 0 0 1 60,114A54,54 0 0 1 60,6z" stroke-width="12" />
<g id="progress__value"></g>
</svg>
<input id="control" type="range" value="60" />
</div>