【動(dòng)畫消消樂|CSS 】仿ios、android中常見的一個(gè)loading動(dòng)畫
效果展示

Demo代碼
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<section>
<div class="loading">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</section>
</body>
</html>
CSS
html,body{
margin: 0;
height: 100%;
}
body{
display: flex;
justify-content: center;
align-items: center;
background: #263238;
}
section {
width: 650px;
height: 300px;
padding: 10px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
/* 紅色邊框僅作提示 */
border: 2px solid red;
}
.loading{
position: relative;
}
.loading>div{
position: absolute;
width: 4px;
height: 20px;
border-radius: 10px;
background-color: white;
}
.loading>div:nth-child(1){
top: 20px;
left: 0px;
background-color: white;
animation: loading infinite 1s;
}
.loading>div:nth-child(2){
top: 14.1442px;
left: 14.1442px;
transform: rotate(-45deg);
background-color: white;
animation: loading infinite 1s 0.125s;
}
.loading>div:nth-child(3){
top: 0px;
left: 20px;
transform: rotate(90deg);
background-color: white;
animation: loading infinite 1s 0.25s;
}
.loading>div:nth-child(4){
top: -14.1442px;
left: 14.1442px;
transform: rotate(45deg);
background-color: white;
animation: loading infinite 1s 0.375s;
}
.loading>div:nth-child(5){
top: -20px;
left: 0px;
transform: rotate(0deg);
background-color: white;
animation: loading infinite 1s 0.5s;
}
.loading>div:nth-child(6){
top: -14.1442px;
left: -14.1442px;
transform: rotate(-45deg);
background-color: white;
animation: loading infinite 1s 0.625s;
}
.loading>div:nth-child(7){
top: 0px;
left: -20px;
transform: rotate(90deg);
background-color: white;
animation: loading infinite 1s 0.75s;
}
.loading>div:nth-child(8){
top: 14.1442px;
left: -14.1442px;
transform: rotate(45deg);
background-color: white;
animation: loading infinite 1s 0.875s;
}
@keyframes loading {
50% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
原理詳解
步驟1
使用一個(gè)div盒子,用于放置整個(gè)loading動(dòng)畫,只需要設(shè)置為相對(duì)定位
<div class="loading"></div>
.loading{
position: relative;
}
步驟2
分別使用8個(gè)div充當(dāng)8個(gè)條狀物
<div class="loading">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
每個(gè)div 樣式設(shè)置為
絕對(duì)定位 寬度:4px 高度:20px border-radius: 10px 背景色:白色
.loading>div{
position: absolute;
width: 4px;
height: 20px;
border-radius: 10px;
background-color: white;
}
效果如下圖

如果沒有設(shè)置為絕對(duì)定位
效果如下

說明:
當(dāng)沒有設(shè)置為絕對(duì)定位的時(shí)候,因?yàn)槊總€(gè)div都是寬4px 高20px的小長條,所以會(huì)從上到下依次展示; 當(dāng)設(shè)置為絕對(duì)定位后,只看到一個(gè)白色長條,其實(shí)這是8個(gè)長條的疊加態(tài)(每個(gè)長條div的位置重合了)
步驟3
使用 :nth-child() 操作其中的每一個(gè)div
先看最后的效果圖
我們對(duì)每一個(gè)小白條標(biāo)號(hào)1、2、3...8

從小白條1開始設(shè)置
top: 20px left: 0px(下移20px 水平方向不動(dòng)) 背景色:紅色
.loading>div:nth-child(1){
top: 20px;
left: 0px;
background-color: red;
}
效果如下圖

注:
因?yàn)樵陂_始的時(shí)候,每個(gè)div已經(jīng)設(shè)置了為絕對(duì)定位,再:nth-child()單獨(dú)對(duì)每個(gè)div設(shè)置的時(shí)候,只需要設(shè)置具體的所在位置,比如top、left、bottom等即可 這里設(shè)置紅色 是為了區(qū)分 便于觀察 此時(shí)白色條狀是7個(gè)div的重疊態(tài) 紅色條狀是第一個(gè)div的最終位置
再設(shè)置小白條3
top: 0px left: 20px;(豎直方向不動(dòng) 右移20px) 背景色:橙色
.loading>div:nth-child(3){
top: 0px;
left: 20px;
background-color: orange;
}
效果如下圖

再旋轉(zhuǎn)90度
.loading>div:nth-child(3){
transform: rotate(90deg);
}
效果如下圖

較難的是小白條2位置關(guān)系的確定
設(shè)置為
top: 14.1442px left: 14.1442px(下移:14.1442px 右移:14.1442px) 背景色:為淡黃色
.loading>div:nth-child(2){
top: 14.1442px;
left: 14.1442px;
background-color: yellow;
}
效果如下圖

