效果
原理
最高效的实现方法当然是用CSS3中的SVG绘制Path,但是我们也可以用最基础的元素和样式构建出这种效果。
我们把整个圆弧分成两个半圆left-circle
和right-circle
,分别包含在两个容器中right-wrapper
和left-wrapper
,容器都设置了overflow:hidden
,比如下图中右侧圆弧left-circle
包含在左侧容器right-wrapper
中,但是初始状态我们是看不到left-circle
。
但随着进度递增,left-circle
顺时针旋转进入right-wrapper
的可见区域,此时我们才能看得到进度条的出现。
最终再结合right-circle
和left-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>