CSS動畫實戰:建立一個太極Loading圖
阿新 • • 發佈:2018-12-30
這裡主要是使用CSS的animation和偽類來構建,分析設定關鍵幀的執行順序和時間段。
效果
動畫分析
首先通過效果對動畫執行進行一下分析:
- 邊框的四條邊進行按順序動畫載入 。
- 矩形邊框變為圓行邊框。
- 太極圖內部圖案漸漸出現。
- 太極圖旋轉。
- 整個動畫逆序執行。
針對上面的1效果是需要思考一下的,其他都比較容易實現。5效果只需設定屬性animation-direction: alternate
即可,整體動畫加入animation-iteration-count: infinite
來保證無限迴圈。
靜態效果實現
首先將靜態效果做出來。
html結構:
<div id="loader">
<div class="logo">
<div class="left"></div>
<div class="right"></div>
</div>
<p>Loading...</p>
</div>
CSS(LESS)部分:
@border-width:2px;
@loader-width:150px;
@loader-insider-width:@loader-width * 0.15 ;
@animate-time:4s;
*{
margin: 0;
padding: 0;
border: 0;
}
html, body{
width: 100%;
height: 100%;
}
#loader{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
p {
padding: 1.5em;
font-family : Arial;
}
.logo{
width: @loader-width;
height: @loader-width;
position: relative;
&:before{
position: absolute;
content: '';
left: 0;
top: 0;
border-color: transparent;
border-width: @border-width;
border-style: solid;
border-top-color: #000;
border-right-color: #000;
width: 100%;
height: 100%;
}
&:after{
position: absolute;
content: '';
bottom: -2 * @border-width;
right: -2 * @border-width;
border-color: transparent;
border-width: @border-width;
border-style: solid;
border-bottom-color: #000;
border-left-color: #000;
width: 100%;
height: 100%;
}
.left{
position: absolute;
width: 50%;
height: 100%;
top: @border-width;
right: 50%;
background-color: #000;
border-top-left-radius: 100% 50%;
border-bottom-left-radius: 100% 50%;
&:before{
position: absolute;
content: '';
width: 100%;
height: 50%;
bottom: 0;
left: 50%;
border-radius: 50%;
background-color: #000;
}
&:after{
position: absolute;
content: '';
width: @loader-insider-width;
height: @loader-insider-width;
background-color: #fff;
bottom: ~'calc(25% - @{loader-insider-width} / 2)';
left: ~'calc(100% - @{loader-insider-width} / 2)';
border-radius: 50%;
}
}
.right{
position: absolute;
width: 50%;
height: 100%;
top: @border-width;
left: 50%;
border-top-right-radius: 100% 50%;
border-bottom-right-radius: 100% 50%;
&:before{
position: absolute;
content: '';
width: 100%;
height: 50%;
top: 0;
right: 50%;
border-radius: 50%;
background-color: #fff;
}
&:after{
position: absolute;
content: '';
width: @loader-insider-width;
height: @loader-insider-width;
background-color: #000;
top: ~'calc(25% - @{loader-insider-width} / 2)';
right: ~'calc(100% - @{loader-insider-width} / 2)';
border-radius: 50%;
}
}
}
}
效果:
動畫實現
上面已經把靜態的效果實現了,現在將動畫部分抽離出來。
動畫關鍵幀時間段
根據效果,做如下時間段劃分:
邊框效果實現
將.logo
的兩個偽類的寬高設定為0,然後新增動畫效果:
.logo{
width: @loader-width;
height: @loader-width;
position: relative;
animation: spin @animate-time infinite;
animation-direction: alternate;
animation-timing-function:ease;
&:before{
position: absolute;
content: '';
left: 0;
top: 0;
border-color: transparent;
border-width: @border-width;
border-style: solid;
animation: line-before @animate-time infinite;
animation-direction: alternate;
}
&:after{
position: absolute;
content: '';
bottom: -2 * @border-width;
right: -2 * @border-width;
border-color: transparent;
border-width: @border-width;
border-style: solid;
animation: line-after @animate-time infinite;
animation-direction: alternate;
}
}
keyframes:
@keyframes line-before {
0% {
width: 0;
height: 0;
border-top-color: #000;
}
9.9% {
border-right-color: transparent;
}
10% {
width: 100%;
border-right-color: #000;
border-top-color: #000;
height: 0;
}
20%,100% {
width: 100%;
border-right-color: #000;
border-top-color: #000;
height: 100%;
}
40% {
width: 100%;
border-right-color: #000;
border-top-color: #000;
height: 100%;
border-radius: 0;
}
//在執行到50%的時候變圓
50%, 100% {
width: 100%;
border-right-color: #000;
border-top-color: #000;
height: 100%;
border-radius: 50%;
}
}
@keyframes line-after {
0%,19.9% {
border-color: transparent;
width: 0;
height: 0;
}
20% {
width: 0;
height: 0;
border-bottom-color: #000;
}
29.9% {
border-left-color: transparent;
}
30% {
width: 100%;
border-left-color: #000;
border-bottom-color: #000;
height: 0;
}
40% {
width: 100%;
border-left-color: #000;
border-bottom-color: #000;
height: 100%;
border-radius: 0;
}
//在執行到50%的時候變圓
50%, 100% {
border-radius: 50%;
width: 100%;
border-left-color: #000;
border-bottom-color: #000;
height: 100%;
}
}
內部圖案出現效果
這個直接調一下透明度即可:
@keyframes left-right-fade {
0%, 50%{
opacity: 0;
}
75%, 100% {
opacity: 1;
}
}
旋轉效果
@keyframes spin {
0%, 75%{
transform:rotate(0deg);
}
90%, 100% {
transform:rotate(360deg);
}
}
所有樣式程式碼
//author: 王樂平
//date: 2017.8.1
//blog: http://blog.csdn.net/lecepin
@border-width:2px;
@loader-width:150px;
@loader-insider-width:@loader-width * 0.15;
@animate-time:4s;
*{
margin: 0;
padding: 0;
border: 0;
}
html, body{
width: 100%;
height: 100%;
}
#loader{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
p {
padding: 1.5em;
font-family: Arial;
}
.logo{
width: @loader-width;
height: @loader-width;
position: relative;
animation: spin @animate-time infinite;
animation-direction: alternate;
animation-timing-function:ease;
&:before{
position: absolute;
content: '';
left: 0;
top: 0;
border-color: transparent;
border-width: @border-width;
border-style: solid;
animation: line-before @animate-time infinite;
animation-direction: alternate;
}
&:after{
position: absolute;
content: '';
bottom: -2 * @border-width;
right: -2 * @border-width;
border-color: transparent;
border-width: @border-width;
border-style: solid;
animation: line-after @animate-time infinite;
animation-direction: alternate;
}
.left{
position: absolute;
width: 50%;
height: 100%;
top: @border-width;
right: 50%;
background-color: #000;
border-top-left-radius: 100% 50%;
border-bottom-left-radius: 100% 50%;
animation: left-right-fade @animate-time infinite;
animation-direction: alternate;
&:before{
position: absolute;
content: '';
width: 100%;
height: 50%;
bottom: 0;
left: 50%;
border-radius: 50%;
background-color: #000;
}
&:after{
position: absolute;
content: '';
width: @loader-insider-width;
height: @loader-insider-width;
background-color: #fff;
bottom: ~'calc(25% - @{loader-insider-width} / 2)';
left: ~'calc(100% - @{loader-insider-width} / 2)';
border-radius: 50%;
}
}
.right{
position: absolute;
width: 50%;
height: 100%;
top: @border-width;
left: 50%;
border-top-right-radius: 100% 50%;
border-bottom-right-radius: 100% 50%;
animation: left-right-fade @animate-time infinite;
animation-direction: alternate;
&:before{
position: absolute;
content: '';
width: 100%;
height: 50%;
top: 0;
right: 50%;
border-radius: 50%;
background-color: #fff;
}
&:after{
position: absolute;
content: '';
width: @loader-insider-width;
height: @loader-insider-width;
background-color: #000;
top: ~'calc(25% - @{loader-insider-width} / 2)';
right: ~'calc(100% - @{loader-insider-width} / 2)';
border-radius: 50%;
}
}
}
}
@keyframes line-before {
0% {
width: 0;
height: 0;
border-top-color: #000;
}
9.9% {
border-right-color: transparent;
}
10% {
width: 100%;
border-right-color: #000;
border-top-color: #000;
height: 0;
}
20%,100% {
width: 100%;
border-right-color: #000;
border-top-color: #000;
height: 100%;
}
40% {
width: 100%;
border-right-color: #000;
border-top-color: #000;
height: 100%;
border-radius: 0;
}
50%, 100% {
width: 100%;
border-right-color: #000;
border-top-color: #000;
height: 100%;
border-radius: 50%;
}
}
@keyframes line-after {
0%,19.9% {
border-color: transparent;
width: 0;
height: 0;
}
20% {
width: 0;
height: 0;
border-bottom-color: #000;
}
29.9% {
border-left-color: transparent;
}
30% {
width: 100%;
border-left-color: #000;
border-bottom-color: #000;
height: 0;
}
40% {
width: 100%;
border-left-color: #000;
border-bottom-color: #000;
height: 100%;
border-radius: 0;
}
50%, 100% {
border-radius: 50%;
width: 100%;
border-left-color: #000;
border-bottom-color: #000;
height: 100%;
}
}
@keyframes left-right-fade {
0%, 50%{
opacity: 0;
}
75%, 100% {
opacity: 1;
}
}
@keyframes spin {
0%, 75%{
transform:rotate(0deg);
}
90%, 100% {
transform:rotate(360deg);
}
}
部落格名稱:王樂平部落格
CSDN部落格地址:http://blog.csdn.net/lecepin