Semicircle speedometer
Speedometer-style semicircle gauge with a springy needle
Techniques: calc-with-custom-properties · dasharray-zones · rotate · cubic-bezier-overshoot
<!--
============================================================
SVGarden — https://www.svgarden.dev
Author : Simon-Pierre Boucher
Contact: contact@spboucher.ai
File : snippets/gauges/gauge-semicircle.html
Desc : Speedometer-style semicircle gauge with a springy needle
============================================================
-->
<div class="sg-gauge-semicircle" style="--sg-color:#7F77DD; --sg-size:170px; --sg-value:72;">
<svg viewBox="0 0 100 62" role="img" aria-label="Speedometer gauge">
<title>Speedometer gauge</title>
<path class="sg-gauge-semicircle-zone1" d="M10 55 A40 40 0 0 1 90 55" pathLength="100" />
<path class="sg-gauge-semicircle-zone2" d="M10 55 A40 40 0 0 1 90 55" pathLength="100" />
<path class="sg-gauge-semicircle-zone3" d="M10 55 A40 40 0 0 1 90 55" pathLength="100" />
<line class="sg-gauge-semicircle-needle" x1="50" y1="55" x2="50" y2="21" />
<circle class="sg-gauge-semicircle-hub" cx="50" cy="55" r="4.5" />
</svg>
</div>
<style>
.sg-gauge-semicircle {
width: var(--sg-size);
}
.sg-gauge-semicircle svg {
display: block;
width: 100%;
}
.sg-gauge-semicircle path {
fill: none;
stroke-width: 7;
stroke-linecap: round;
}
.sg-gauge-semicircle-zone1 { stroke: #2ba05a; stroke-dasharray: 60 100; }
.sg-gauge-semicircle-zone2 { stroke: #efbb33; stroke-dasharray: 0 60 25 100; }
.sg-gauge-semicircle-zone3 { stroke: #d4553f; stroke-dasharray: 0 85 15 100; }
.sg-gauge-semicircle-needle {
stroke: var(--sg-color);
stroke-width: 3;
stroke-linecap: round;
transform-box: view-box;
transform-origin: 50px 55px;
transform: rotate(calc(var(--sg-value) * 1.8deg - 90deg));
animation: sg-gauge-semicircle-swing 1.2s cubic-bezier(0.3, 1.4, 0.5, 1);
}
.sg-gauge-semicircle-hub {
fill: var(--sg-color);
}
@keyframes sg-gauge-semicircle-swing {
from { transform: rotate(-90deg); }
to { transform: rotate(calc(var(--sg-value) * 1.8deg - 90deg)); }
}
</style>