Как сделать анимацию линии спидометра с выводом числовых значений скорости
Необходимо сделать подобный спидометр
но я мало работал с svg, поэтому прошу помощи) Будет достаточно хотя бы направления, куда копать, как гуглить. Может какие то ссылки на похожие примеры. Заранее благодарен!
Ответы (2 шт):
В принципе, можно управлять увеличчением скорости с помощью input type="range" из которого на javascript можно олучить value и присвоить его маске которая по сути дублирует наш с вами path через use то есть на самом деле мы увеличиваем/уменьшаем ширину(width) этого самого rect который имеет более яркую расцветку
Ну и соббственно весь мой код смотрите в работе
let range = document.getElementById("inp");
let rect = document.querySelector("#rect");
let text = document.querySelector("#text");
let data = document.querySelector("#data");
range.oninput = function() {
rect.style.width = this.value + "%";
text.innerHTML = this.value;
data.setAttribute("x", 50 + this.value / 10);
}
<svg width="200px" viewBox="0 0 152.97 49.075" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="mask">
<rect width="100%" height="100%" fill="#000" />
<use href="#path" fill="#fff" />
</mask>
</defs>
<path id="path" d="m2.4223 48.852c3.0345-33.053 23.447-46.321 49.398-46.376 18.889-0.04009 41.213-0.15614 65.136 0.29209 10.311 0.19319 21.446-0.18148 35.939 0.24748" fill="none" stroke="#ccc" stroke-width="4.8"/>
<rect id="rect" width="50%" height="100%" fill="#F50D86" mask="url(#mask)" />
<text id="text" x="20" y="49" style="text-transform: uppercase; font-size: 20px; font-family: sans-serif; font-weight: 900;" fill="#000">20</text>
<text id="data" x="50" y="49" style="text-transform: uppercase; font-family: sans-serif; font-size: 14px; font-weight: 100;" fill="#000">км.ч</text>
</svg>
<input style="display: block; margin-top: 50px; width: 200px;" id="inp" type="range" min="20" max="100" value="20">
Решение stroke-dasharray
Для решения используются значения параметров атрибута path
stroke-dasharray="dash,gap", где
dash - тире
gap - пробел
максимальная длина линии получена с помощью метода JS getTotalLength() и равна 664.4px
при значении
stroke-dasharray="0,664.4"линия спидометра будет полностью скрыта, так черта имеет нулевое значение, а пробел равен максимальной длинепри значении
stroke-dasharray="664.4;0"линия спидометра будет полностью нарисована, так как длина черты имеет максимальное значение
На этом и основана анимация рисования линии спидометра от нуля до максимума
Анимация начинается при наведении курсора
.container {
width:75vw;
height:75vh;
}
svg {
background:#131525;
}
#trace {
fill:none;
stroke:#444551;
stroke-width:16;
}
#velocity {
fill:none;
stroke:#F9118D;
stroke-width:16;
stroke-dasharray:0,664.4;
}
svg:hover #velocity {
animation: move 5s forwards;
}
@keyframes move {
to{stroke-dasharray:664.4,0}
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" preserveAspectRatio="xMinYMin meet" fill="#131525" id="svg4" viewBox="0 0 650 243">
<path id="trace" d="M60.4 215.2c.4-19.4 3.9-30.8 8-45.6a171 171 0 0 1 14.2-36.3c9-16.1 13.4-20.8 20.7-30.2 7.6-9.7 17.8-17.3 27.8-24.6 8.5-6.1 17.5-11.5 27-15.9 12-5.5 24.5-9.9 37.4-12.7 10.4-2.3 21.1-2.6 31.8-3.2 15.6-.9 46.8-.8 46.8-.8l355.2-.8" />
<path id="velocity" d="M60.4 215.2c.4-19.4 3.9-30.8 8-45.6a171 171 0 0 1 14.2-36.3c9-16.1 13.4-20.8 20.7-30.2 7.6-9.7 17.8-17.3 27.8-24.6 8.5-6.1 17.5-11.5 27-15.9 12-5.5 24.5-9.9 37.4-12.7 10.4-2.3 21.1-2.6 31.8-3.2 15.6-.9 46.8-.8 46.8-.8l355.2-.8" />
</svg>
</div>
Анимация при управлении input
Я выбрал максимальное значение спидометра 360 км/ч Это max = "360" input
Принцип анимации линии спидометра точно такой же, как и в примере выше- увеличение dash и уменьшение gap
let total = velocity.getTotalLength(),
input = document.querySelector("[type='range']"),
txt = document.querySelector("#txt1");
input.addEventListener("input",()=>{
speedometr();
})
window.addEventListener("load",()=>{
speedometr();
})
function speedometr(){
let val = Number(input.value);
let dash = total * val / 360;
let gap = total - dash;
velocity.style.strokeDasharray = dash + " " + gap
txt.innerHTML = (val + "км/ч");
}
.container {
width:70vw;
height:70vh;
}
svg {
background:#131525;
}
#trace {
fill:none;
stroke:#444551;
stroke-width:16;
stroke-dasharray:664.4,0;
}
#velocity {
fill:none;
stroke:#F9118D;
stroke-width:16;
stroke-dasharray:0,664.4;
}
<div class="container">
<div><input id="size" type="range" min="0" step="10" max = "360" value="0" /></div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" preserveAspectRatio="xMinYMin meet" fill="#131525" id="svg4" viewBox="0 0 650 243">
<path id="trace" d="M60.4 215.2c.4-19.4 3.9-30.8 8-45.6a171 171 0 0 1 14.2-36.3c9-16.1 13.4-20.8 20.7-30.2 7.6-9.7 17.8-17.3 27.8-24.6 8.5-6.1 17.5-11.5 27-15.9 12-5.5 24.5-9.9 37.4-12.7 10.4-2.3 21.1-2.6 31.8-3.2 15.6-.9 46.8-.8 46.8-.8l355.2-.8" />
<path id="velocity" d="M60.4 215.2c.4-19.4 3.9-30.8 8-45.6a171 171 0 0 1 14.2-36.3c9-16.1 13.4-20.8 20.7-30.2 7.6-9.7 17.8-17.3 27.8-24.6 8.5-6.1 17.5-11.5 27-15.9 12-5.5 24.5-9.9 37.4-12.7 10.4-2.3 21.1-2.6 31.8-3.2 15.6-.9 46.8-.8 46.8-.8l355.2-.8" />
<text id="txt1" y="60%" x="50%" font-family="sans-serif" text-anchor="middle" font-size="56px" fill="white">100 км/ч</text>
</svg>
</div>