再旋轉(zhuǎn) -45度

難點(diǎn):為什么下移、右移距離是14.1442px呢?
海轟的理解:
以最開始的div的重心建立坐標(biāo)軸(圖中藍(lán)色部分表示初始位置)
紅色圓圈表示重心
小白條1、3可以很簡單的表示出來(圖中水平、豎直方向的淺橙色部分)
其中紅色圓圈的距離是20px(因?yàn)橐苿?dòng)的就是20px)
為了使得每個(gè)條狀形成一個(gè)圓圈
我們規(guī)定每個(gè)圓圈的重心在同一個(gè)圓上
那么小白條2的位置關(guān)系如下(右下角的那個(gè)淺橙色部分)

再旋轉(zhuǎn)-45度
仔細(xì)觀賞 是不是三個(gè)條狀圍成了一個(gè)圓 哈哈

那么距離如何計(jì)算呢?
可以很清楚的觀察出一個(gè)等腰直角三角形
圓半徑是20px
那么x=20/根號(hào)2=20/1.414=14.1442 px

右上角、左上角、左下角的規(guī)律也是一樣的,這里就不多闡述了
設(shè)置小白條4為
top: -14.1442px left: 14.1442px; 背景色:綠色 旋轉(zhuǎn)45度
top: -14.1442px;
left: 14.1442px;
transform: rotate(45deg);
background-color: green;
}
效果如下圖

按照相同的規(guī)律設(shè)置小白條5、6、7、8(理清楚方向就可以了 數(shù)據(jù)都差不多)
.loading>div:nth-child(5){
top: -20px;
left: 0px;
transform: rotate(0deg);
background-color: cyan;
}
.loading>div:nth-child(6){
top: -14.1442px;
left: -14.1442px;
transform: rotate(-45deg);
background-color: blue;
}
.loading>div:nth-child(7){
top: 0px;
left: -20px;
transform: rotate(90deg);
background-color: purple;
}
.loading>div:nth-child(8){
top: 14.1442px;
left: -14.1442px;
transform: rotate(45deg);
background-color: white;
}
效果如下圖

步驟4
設(shè)置動(dòng)畫
每一個(gè)白條的動(dòng)畫都一樣 只是錯(cuò)序進(jìn)行即可
動(dòng)畫效果描述為:
50%時(shí),透明級(jí)別為0.3 100%,透明級(jí)別為1
@keyframes loading {
50% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
以小白條1運(yùn)行此動(dòng)畫為例
設(shè)置為
無限循環(huán) 動(dòng)畫持續(xù)時(shí)間:1s
.loading>div:nth-child(1){
animation: loading infinite 2s;
}
效果如下圖

類似流水燈的原理
8個(gè)白色條狀
每次只亮1個(gè) 其余7個(gè)都不亮
以1、0代表亮與不亮
則有8種狀態(tài)
1000 0000(小白條1亮) 0100 0000(小白條2亮) 0010 0000(小白條3亮) 0001 0000(小白條4亮) 0000 1000(小白條5亮) 0000 0100(小白條6亮) 0000 0010(小白條7亮) 0000 0001(小白條8亮)
動(dòng)畫持續(xù)時(shí)間為1s
有8個(gè)小白條
為了使得當(dāng)8個(gè)白條亮完后 第一個(gè)白條又開始新一輪循環(huán)
設(shè)置每個(gè)相鄰條狀動(dòng)畫間隔時(shí)間為1/8=0.125s
所以設(shè)置動(dòng)畫為:
.loading>div:nth-child(1){
animation: loading infinite 1s;
}
.loading>div:nth-child(2){
animation: loading infinite 1s 0.125s;
}
.loading>div:nth-child(3){
animation: loading infinite 1s 0.25s;
}
.loading>div:nth-child(4){
animation: loading infinite 1s 0.375s;
}
.loading>div:nth-child(5){
animation: loading infinite 1s 0.5s;
}
.loading>div:nth-child(6){
animation: loading infinite 1s 0.625s;
}
.loading>div:nth-child(7){
animation: loading infinite 1s 0.75s;
}
.loading>div:nth-child(8){
animation: loading infinite 1s 0.875s;
}
效果如下圖

步驟5
最后將所有div的顏色修改為白色
得到最終效果

結(jié)語
希望對(duì)您有所幫助
如有錯(cuò)誤歡迎小伙伴指正~
我是 海轟?(?ˊ?ˋ)?
如果您覺得寫得可以的話
請點(diǎn)個(gè)贊吧
謝謝支持??

