html环形进度条

最近看到在一个网站是看到了这个这种样式发现它是div+css实现的一般的话是用画布实现的、所以我仿照这个思路写了一个弧形进度条

image.png

使用css和html还有var()函数 实现环形进度条

最终效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SKRLCmNm-1626331310055)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/343bf207b3b244b29be6ff1cf6acb9b8~tplv-k3u1fbpfcp-watermark.image)]

clip属性

w3cschool强调该属性的使用对象是绝对定位的元素
image.png
首先先说这个属性clip属性:clip:rect(top,right,bottom,left)
假如下面的正方形的宽高都是1rem的话我要显示这个正方形的一半一个半(一个高1rem、宽0.5rem)的矩形这个属性要这样写clip:rect(0,0.5rem,1rem,0rem)

image.png

<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这四个条界限中部分

image.png

开始画半圆

既然一个可以从正方形中截取一半显示那半圆就好实现了

    .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)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b7061b5213b24c6eabea5808c12ac488~tplv-k3u1fbpfcp-watermark.image)]

然后旋转这个半圆

在进度条小于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)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/29f4da70f3454934a828644f7540852c~tplv-k3u1fbpfcp-watermark.image)]

在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)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4fcdf0435c90426cba536e412af21367~tplv-k3u1fbpfcp-watermark.image)]

完成超过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>

image.png
大致的相关就出来了

下面是一个完整的代码案例

完整代码

<!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>

猜你喜欢

转载自blog.csdn.net/zhoulib__/article/details/118759137