svg动画制作_如何制作动画SVG车速表

量规是一种工具,可以直观地指示给定范围内的值。 在计算机中,“磁盘空间指示器”使用量规来显示可用磁盘空间总量。 量规在其范围内具有区域或区域,每种区域或区域都有其自己的颜色。 在前端开发中,我们可以使用<meter> HTML5标签显示特定范围内的数据。

在本文中,我们将制作一个半圆形SVG量规 ,并对其进行动画处理。 看一下这个预览GIF,它显示了最终版本在Firefox中的工作方式

仪表的范围是0-100 ,并以黄色,蓝色和红色显示三个相等的区域 。 您可以根据需要更改区域的范围和数量。

为了便于说明,我将执行手动计算,并在以下步骤中使用内联SVG属性/属性。

演示GIF

但是,我的最终演示将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中,让我们向包装器添加widthheight属性,它们都大于或等于圆的直径(在我们的示例中为300px)。 我们还需要将#meter元素的宽度和高度设置为100%。

#wrapper{
  width: 400px;
  height: 400px;
}

#meter{
  width: 100%;
  height: 100%;
}
2.将轮廓添加到圆并删除填充

借助strokestroke-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/

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值