JSFiddle - React, Tailwind, and code Playground
HTML
<html>
<body>
<input type="number" id="P" name="P" value="0"><input type="button" name="anim" id="anim" value="Animate progress bar"/>
<div style="width:100%;height:50px;background-color:grey">
<div id="output" style="width:0%;height:30px;padding-top:10px;background-color:green">
</div>
</div>
</body>
</html>
JavaScript
window.addEventListener("load", (ev) => {
let euro_points = [0, 10, 80, 100]; //The milestones in euros
let percent_points = [0, 25, 50, 100]; //The milestones in percent on the scale
let p = document.getElementById("P");
let o = document.getElementById("output");
p.addEventListener("change", () => {
o.innerHtml = p.value;
//Find the highest euro_points variable which is still smaller than the input value
let i = 0;
for (i = 0; i < euro_points.length; i++) {
if (euro_points[i] > p.value)
break;
}
//we are 1 too high
i = i - 1;
if (i == euro_points.length - 1) { // We hit the top, do whatever you want, if you do nothing, you access euro_points and percent_points past the array size
o.style.width = "100%";
o.style["background-color"] = "blue";
o.innerText = "Saturate at highest level";
return;
}
//Compute a linear regression between the two nearest points
let p_val = percent_points[i] + (p.value - euro_points[i]) / (euro_points[i + 1] - euro_points[i]) * (percent_points[i + 1] - percent_points[i]);
//Visualize
o.style["background-color"] = "green";
o.style.width = p_val + "%";
o.innerText = p.value + " i=" + i;
});
//animation, not relevant, only for demonstration
let do_anim = false;
document.getElementById("anim").addEventListener("click", () => {
do_anim ^= true;
});
window.setInterval(() => {
if (do_anim) {
if (p.value >= 150) {
p.value = 0;
} else {
p.value -= -0.5;
}
p.dispatchEvent(new Event("change"));
}
}, 50);
});