效果如下:
这里只是介绍我的一个实现方案, 顺便留下一个没能解决的问题(重点), 求大神支招解决
HTML 结构
<div class="spinner">
<div class="top"></div>
<div class="bottom"></div>
</div>
解释:
0. 圆圈使用border和border-radius实现, 扇形通过rotate和overflow:hidden的方式来实现。
1. spinner 作为容器, top负责上半个圆, bottom负责下半个圆。
css frame
.spinner {
width: 70px;
height: 70px;
position: relative;
left: 100px;
top: 100px;
color: white;
}
.spinner .top, .spinner .bottom{
width: 70px;
height: 35px;
position: relative;
overflow: hidden;
}
.spinner::before, .spinner .top::before, .spinner .bottom::before{
content: '';
width: 70px;
height: 70px;
display: inline-block;
border-style: solid;
border-top-color: #FFF;
border-right-color: #FFF;
border-left-color: transparent;
border-bottom-color: transparent;
border-radius: 50%;
border-width: 5px;
box-sizing: border-box;
}
动画部分css
/* 使用spinner::before来覆盖空隙*/
.spinner::before {
position: absolute;
border-right-color: transparent;
border-top-color: transparent;
transform: rotateZ(47deg);
-webkit-animation: fix-gap 2s ease-in infinite;
}
.spinner .top::before {
transform: rotateZ(-225deg);
-webkit-animation: rotate-top 2s ease-in infinite;
/*-webkit-animation-delay: 0.3s;*/
}
.spinner .bottom::before {
border-bottom-color: #fff;
border-top-color: transparent;
position: relative;
bottom: 35px;
transform: rotateZ(-135deg);
-webkit-animation: rotate-bottom 2s ease-out infinite;
/*-webkit-animation-delay: 0.3s;*/
}
@-webkit-keyframes fix-gap {
49% {
border-top-color: transparent;
}
50% {
border-top-color: white;
}
100% {
border-top-color: white;
}
}
@-webkit-keyframes rotate-top {
50% {
transform: rotateZ(-45deg);
}
100% {
transform: rotateZ(-45deg);
}
}
@-webkit-keyframes rotate-bottom {
50% {
transform: rotateZ(-135deg);
}
100% {
transform: rotateZ(45deg);
}
}
解释:
这里用到了3个before伪元素,为什么会使用3个,不是只有上半个和下半个圆吗? 对, 这就是我要提出来的问题, 见下图:
可能没有发现问题, 如果你仔细些可以看到上半圆和下半圆中间有一条空隙, 不能忍啊!
见大图:
为了fix这条空隙, 我的解决方法是通过旋转spinner::before
,在动画过程中添加border的来覆盖空隙。
所有代码
<div class="spinner">
<div class="top"></div>
<div class="bottom"></div>
</div>
<h4>Circle Spinner -by 横天</h4>
<style>
.spinner {
width: 70px;
height: 70px;
position: relative;
left: 100px;
top: 100px;
color: white;
}
.spinner .top, .spinner .bottom{
width: 70px;
height: 35px;
position: relative;
-webkit-backface-visibility: hidden;
-webkit-transform: translateZ(0) scale(1.0, 1.0);
overflow: hidden;
}
.spinner::before, .spinner .top::before, .spinner .bottom::before{
content: '';
width: 70px;
height: 70px;
display: inline-block;
border-style: solid;
border-top-color: #FFF;
border-right-color: #FFF;
border-left-color: transparent;
border-bottom-color: transparent;
border-radius: 50%;
border-width: 5px;
box-sizing: border-box;
}
/* 使用spinner::before来覆盖空隙*/
.spinner::before {
position: absolute;
border-right-color: transparent;
border-top-color: transparent;
transform: rotateZ(47deg);
-webkit-animation: fix-gap 2s ease-in infinite;
}
.spinner .top::before {
transform: rotateZ(-225deg);
-webkit-animation: rotate-top 2s ease-in infinite;
/*-webkit-animation-delay: 0.3s;*/
}
.spinner .bottom::before {
border-bottom-color: #fff;
border-top-color: transparent;
position: relative;
bottom: 35px;
transform: rotateZ(-135deg);
-webkit-animation: rotate-bottom 2s ease-out infinite;
/*-webkit-animation-delay: 0.3s;*/
}
@-webkit-keyframes fix-gap {
49% {
border-top-color: transparent;
}
50% {
border-top-color: white;
}
100% {
border-top-color: white;
}
}
@-webkit-keyframes rotate-top {
50% {
transform: rotateZ(-45deg);
}
100% {
transform: rotateZ(-45deg);
}
}
@-webkit-keyframes rotate-bottom {
50% {
transform: rotateZ(-135deg);
}
100% {
transform: rotateZ(45deg);
}
}
body {
background: rgb(235, 205, 86);
}
h4 {
position: absolute;
bottom: 20px;
left: 20px;
margin: 0;
font-weight: 200;
opacity: .5;
font-family: sans-serif;
color: #fff;
}
</style>
最后
- 跪求更好的解决方法?
- 我已经试过了
-webkit-backface-visibility: hidden;
或者-webkit-transform: translateZ(0) scale(1.0, 1.0);
没有达到想要的效果, 求fix!!!!! - 其实用svg + css3实现很简单, 但是svg在mobile 兼容性差, 所以只能用div + css3, 或者canvas。
补充
如果只是要画一个圆形, 可以用linear-gradient. 但是不支持transition
<div class="circle"> </div>
<style>
.circle{
background-image: linear-gradient(18deg, #57ad68 50%, transparent 50%, transparent), linear-gradient(270deg, #57ad68 50%, #b7b7b7 50%, #b7b7b7);
width: 100px;
height: 100px;
border-radius: 50%;
}
</style>