量规是一种工具,可以直观地指示给定范围内的值。 在计算机中,“磁盘空间指示器”使用量规来显示可用磁盘空间总量。 量规在其范围内具有区域或区域,每种区域或区域都有其自己的颜色。 在前端开发中,我们可以使用<meter>
HTML5标签显示特定范围内的数据。
在本文中,我们将制作一个半圆形的SVG量规 ,并对其进行动画处理。 看一下这个预览GIF,它显示了最终版本在Firefox中的工作方式 :
仪表的范围是0-100 ,并以黄色,蓝色和红色显示三个相等的区域 。 您可以根据需要更改区域的范围和数量。
为了便于说明,我将执行手动计算,并在以下步骤中使用内联SVG属性/属性。
但是,我的最终演示将CSS和JavaScript用于SVG属性的计算和插入,以使其更加灵活。
1.画一个圆
让我们在SVG中画一个简单的圆圈。 HTML5的新<svg>
标记使我们可以将SVG添加到HTML代码中。 在<svg>
标记内,我们添加<circle>
SVG形状,如下所示:
<div id="wrapper">
<svg id="meter">
<circle r="150" cx="50%" cy="50%"></circle>
</svg>
</div>
在CSS中,让我们向包装器添加width
和height
属性,它们都大于或等于圆的直径(在我们的示例中为300px)。 我们还需要将#meter
元素的宽度和高度设置为100%。
#wrapper{
width: 400px;
height: 400px;
}
#meter{
width: 100%;
height: 100%;
}
2.将轮廓添加到圆并删除填充
借助stroke
和stroke-width
SVG属性,我们向圆添加了轮廓,并且通过使用fill="none"
属性,我们也删除了圆的填充。
<circle id="low" r="150" cx="50%" cy="50%" stroke="#FDE47F"
stroke-width="60" fill="none"></circle>
3.仅覆盖半个圆圈
对于半圆轮廓, dash length
值必须等于圆的半周长,以使短划线覆盖圆的一半圆周,并且gap length
值必须等于或大于其余圆周。
如果更多,它将被浏览器转换为剩余的周长,因此我们将使用全周长值作为gap length
。 这样我们可以避免计算剩余周长。
让我们看一下计算:
圆周 = 2 Ã???????¢????? π × [R
其中r是半径。 对于半径150,圆周为:
圆周 = 2 Ã???????¢????? π × 150 圆周 = 942.48
如果我们除以2,我们得到471.24为半圆周,所以值stroke-dasharray
属性用于在150个半径圆半圆形轮廓471, 943
。 该半圆将用于表示仪表的低范围区域。
<!-- Low Range Zone (Yellow) -->
<circle id="low" r="150" cx="50%" cy="50%" stroke="#FDE47F"
stroke-width="60" stroke-dasharray="471, 943" fill="none">
</circle>
如您所见,它是颠倒的,因此,通过将值为rotateX(180deg)
的transform
CSS属性添加到<svg id="meter">
HTML元素中,来打开<svg id="meter">
。
#meter {
transform: rotateX(180deg);
}
4.添加其他区域
<!-- Low Range Zone (Yellow) -->
<circle id="low" r="150" cx="50%" cy="50%" stroke="#FDE47F"
stroke-width="60" stroke-dasharray="471, 943" fill="none"><
/circle>
<!-- Average Range Zone (Blue) -->
<circle id="avg" r="150" cx="50%" cy="50%" stroke="#7CCCE5"
stroke-width="60" stroke-dasharray="314, 943"
fill="none"></circle>
<!-- Low Range Zone (Yellow) -->
<circle id="low" r="150" cx="50%" cy="50%" stroke="#FDE47F"
stroke-width="60" stroke-dasharray="471, 943" fill="none">
</circle>
<!-- Average Range Zone (Blue) -->
<circle id="avg" r="150" cx="50%" cy="50%" stroke="#7CCCE5"
stroke-width="60" stroke-dasharray="314, 943" fill="none">
</circle>
<!-- High Range Zone (Red) -->
<circle id="high" r="150" cx="50%" cy="50%" stroke="#E04644"
stroke-width="60" stroke-dasharray="157, 943" fill="none">
</circle>
5.添加仪表轮廓
让我们在仪表上添加灰色轮廓以使其看起来更好。 轮廓圆的dash length
必须等于半周长。 我们将其放置在代码中的所有其他圆圈之前,这样它将首先由浏览器呈现 ,因此将显示在屏幕上的区域圆圈下方 。
<!-- Meter Outline (Grey) -->
<circle id="outline_curves" r="150" cx="50%" cy="50%"
stroke="#f6f6f6" stroke-width="65"
stroke-dasharray="471, 943" fill="none">
</circle>
<!-- Low Range Zone (Yellow) -->
<circle id="low" r="150" cx="50%" cy="50%" stroke="#FDE47F"
stroke-width="60" stroke-dasharray="471, 943" fill="none"><
/circle>
<!-- Average Range Zone (Blue) -->
<circle id="avg" r="150" cx="50%" cy="50%" stroke="#7CCCE5"
stroke-width="60" stroke-dasharray="314, 943" fill="none">
</circle>
<!-- High Range Zone (Red) -->
<circle id="high" r="150" cx="50%" cy="50%" stroke="#E04644"
stroke-width="60" stroke-dasharray="157, 943" fill="none">
</circle>
由于轮廓未覆盖半圆的末端,因此我们还通过在末端添加两个dash length
为2px, gap length
为半周长减去2px的圆,向末端添加了大约2px的2条线。 因此,该圆的stroke-dasharray
属性值为2, 469
。
<!-- Outline Ends (Grey) -->
<circle id="outline_ends" r="150" cx="50%" cy="50%" stroke="#f9f9f9"
stroke-width="65" stroke-dasharray="2, 469" fill="none"></circle>
现在,让我们在低,平均和高范围区域之后添加另一个圆圈。 当仪表运行时,新的圆圈将用作遮罩,以隐藏不必要的区域。
其属性将与轮廓圆的属性相同,并且其笔触颜色也将为灰色。 稍后将使用Javascript调整遮罩的大小,以响应输入滑块显示其下方的区域。
到目前为止的组合代码如下。
<!-- Meter Outline -->
<circle id="outline_curves" r="150" cx="50%" cy="50%"
stroke="#f6f6f6" stroke-width="65"
stroke-dasharray="471, 943" fill="none">
</circle>
<!-- Low Range Zone (Yellow) -->
<circle id="low" r="150" cx="50%" cy="50%" stroke="#FDE47F"
stroke-width="60" stroke-dasharray="471, 943" fill="none">
</circle>
<!-- Average Range Zone (Blue) -->
<circle id="avg" r="150" cx="50%" cy="50%" stroke="#7CCCE5"
stroke-width="60" stroke-dasharray="314, 943" fill="none">
</circle>
<!-- High Range Zone (Red) -->
<circle id="high" r="150" cx="50%" cy="50%" stroke="#E04644"
stroke-width="60" stroke-dasharray="157, 943" fill="none">
</circle>
<!-- Mask -->
<circle id="mask" r="150" cx="50%" cy="50%" stroke="#f6f6f6"
stroke-width="65" stroke-dasharray="471, 943" fill="none">
</circle>
<!-- Outline Ends -->
<circle id="outline_ends" r="150" cx="50%" cy="50%"
stroke="#f9f9f9" stroke-width="65" stroke-dasharray="2, 469"
fill="none">
</circle>
如果要显示遮罩下方的区域,则需要减小遮罩的dash length
的大小。 例如,当值stroke-dasharray
面具圈的属性是157, 943
,弧线将站在以下状态:
因此,我们现在要做的就是使用JavaScript动画来调整蒙版的stroke-dasharray
。 但是在执行此操作之前,正如我之前提到的,在最后的演示中,我使用CSS和JavaScript计算并添加了大多数SVG属性。
在下面,您可以找到导致与上述结果相同HTML,CSS和JavaScript代码。
HTML
我在用户输入中添加了一个针图像( gauge-needle.svg
),一个范围滑块( input#slider
)和一个标签( label#lbl
),以显示滑块值在0-100的范围内。
<div id="wrapper">
<svg id="meter">
<circle id="outline_curves" class="circle outline"
cx="50%" cy="50%"></circle>
<circle id="low" class="circle range" cx="50%" cy="50%"
stroke="#FDE47F"></circle>
<circle id="avg" class="circle range" cx="50%" cy="50%"
stroke="#7CCCE5"></circle>
<circle id="high" class="circle range" cx="50%" cy="50%"
stroke="#E04644"></circle>
<circle id="mask" class="circle" cx="50%" cy="50%" >
</circle>
<circle id="outline_ends" class="circle outline"
cx="50%" cy="50%"></circle>
</svg>
<img id="meter_needle" src="gauge-needle.svg" alt="">
<input id="slider" type="range" min="0" max="100" value="0" />
<label id="lbl" id="value" for="">0</label>
</div>
CSS
下面CSS代码为SVG添加了样式规则,因为SVG形状的样式可以与HTML元素相同。 如果您想了解更多有关如何使用CSS设置SVG样式的信息,请阅读这篇文章 。 要设置滑块的样式,请查看此文章 。
#wrapper {
position: relative;
margin: auto;
}
#meter {
width: 100%; height: 100%;
transform: rotateX(180deg);
}
.circle {
fill: none;
}
.outline, #mask {
stroke: #F1F1F1;
stroke-width: 65;
}
.range {
stroke-width: 60;
}
#slider, #lbl {
position: absolute;
}
#slider {
cursor: pointer;
left: 0;
margin: auto;
right: 0;
top: 58%;
width: 94%;
}
#lbl {
background-color: #4B4C51;
border-radius: 2px;
color: white;
font-family: 'courier new';
font-size: 15pt;
font-weight: bold;
padding: 4px 4px 2px 4px;
right: -48px;
top: 57%;
}
#meter_needle {
height: 40%;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 10%;
transform-origin: bottom center;
/*orientation fix*/
transform: rotate(270deg);
}
JavaScript
在JavaScript中,首先我们计算并设置包装器和所有圆弧的尺寸,然后将适当的stroke-dasharray
值添加到圆中。 之后,我们将自定义事件绑定到范围滑块以执行动画。
/* Set radius for all circles */
var r = 250;
var circles = document.querySelectorAll('.circle');
var total_circles = circles.length;
for (var i = 0; i < total_circles; i++) {
circles[i].setAttribute('r', r);
}
/* Set meter's wrapper dimension */
var meter_dimension = (r * 2) + 100;
var wrapper = document.querySelector("#wrapper");
wrapper.style.width = meter_dimension + "px";
wrapper.style.height = meter_dimension + "px";
/* Add strokes to circles */
var cf = 2 * Math.PI * r;
var semi_cf = cf / 2;
var semi_cf_1by3 = semi_cf / 3;
var semi_cf_2by3 = semi_cf_1by3 * 2;
document.querySelector("#outline_curves")
.setAttribute("stroke-dasharray", semi_cf + "," + cf);
document.querySelector("#low")
.setAttribute("stroke-dasharray", semi_cf + "," + cf);
document.querySelector("#avg")
.setAttribute("stroke-dasharray", semi_cf_2by3 + "," + cf);
document.querySelector("#high")
.setAttribute("stroke-dasharray", semi_cf_1by3 + "," + cf);
document.querySelector("#outline_ends")
.setAttribute("stroke-dasharray", 2 + "," + (semi_cf - 2));
document.querySelector("#mask")
.setAttribute("stroke-dasharray", semi_cf + "," + cf);
/* Bind range slider event*/
var slider = document.querySelector("#slider");
var lbl = document.querySelector("#lbl");
var mask = document.querySelector("#mask");
var meter_needle = document.querySelector("#meter_needle");
function range_change_event() {
var percent = slider.value;
var meter_value = semi_cf - ((percent * semi_cf) / 100);
mask.setAttribute("stroke-dasharray", meter_value + "," + cf);
meter_needle.style.transform = "rotate(" +
(270 + ((percent * 180) / 100)) + "deg)";
lbl.textContent = percent + "%";
}
slider.addEventListener("input", range_change_event);
自定义
仪表的行为由range_change_event()
自定义函数执行,该函数负责调整蒙版大小和针的动画。
它获取介于0到100之间的滑块值(用户输入),并将其转换为471-0(值是半径150的半周长)之间的半周长等效值( meter_value
),并将该meter_value
设置为遮罩的stroke-dasharray
属性的dash length
。
在将用户输入(在0-100范围内)转换为等效于0-180的度数之后, range_change_event()
定制函数还会旋转指针。
在上面的代码中将270°添加到针的旋转中,因为我使用的图像是垂直的针,因此我必须首先将其旋转270°才能使其向左平放。
最后,我将range_change_event()
函数绑定到范围滑块,以便可以使用它来操作仪表。
观看演示或在我们的Github存储库中查看源代码。
翻译自: https://www.hongkiat.com/blog/svg-meter-gauge-tutorial/