36 lines
2.3 KiB
HTML
36 lines
2.3 KiB
HTML
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;font-family:'Segoe UI',system-ui,sans-serif;background:linear-gradient(135deg,#0a0a14,#1a1a30);">
|
|
<svg viewBox="0 0 300 200" width="90%" style="max-width:500px;">
|
|
<defs>
|
|
<linearGradient id="rpmGrad" x1="0" y1="0" x2="1" y2="0">
|
|
<stop offset="0%" stop-color="#667eea"/>
|
|
<stop offset="40%" stop-color="#667eea"/>
|
|
<stop offset="70%" stop-color="#f39c12"/>
|
|
<stop offset="100%" stop-color="#e74c3c"/>
|
|
</linearGradient>
|
|
</defs>
|
|
<path d="M 50,170 A 100,100 0 0,1 250,170" fill="none" stroke="rgba(255,255,255,0.08)" stroke-width="18" stroke-linecap="round"/>
|
|
<path id="rpm-arc" d="M 50,170 A 100,100 0 0,1 250,170" fill="none" stroke="url(#rpmGrad)" stroke-width="18" stroke-linecap="round"
|
|
stroke-dasharray="314" stroke-dashoffset="314" style="transition:stroke-dashoffset 0.1s ease;"/>
|
|
<text x="150" y="150" text-anchor="middle" fill="#fff" font-size="48" font-weight="900" data-bind="rpm">0</text>
|
|
<text x="150" y="180" text-anchor="middle" fill="rgba(255,255,255,0.5)" font-size="14">RPM</text>
|
|
<text x="42" y="185" text-anchor="middle" fill="rgba(255,255,255,0.3)" font-size="10">0</text>
|
|
<text x="258" y="185" text-anchor="middle" fill="rgba(255,255,255,0.3)" font-size="10">8k</text>
|
|
</svg>
|
|
<div data-bind-rpm style="display:none;">
|
|
<script>
|
|
(function() {
|
|
const arc = document.getElementById('rpm-arc');
|
|
const observer = new MutationObserver(() => {
|
|
const rpm = parseFloat(getComputedStyle(document.querySelector('[data-bind-rpm]')).getPropertyValue('--rpm')) || 0;
|
|
const max = parseFloat(getComputedStyle(document.querySelector('[data-bind-rpm]')).getPropertyValue('--rpm-max')) || 8000;
|
|
if (!isNaN(rpm) && arc) {
|
|
const pct = Math.min(rpm / max, 1);
|
|
arc.setAttribute('stroke-dashoffset', 314 - (314 * pct));
|
|
}
|
|
});
|
|
observer.observe(document.querySelector('[data-bind-rpm]'), { attributes: true, attributeFilter: ['style'] });
|
|
})();
|
|
</script>
|
|
</div>
|
|
</div>
|