环形进度条的问题,网上有不少的demo,也有各类不一样的实现方式,很棒的实现也有不少,我这本身作一下一方面是想开阔一下本身的思路,一方面很久没看SVG和Canvas的东西了,基础的拿来熟悉下。css
这个是最基本的实现方式,我在想怎样用尽可能少的DOM结构来实现,最终仍是用了三个div,不过这个方法仅供开阔思路,样式表如今PC还好,手机上的问题就多了,仅供参考。web
一、利用div的border画一个背景的圆环svg
<div class="demo1-bg1"></div> /* css */ .demo1-bg1{ width: 100px; height: 100px; display: -webkit-box; -webkit-box-pack: center; -webkit-box-align: center; margin: 50px auto; background: fff; border-radius: 50%; box-shadow: 0 0 0 10px red inset; }
二、添加两个子元素div,分别设置border来实现两个半圆环并遮盖背景圆环flex
<div class="demo1-bg1"> <div id="J_bg2_1" class="demo1-bg2-1"></div> <div id="J_bg2_2" class="demo1-bg2-2"></div> </div> /* css */ .demo1-bg2-1,.demo1-bg2-2{ position: relative; margin: 0; padding: 0; -webkit-box-flex: 1; height: 80px; background: #fff; border: 10px solid grey; } .demo1-bg2-1{ border-radius: 50px 0 0 50px; border-color: grey transparent grey grey; transform-origin: 100% 50%; z-index: 1; } .demo1-bg2-2{ border-radius: 0 50px 50px 0; border-color: grey grey grey transparent; transform-origin: 0 50%; z-index: 2; }
-->
-->
spa
三、用JS旋转两个子元素,露出背景圆环3d
这个原理也很简单,是利用SVG的stroke和dash-array属性来实现,也是我经常使用的实现方式。orm
绘制一个圆环路径,填充灰色圆环xml
<svg xmlns="http://www.w3.org/200/svg" height="150" width="110"> <circle cx="55" cy="55" r="50" fill="none" stroke="grey" stroke-width="5" stroke-linecap="round"/> </svg>
绘制一个内圆环,半径/圆心和外圆环同样,恰好重叠blog
<circle class="demo2" id="J_progress_bar" cx="55" cy="55" r="50" fill="none" stroke="red" stroke-width="5"/>
设置内圆环的stroke-dasharray属性,stroke-dasharray的值得意思是,第一个值为圆环第一段填充颜色的长度,第二个值为圆环接下来不填充颜色的长度,以此类推并重复。这里设置为:stroke-dasharray="0,10000"
第一个值就是填充红色的值,为0,第二段为不填充的长度,超过圆环的周长便可。此时进度条为0%:
这时候发现stroke-dasharray填充是从3点钟位置开始的,因此就让内圆环旋转-90度:
.demo2{ transform-origin: center; transform: rotate(-90deg); }
JS控制内圆环的stroke-dasharray的值来控制内圆环第一段绘制红色的长度
var demo2 = document.querySelector("#J_demo2"); var btn1 = document.querySelector("#J_btn_1"); var btn2 = document.querySelector("#J_btn_2"); var circleLength = Math.floor(2 * Math.PI * demo2.getAttribute("r")); window.onload = rotateCircle; btn2.onclick = rotateCircle; function rotateCircle () { var val = parseFloat(btn1.value).toFixed(2); val = Math.max(0,val); val = Math.min(100,val); demo2.setAttribute("stroke-dasharray","" + circleLength * val / 100 + ",10000"); }