圆圈转动完整代码
html
<div id="wrap">
<div class="box-left">
<div class="circle-left"></div>
</div>
<div class="box-right">
<div class="circle-right"></div>
</div>
</div>
css
#wrap{
width: 200px;
height: 200px;
margin: 200px auto;
position: relative;
border-radius: 50%;
}
/*底部圆圈*/
#wrap::before{
content: "";
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
left: 0;
top: 0;
border: 10px solid rgba(255,255,255,0.5);
border-radius: 50%;
}
/*左右两个盒子里面各放着一个半圆圈,主要overflow*/
.box-left, .box-right{
width: 50%;
height: 100%;
box-sizing: border-box;
position: absolute;
top: 0;
overflow: hidden;
}
.box-left, .circle-left{
left: 0;
}
.box-right, .circle-right{
right: 0;
}
.circle-left, .circle-right{
width: 200%;
height: 100%;
box-sizing: border-box;
border: 10px blue solid;
border-radius: 50%;
position: absolute;
top: 0;
}
/*左边盒子里的圆圈初始时只显示右半边*/
.circle-left{
border-top-color: transparent;
border-left-color: transparent;
transform: rotate(-45deg);
animation: circleRotate 2s linear forwards 2s;
}
/*右边盒子里的圆圈初始时只显示左半边*/
.circle-right{
border-bottom-color: transparent;
border-right-color: transparent;
transform: rotate(-45deg);
animation: circleRotate 2s linear forwards;
}
@keyframes circleRotate{
from {transform: rotate(-45deg)}
to {transform: rotate(135deg)}
}
效果
为了更像进度条做些扩展
html
先在html中加上显示进度数值的元素,及进度条完成时弹出对勾的元素。
<div id="wrap">
<div class="box-left">
<div class="circle-left"></div>
</div>
<div class="box-right">
<div class="circle-right"></div>
</div>
<div class="mark-box">
<!-- 显示进度条数值的元素 -->
<div class="number"></div>
<!-- 进度条完成时弹出的对勾 -->
<div class="checkmark"></div>
</div>
</div>
css
接着上面的css继续写,先注释掉上面的 animation (因为接下来要用js来完成动画)。
/*新加元素的样式*/
.mark-box{
width: 40%;
height: 30%;
/*background-color: red;*/
position: absolute;
left: 30%;
top: 35%;
color: white;
font-size: 30px;
text-align: center;
line-height: 2em;
}
.checkmark{
width: 100%;
height: 100%;
/*background-color: yellow;*/
position: absolute;
top: 0;
left: 0;
transform: rotate(-45deg) translate(13%, -10%);
}
.checkmark::before, .checkmark::after{
content: "";
background-color: white;
position: absolute;
left: 0;
}
.checkmark::before{
width: 5px;
height: 0;
top: 0;
transition: all 0.15s;
}
.checkmark::after{
width: 0;
height: 5px;
bottom: 0;
transition: all 0.15s 0.15s;
}
.checkmark.active::before{
height: 100%;
}
.checkmark.active::after{
width: 100%;
}
js
用 requestAnimationFrame 完成动画
let circleLeft = document.querySelector('.circle-left');
let circleRight = document.querySelector('.circle-right');
let checkmark = document.querySelector('.checkmark');
let textNode = document.querySelector('.mark-box > .number');
function go(start, target){
//如果进度值初始就大于50,就把右边半圆先填满
if(start >= 50){
circleRight.style.transform = 'rotate(135deg)';
}
let progress = start;
let now = start;
//用定时器模拟进度增长
setInterval(() => {
progress++;
}, 100)
let num = 0; //测试标记
function grow(){
console.log('lala', ++num) //测试标记
if(progress > target){
return;
}
//如果进度数值有变化才做dom操作
if(progress !== now){
now = progress;
let deg = (180/50)*progress;
//进度数值显示
textNode.textContent = progress;
//如果进度值小于50,那就右边半圆转动
if(progress <= 50){
console.log('dom') //测试标记
circleRight.style.transform = `rotate(${deg-45}deg)`;
}else if(progress > 50){//如果进度值大于50,那就左边半圆转动
console.log('dom') //测试标记
circleLeft.style.transform = `rotate(${deg-180-45}deg)`;
//如果进度值达到100了,那就弹出对勾
if(progress === 100){
textNode.style.display = 'none';
checkmark.classList.add('active');
console.log('done');
return;
}
}
}
requestAnimationFrame(grow);
}
requestAnimationFrame(grow);
}
go(0, 108)
最终效果
来源:CSDN
作者:samfung09
链接:https://blog.csdn.net/samfung09/article/details/104024958