【前端小知识(一)】环形进度条方案 源码+效果

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

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

最终效果

 预览地址:Document

源码:https://github.com/paiDaXing-web/web.git

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>
复制代码

然后旋转这个半圆

在进度条小于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>
复制代码

在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>
复制代码

完成超过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 Math.abs(this.deg) % 360
                }
            }
        })
    </script>
</body>

</html>
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优价实习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值