JSFiddle - React, Tailwind, and code Playground
by ckissi
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="speedtest">
<svg id="gauge" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<path style="fill: #e31212;" d="M12.9,75.5c0.3,0.5,0.7,0.9,1,1.4l7.6-5.7c-0.3-0.4-0.5-0.7-0.8-1.1L12.9,75.5z"/>
<path style="fill: #ea1f39; display: none;" d="M9.3,69.3c0.3,0.5,0.5,1,0.8,1.5l8.4-4.4c-0.2-0.4-0.4-0.8-0.6-1.2L9.3,69.3z"/>
<path style="fill: #f12d60; display: none;" d="M6.7,62.4C6.9,62.9,7,63.5,7.2,64l9.1-3c-0.1-0.4-0.3-0.8-0.4-1.2L6.7,62.4z"/>
<path style="fill: #f83c85; display: none;" d="M5.3,55.2c0,0.6,0.1,1.1,0.2,1.7l9.4-1.5c-0.1-0.4-0.1-0.9-0.2-1.3L5.3,55.2z"/>
<path style="fill: #ff4ba8; display: none;" d="M5,47.9c0,0.6,0,1.1,0,1.7l9.5,0.1c0-0.5,0-0.9,0-1.4L5,47.9z"/>
<path style="fill: #fb3eb2; display: none;" d="M5.9,40.7c-0.1,0.6-0.2,1.1-0.3,1.7L15,44c0.1-0.4,0.2-0.9,0.2-1.3L5.9,40.7z"/>
<path style="fill: #f732bf; display: none;" d="M8,33.7c-0.2,0.5-0.4,1.1-0.6,1.6l9,3.1c0.1-0.4,0.3-0.9,0.5-1.3L8,33.7z"/>
<path style="fill: #f226cd; display: none;" d="M11.2,27.1c-0.3,0.5-0.5,1-0.8,1.5l8.3,4.6c0.2-0.4,0.4-0.8,0.7-1.2L11.2,27.1z"/>
<path style="fill: #ee1adc; display: none;" d="M15.5,21.2c-0.4,0.4-0.8,0.9-1.1,1.3l7.5,5.8c0.3-0.4,0.6-0.7,0.9-1.1L15.5,21.2z"/>
<path style="fill: #ae19de; display: none;" d="M20.6,16c-0.5,0.3-0.9,0.7-1.3,1.1l6.5,7c0.3-0.3,0.6-0.6,1-0.9L20.6,16z"/>
<path style="fill: #6618cd; display: none;" d="M26.4,11.7c-0.5,0.3-0.9,0.6-1.4,0.9l5.3,7.9c0.3-0.2,0.7-0.5,1-0.7L26.4,11.7z"/>
<path style="fill: #2716bd; display: none;" d="M33,8.3c-0.6,0.2-1.1,0.5-1.6,0.7l3.9,8.7c0.4-0.2,0.9-0.4,1.3-0.6L33,8.3z"/>
<path style="fill: #1537ac; display: none;" d="M39.9,6.1c-0.5,0.1-1.1,0.3-1.6,0.4l2.5,9.2c0.4-0.1,0.8-0.2,1.2-0.3L39.9,6.1z"/>
<path style="fill: #2061c1; display: none;"...
CSS
html, body {
height: 100%;
}
body {
background-image: linear-gradient(rgba(0, 0, 0, 0.25), rgba(255, 255, 255, 0.25) 50%, rgba(255, 255, 255, 0) 50%), linear-gradient(#e31212, #e31212 50%, #fff 50%);
display: flex;
align-items: center;
justify-content: center;
font-family: "Nunito", sans-serif;
}
#speedtest {
position: relative;
width: 400px;
height: 400px;
padding: 20px;
border-radius: 6px;
box-sizing: border-box;
}
#speedtest #gauge {
width: 100%;
height: 100%;
padding: 12px;
background: #fff;
border-radius: 50%;
box-shadow: 0 0 32px rgba(21, 55, 172, 0.25), inset 0 -192px 192px -240px #e31212;
box-sizing: border-box;
}
#speedtest #gauge path:first-child {
opacity: 1 !important;
display: block !important;
}
#speedtest #gauge-label {
position: absolute;
top: 47.5%;
left: 50%;
font-size: 64px;
transform: translate(-50%, -50%);
color: #e31212;
}
#speedtest #gauge-label:after {
content: "Mbit/s";
position: absolute;
font-size: 35%;
bottom: 5px;
left: 50%;
transform: translate(-50%, 100%);
}
#speedtest:before, #speedtest:after {
display: block;
position: absolute;
bottom: 25%;
font-family: inherit;
font-size: 14px;
color: #9198af;
}
#speedtest:before {
content: "0";
left: 28%;
}
#speedtest:after {
content: "100";
right: 28%;
}
JavaScript
var delay = 2000, value = 0, valueStore = 0, tick = 1, tickStore = 1, tickDiff = 0, tickDiffValue = 0;
function valBetween(v, min, max) {
return Math.min(max, Math.max(min, v));
}
function loop() {
value = Math.ceil(Math.random() * 100);
tick = valBetween(Math.ceil((value / 100) * 28), 1, 28);
tickDiff = Math.abs(tick - tickStore);
tickDiffValue = Math.abs(value - valueStore) / tickDiff;
console.log("tickDiff: " + tickDiffValue + " * " + tickDiff + " = " + (tickDiffValue * tickDiff));
var counter = 0, valueStoreTemp = valueStore, tickStoreTemp = tickStore;
var gauge = document.getElementById('gauge');
var gaugePaths = gauge.getElementsByTagName('path');
if (value > valueStore) {
for (var i = tickStoreTemp; i <= tick; i++) {
(function (i) {
setTimeout(function () {
gauge.style.boxShadow = '0 0 32px rgba(21, 55, 172, 0.25), inset 0 -192px 192px -240px ' + gaugePaths[i - 1].style.fill + ', inset 0 0 2px -1px ' + gaugePaths[i - 1].style.fill;
gaugePaths[i - 1].style.display = 'block';
document.getElementById('gauge-label').style.color = gaugePaths[i - 1].style.fill;
document.getElementById('gauge-label').textContent = Math.ceil(valueStoreTemp + (tickDiffValue * Math.abs(tickStoreTemp - i)));
if (i == tick) { document.getElementById('gauge-label').textContent = value; }
}, 50 * counter);
counter++;
}(i));
}
} else if (value < valueStore) {
for (var i = tickStoreTemp; i >= tick; i--) {
(function (i) {
setTimeout(function () {
gauge.style.boxShadow = '0 0 32px rgba(21, 55, 172, 0.25), inset 0 -192px 192px -240px ' + gaugePaths[i - 1].style.fill + ', inset 0 0 2px -1px ' + gaugePaths[i - 1].style.fill;
gaugePaths[i - 1].style.display = 'none';
...