最近看到在一个网站是看到了这个这种样式发现它是div+css实现的一般的话是用画布实现的、所以我仿照这个思路写了一个弧形进度条
使用css和html还有var()函数 实现环形进度条
最终效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SKRLCmNm-1626331310055)()]
clip属性
w3cschool强调该属性的使用对象是绝对定位的元素
首先先说这个属性clip属性:clip:rect(top,right,bottom,left)
假如下面的正方形的宽高都是1rem的话我要显示这个正方形的一半一个半(一个高1rem、宽0.5rem)的矩形这个属性要这样写clip:rect(0,0.5rem,1rem,0rem)
<div style="position: relative;width: 1rem;height:1rem;">
<div style="position: absolute;width: 1rem;height:1rem;background: red;clip:rect(0,0.5rem,1rem,0);"></div>
</div>
相当于这个正方形从top=0到bottom=1rem和left=0到right=0.5rem这四个条界限中部分
开始画半圆
既然一个可以从正方形中截取一半显示那半圆就好实现了
.half_circle{
position: absolute;
width: 1rem;
height:1rem;
clip:rect(0,0.5rem,1rem,0);
border-radius:50%;
box-sizing:border-box;
/* 这个属性是盒子模型的类型可以让border的宽度算入盒子的宽度 */
border:0.08rem solid red
}
<div style="position: relative;width: 1rem;height:1rem;">
<div class="half_circle"></div>
</div>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KwmPQwjs-1626331310062)()]
然后旋转这个半圆
在进度条小于50%时 整个进度条的圆弧的弧度不会超过整个半圆的范围
.half_circle{
position: absolute;
width: 1rem;
height:1rem;
clip:rect(0,0.5rem,1rem,0);
border-radius:50%;
box-sizing:border-box;
/* 这个属性是盒子模型的类型可以让border的宽度算入盒子的宽度 */
border:0.08rem solid red;
transform: rotate(50deg)
}
<div style="position: relative;width: 1rem;height:1rem;">
<div class="half_circle"></div>
</div>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A4nqRA0Q-1626331310064)()]
在50%以下的进度条
.half_circle_box{
clip:rect(0,1rem,1rem,0.5rem);
position: absolute;
width: 1rem;
height:1rem;
}
.half_circle{
position: absolute;
width: 1rem;
height:1rem;
clip:rect(0,0.5rem,1rem,0);
border-radius:50%;
box-sizing:border-box;
/* 这个属性是盒子模型的类型可以让border的宽度算入盒子的宽度 */
border:0.08rem solid red;
transform: rotate(50deg)
}
<div style="position: relative;width: 1rem;height:1rem;">
<div class="half_circle_box">
<div class="half_circle"></div>
</div>
</div>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-45kM2hdV-1626331310065)()]
完成超过50%的进度圆弧
现在50%以下的进度条就算完成了,然后时超过50%的
显然一个半圆是完成不了的然后就要显示另一个半圆
当我要显示240deg的圆弧时 可以看出两个半圆一个旋转180deg一个选择60deg就是240deg
.half_circle_box{
/* clip:rect(0,1rem,1rem,0.5rem); */
position: absolute;
width: 1rem;
height:1rem;
}
.half_circle{
position: absolute;
width: 1rem;
height:1rem;
clip:rect(0,0.5rem,1rem,0);
border-radius:50%;
box-sizing:border-box;
/* 这个属性是盒子模型的类型可以让border的宽度算入盒子的宽度 */
border:0.08rem solid red;
transform: rotate(180deg)
}
.other_half_circle{
position: absolute;
width: 1rem;
height:1rem;
clip:rect(0,1rem,1rem,0.5rem);
border-radius:50%;
box-sizing:border-box;
border:0.08rem solid red;
transform: rotate(60deg)
}
<div style="position: relative;width: 1rem;height:1rem;">
<div class="half_circle_box">
<div class="half_circle"></div>
<div class="other_half_circle"></div>
</div>
</div>
大致的相关就出来了
下面是一个完整的代码案例
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
html {
font-size: 160px;
}
.circle {
position: relative;
/* font-size: 193px; */
width: 1rem;
height: 1rem;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
background-color: #e7ebe3;
}
.circle:after {
position: absolute;
top: 0.08rem;
left: 0.08rem;
display: block;
content: " ";
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
background-color: white;
width: 0.84rem;
height: 0.84rem;
-webkit-transition-property: all;
-moz-transition-property: all;
-o-transition-property: all;
transition-property: all;
-webkit-transition-duration: 0.2s;
-moz-transition-duration: 0.2s;
-o-transition-duration: 0.2s;
transition-duration: 0.2s;
-webkit-transition-timing-function: ease-in;
-moz-transition-timing-function: ease-in;
-o-transition-timing-function: ease-in;
transition-timing-function: ease-in;
}
.circle .slice {
position: absolute;
width: 1rem;
height: 1rem;
}
.bar {
width: 1rem;
height: 1rem;
position: absolute;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
border: 0.08rem solid #307bbb;
box-sizing: border-box;
clip: rect(0, 0.5rem, 1rem, 0rem);
/* 截出一个半圆 */
transform: rotate(calc(1deg * var(--deg)));
}
.fill {
width: 1rem;
height: 1rem;
position: absolute;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
border: 0.08rem solid #307bbb;
box-sizing: border-box;
clip: rect(0, 1rem, 1rem, 0.5rem);
/* 截出一个半圆 */
transform: rotate(calc(1deg * var(--deg)));
}
</style>
<body>
<div v-cloak id="app">
<div class="circle">
<div
style="position: absolute;z-index: 999;width: 1rem;height:1rem;display: flex;flex-direction: column;justify-content: center;align-items: center;font-size: 20px;">
<div>
{{circleDeg}}deg
</div>
<div>
{{(circleDeg / 360) | toFixed2}}%
</div>
</div>
<div :style="circleDeg > 180 ? '' : 'clip: rect(0, 1rem, 1rem, 0.5rem);'" class="slice">
<div :style="{'--deg':circleDeg > 180 ? 180 : circleDeg}" class="bar"></div>
<div v-if="circleDeg > 180" :style="{'--deg':circleDeg - 180}" class="fill"></div>
</div>
</div>
<!-- <span>22%</span> -->
角度:<input v-model="deg" type="number" />
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data: function () {
return {
deg: 45
}
},
filters:{
toFixed2:function(num){
return (num * 100).toFixed(2)
}
},
computed: {
circleDeg: function () {
return this.deg % 360
}
}
})
</script>
</body>
</html>