实现一个环形进度条

前两天偶然看到这个题目,抽空做了一下
环形进度条
话不多说,看看具体怎么实现的叭
如果是对其前端比较熟悉的人,看到这个图应该大致知道有哪几个点啦,比如用到了同心圆、旋转。
1.画两种不同背景色的圆(我这里是旋转的浅色,把深色作为底色,在浅色旋转的过程中,深色一步步露出来)
2.浅色部分是两个圆切割出的两个半圆,一个左半圆,一个右半圆
3.右半圆旋转180°后,置它的背景色为底色,位置归位
4.然后左半圆旋转,180°后停止
5.中间是用一个小一点的白色背景圆遮住形成圆的效果,数字用定时器模拟0-100的变化
以上需要注意的是,旋转度数是根据中间的数字*360°计算的,由于左半圆开始旋转时中间数字已经为50%,故左半圆的旋转度数还要减去180°。
几个用到的CSS属性:
border-radius --画圆
transform:rotate(xdeg) --旋转
clip:rect(top,right,bottom,left) --切割半圆

先看html代码

<!-- 最外面是深色圆 -->
  <div class="circle-bar">
      <!-- 里面两个是两个半圆 -->
      <div class="left-circle-bar"></div>
      <div class="right-circle-bar"></div>
      <!-- 然后是中间白色部分 -->
      <div class="mask">
          <span>0%</span>
      </div>
  </div>

css代码

		/* 画圆 */
        .circle-bar, .circle-bar > *  {
            border-radius: 50%;
        }
        /* 实现同心圆,也就是让所有子元素都有一样的绝对定位 */
        .circle-bar > *{
            position: absolute;
            top:0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
        }
        /* 用font-size可以让容器与子元素的宽高用相对单位em,这样只要改变font-size大小,整个形状都能改变*/
        .circle-bar{
            font-size: 200px;
            height: 1em;
            width: 1em;
            background-color:rgb(221, 42, 42);
            position: relative;
        }
        .left-circle-bar,.right-circle-bar{
            height:1em;
            width:1em;
            background-color: lightcoral;
        }
        /*切割半圆*/
        .left-circle-bar{
            clip: rect(0,0.5em,1em,0);
        }
        .right-circle-bar{
            clip: rect(0,1em,1em,0.5em);
        }
        /*白色部分,用了flex布局使百分比垂直居中显示*/
        .circle-bar .mask{
            height:0.8em;
            width: 0.8em;
            background-color: white;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .circle-bar .mask span{
            font-size: 0.25em;
        }

以上就是实现了静态的页面,看起来是这样
静态环形进度条
然后要做的就是百分比模拟0-100变化,半圆的旋转与中间的百分比进行绑定,这里有两个注意点:
1.监控中间span元素的变化
onchange事件监听只能作用于input text等输入框,而普通的文本元素如何监听呢,我们有DOMNodeInserted,那么怎样的文本变化形式可以触发这个事件呢?
使用DOMElement.innerHTML = '50%'方法改变的span内容可以触发DOMNodeInserted
使用DOMElement.innerText= '50%'方法改变的span内容不可以触发DOMNodeInserted
2.获取底层圆的背景色
在前面我们说到,当旋转过一半时,右半圆的背景色要置为与底色一样的,那么如何获取这个非内联样式的背景色呢
直接使用DOMElement.style.backgroundColor是获取不到的,因为它只能获取内联样式。
在DOM标准中有一个全局方法window.getComputedStyle(DOMElement,null).,但是它不兼容IE,IE中的DOM元素属性有一个方法DOMElement.currentStyle.,本文中没有对这两种进行封装,大家可以自己封装一下,做起来也很简单

那么我们看最后的js代码


        let spanEle = document.querySelector("span");
        let leftCircle = document.querySelector(".left-circle-bar");
        let rightCircle = document.querySelector(".right-circle-bar");
        let circle= document.querySelector(".circle-bar");
        //获取底圆的背景色
        let color = window.getComputedStyle(circle).backgroundColor;
          //这里模拟span元素值得变化
          //顺便说一下,innerHTML和innertext的区别,前者是W3C的标准属性,后者兼容性不强,前者包括标签,后者只显示内容
          let interval = setInterval(() => {
              let num = parseInt(spanEle.innerHTML);
              if(num<100){
                  num++;
              }else{
                  num = 100;
                  clearInterval(interval);
              }
              spanEle.innerHTML =  num +'%' ;
          }, 100);
  
        spanEle.addEventListener('DOMNodeInserted',function(e){
          //当span元素中的值发生变化则改变圆环的旋转度数
          let num = parseInt(e.target.nodeValue);
          // console.log(num);
          let deg;
          if(num<=50){
              deg = num*3.6 + 'deg';
              rightCircle.style["transform"] = 'rotate('+ deg + ')';
          }else{
          	  //因为旋转度数过半,这里对num减去了50,然后再用结果乘度数
              deg = (num-50)*3.6 + 'deg';
              leftCircle.style["transform"] = 'rotate('+ deg + ')';
              rightCircle.style.backgroundColor = color;
              rightCircle.style["transform"] = 'rotate(0deg)';
          }
        });

这样就结束啦,一个环形进度条就实现完毕啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值