Web特效背后的笨拙实现 -- 圆形进度条

2018-07-05  本文已影响11人  人生看淡不服就干

效果

原理

最高效的实现方法当然是用CSS3中的SVG绘制Path,但是我们也可以用最基础的元素和样式构建出这种效果。

我们把整个圆弧分成两个半圆left-circleright-circle,分别包含在两个容器中right-wrapperleft-wrapper,容器都设置了overflow:hidden,比如下图中右侧圆弧left-circle包含在左侧容器right-wrapper中,但是初始状态我们是看不到left-circle

但随着进度递增,left-circle顺时针旋转进入right-wrapper的可见区域,此时我们才能看得到进度条的出现。

最终再结合right-circleleft-wrapper共同实现完整的进度条效果。

代码

<!DOCTYPE html>
<html>
<header>
    <title>circle</title>
    <style type="text/css">
        div {
          box-sizing: border-box;
        }
        .downloading {
          width: 40px;
          height: 40px;
          background-color: gray;
          position: relative;
        }
        .loading-wrapper-left,
        .loading-wrapper-right {
          width: 50%;
          height: 100%;
          position: absolute;
          top: 0;
          overflow: hidden;
        }
        .loading-wrapper-left {
          left: 0;
        }
        .loading-wrapper-right {
          right: 0;
        }
        .loading-circle-left,
        .loading-circle-right {
          width: 100%;
          height: 100%;
          border: solid 2px white;
          position: absolute;
          top: 0;
        }
        .loading-circle-left {
          border-radius: 20px 0 0 20px;
          border-right: transparent;
          right: 100%;
          transform-origin: 100% 50%;
        }
        .loading-circle-right {
          border-radius: 0 20px 20px 0;
          border-left: transparent;
          left: 100%;
          transform-origin: 0% 50%;
        }
    </style>
</header>
<body>
    <div class="downloading">
        <div class="loading-wrapper-left">
            <div class="loading-circle-right"></div>
        </div>
        <div class="loading-wrapper-right">
            <div class="loading-circle-left"></div>
        </div>
    </div>
</body>
<script type="text/javascript">
    function updateProgress(progress){
        if (progress < 0 || progress > 100) {
            return;
        }
        var leftCircleRotateDegree = progress <= 50 ? progress / 100.0 * 360 : 180;
        var rightCircleRotateDegree = progress > 50 ? (progress - 50) / 100.0 * 360 : 0;

        var leftCircle = document.getElementsByClassName('loading-circle-left')[0];
        var rightCircle = document.getElementsByClassName('loading-circle-right')[0];

        leftCircle.style.transform = 'rotate('+leftCircleRotateDegree+'deg)';
        rightCircle.style.transform = 'rotate('+rightCircleRotateDegree+'deg)';
    }

    var progress = 0;
    setInterval(function(){
        if(progress >= 100){
            progress = 0;
        }else{
            progress ++;
        }
        updateProgress(progress);
    },500);
</script>
</html>
上一篇 下一篇

猜你喜欢

热点阅读