1.功能描述
- 仪表盘与指针自适应宽度,保持宽高比,保持指针位置
- 保留指针旋转动画效果
- 根据返回结果计算指针角度
2 效果展示

3 实现
3.1 实现仪表盘
- 使用padding撑开高度,保持宽高比
- 使用before伪元素绘制仪表盘,锥形渐变实现颜色由浅到深
- 使用after伪元素覆盖中心位置
- 指针我使用的字体图标,使用 vw 单位设置大小和位置
<div class="conic-wrap">
<div class="conic">
<span class="pointer icon icon-Pointer"></span>
</div>
</div>
<div>
<el-button @click="testSpeed">Run Speed Test</el-button>
</div>
.conic-wrap {
padding: 0 12%;
}
.conic {
padding-bottom: 100%;
position: relative;
overflow: hidden;
}
.conic::before {
content:"";
position: absolute;
display: block;
top: 0;
left: 0;
right:0;
bottom:0;
border-radius: 50%;
transform: rotate(-180deg);
background:
conic-gradient(
#fff 70deg,
#e7edf6 70deg,
#215db6 290deg,
#fff 290deg,
#fff 360deg
);
}
.conic::after {
content:"";
position: absolute;
display: block;
width: 60%;
height: 60%;
border-radius: 50%;
background-color: #fff;
top: 50%;
left:50%;
transform: translate(-50%,-50%);
}
.conic span.pointer {
position: absolute;
color: #215db6;
transform-origin: center 70%;
z-index: 1;
left: calc(50% - 2.6vw);
top: calc(50% - 3.2vw);
z-index: 1;
font-size: 5.4vw;
cursor: auto;
transform:rotate(v-bind(pointerDeg));
transition: all .5s cubic-bezier(.14,1.24,.96,.77);
}
.in-animation{
animation: pointerMove 1.5s ease-in-out;
}
@keyframes pointerMove {
from{
transform:rotate(-102deg);
}
10% {
transform:rotate(-104deg);
}
to {
transform:rotate(v-bind(pointerDeg));
}
}
3.2 保持动画效果
- 每次更改指针角度后,调用 makeAnimate 方法,为指针重新添加动画效果,当执行结束后再移除
makeAnimate() {
document.querySelector('span.pointer').addEventListener('animationend', function () {
this.classList.remove('in-animation')
})
document.querySelector('span.pointer').classList.add('in-animation')
},
3.3 动态更改指针角度
- vue3 支持在 css 中使用 data 属性
- 示例 v-bind(data属性名称)
.conic span.pointer {
transform:rotate(v-bind(pointerDeg));
}