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>
<!-- Design:
https://dribbble.com/shots/2987559-SmartHome-App-Dark -->
<div class="gauge" data-digit=60>
<div class="gauge-outer"></div>
<div class="gauge-inner"></div>
<div class="gauge-digits"></div>
</div>
CSS
@charset "UTF-8";
body {
background-color: #1c2039;
}
.gauge {
position: relative;
width: 7em;
height: 5.8em;
margin: 0.5em auto;
font-size: 5em;
direction: ltr;
}
.gauge-inner {
position: relative;
top: -4.85em;
opacity: 0;
transition: opacity 0.5s;
}
.gauge.load .gauge-inner {
opacity: 1;
}
.gauge-inner .bar {
left: 50%;
position: absolute;
transform-origin: 0 2.5em;
width: 0.03em;
height: 0.2em;
background: rgba(255, 255, 255, 0.2);
}
.gauge-inner .bar.peak {
height: 0.35em;
}
.gauge-outer {
position: relative;
height: 100%;
margin-top: 0.3em;
}
.gauge-outer .bar {
position: absolute;
width: 0.05em;
height: 0.7em;
left: 50%;
transform-origin: 0 3.43em;
background-color: rgba(0, 0, 0, 0.2);
opacity: 0;
transition: opacity 0.5s;
}
.gauge.load .gauge-outer .bar {
opacity: 1;
}
.gauge-digits {
position: absolute;
height: 81%;
width: 70%;
top: 1.3em;
left: 50%;
transform: translateX(-50%);
color: rgba(255, 255, 255, 0.4);
opacity: 0;
transition: opacity 0.5s 0.5s;
}
.gauge.load .gauge-digits {
opacity: 1;
}
.gauge-digits.scale {
transform: translateX(-50%) scale(0.8);
}
.gauge-digits .digit {
position: absolute;
font-size: 0.4em;
line-height: 0.2;
}
.gauge-digits .current-digit {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 1.5em;
color: rgba(255, 255, 255, 0.9);
}
.gauge-digits .current-digit:after {
content: "°";
}
JavaScript
document.addEventListener('DOMContentLoaded', function () {
(function () {
const points = 43;
const radius = 257;
const max = 100;
const peaks = [10, 30, 50];
const step = (max + 1) / points;
const realPeaks = peaks.map(peak => Math.floor(peak * (1 / step)));
const hueStep = 120 / points;
const gaugeDigits = document.querySelector('.gauge-digits');
const digit = parseInt(document.querySelector('.gauge').getAttribute('data-digit'));
gaugeDigits.insertAdjacentHTML('beforeend', `<span class="digit current-digit count">0</span>`);
for (let i = 0; i < points; i++) {
const degree = i * (radius / (points - 1)) - radius / 2;
const isPeak = realPeaks.indexOf(i) > -1;
const gaugeInner = document.querySelector('.gauge-inner');
gaugeInner.insertAdjacentHTML('beforeend', `<i class="bar${isPeak ? ' peak' : ''}" style="transform: rotate(${degree}deg)"></i>`);
const intStep = Math.ceil(step * i);
const intNextStep = Math.ceil(step * (i + 1));
let styles = `transition-delay: ${ (i / digit) * (i / digit) + 1 }s;`;
if (intStep <= digit) {
styles += `background-color: hsl(${240 + i * hueStep}, 92%, 64%);`;
}
if (intStep > digit || (intStep <= digit && intNextStep <= digit)) {
styles += `
-webkit-transform: rotate(${degree}deg);
-moz-transform: rotate(${degree}deg);
-ms-transform: rotate(${degree}deg);
-o-transform: rotate(${degree}deg);
transform: rotate(${degree}deg);`;
} else {
if (intNextStep > digit)
styles += `
-webkit-transform: rotate(${degree}deg) translateY(-.3em);
-moz-transform: rotate(${degree}deg) translateY(-.3em);
-ms-transform:...