炫酷水波浪Loading過(guò)渡動(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="circle">
<div class="wave"></div>
</div>
</section>
</body>
</html>
CSS
/*
模版css樣式
僅供演示使用
*/
html, body {
margin: 0;
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-color: #12383e;
}
section {
width: 650px;
height: 300px;
padding: 10px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
border-radius: 20px;
border: 18px solid white;
overflow: hidden;
}
section::before {
content: 'CSS';
width: 150px;
height: 150px;
text-align: center;
line-height: 250px;
background-color: #00cec9;
position: absolute;
top: -76px;
right: -76px;
transform: translate(50%, -50%);
font-size: 32px;
font-weight: 500;
font-family: sans-serif;
color: white;
transform: rotate(45deg);
}
section::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
border: 10px solid white;
border-radius: 20px;
}
/* 實(shí)現(xiàn)代碼 */
.circle {
position: relative;
width: 200px;
height: 200px;
background: #b0f4ff;
border-radius: 50%;
overflow: hidden;
animation: loadingBreath 5s infinite linear;
}
.circle::before {
content: 'Loading...';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 18px;
letter-spacing: 2px;
color: #10a789;
font-family: sans-serif;
z-index: 2;
}
.circle::after {
content: '';
position: absolute;
width: 100%;
height: 25%;
bottom: 0;
background-image: linear-gradient(to top, #12c8e0, #36e9ff, #5ffbf1);
animation: loadingRun 5s linear infinite;
}
.wave::before {
content: '';
position: absolute;
left: -50%;
width: 200%;
height: 200%;
z-index: 1;
background-color: #85f7fb;
border-radius: 52% 25% 62% 69%/25% 38%;
animation: loadingWave 5s linear infinite;
}
.wave::after {
content: '';
position: absolute;
left: -50%;
width: 200%;
height: 200%;
z-index: 1;
background-color: #d0f4ff;
border-radius: 42% 38% 40% 62%/28% 35%;
animation: loadingWave 5s ease-in-out infinite;
}
/* 呼吸燈動(dòng)畫 */
@keyframes loadingBreath {
0% {
box-shadow: 0 0 5px 0 #85f7fb;
}
25% {
box-shadow: 0 0 20px 0 #85f7fb;
}
50% {
box-shadow: 0 0 5px 0 #85f7fb;
}
75% {
box-shadow: 0 0 20px 0 #85f7fb;
}
100% {
box-shadow: 0 0 5px 0 #85f7fb;
}
}
/* 底部液體上升動(dòng)畫 */
@keyframes loadingRun {
0% {
height: 25%;
}
100% {
height: 100%;
}
}
/* wave動(dòng)畫 */
@keyframes loadingWave {
0% {
top: -100%;
transform: rotate(0);
}
100% {
top: -200%;
transform: rotate(360deg);
}
}
原理詳解
步驟1
從效果圖上分析
可以將其分為兩個(gè)部分
容器 波浪
這里使用兩個(gè)div,一個(gè)為circle類,一個(gè)為wave類,分別代表容器和wave
<div class="circle">
<div class="wave"></div>
</div>
步驟2
設(shè)置circle類
相對(duì)定位 寬度、高度均為200px 背景色:#b0f4ff 圓角:50%
.circle {
position: relative;
width: 200px;
height: 200px;
background: #b0f4ff;
border-radius: 50%;
}
效果圖如下:

步驟3
利用.circle::befor偽元素
用于顯示“Loading...”字樣
設(shè)置為
絕對(duì)定位 使其位于「正中間」( top: 50%; left: 50%; transform: translate(-50%, -50%);) 字體大小:18px 顏色:#10a789; z-index:2(比1大就行 使其文字處于最上層)
.circle::before {
content: 'Loading...';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 18px;
letter-spacing: 2px;
color: #10a789;
font-family: sans-serif;
z-index: 2;
}
效果圖如下:

步驟4
利用.circle::after偽元素
設(shè)置為
絕對(duì)定位(bottom: 0; ) 寬度:100% 高度:25% 背景顏色為漸變色 linear-gradient(to top, #12c8e0, #36e9ff, #5ffbf1);
.circle::after {
content: '';
position: absolute;
width: 100%;
height: 25%;
bottom: 0;
background-image: linear-gradient(to top, #12c8e0, #36e9ff, #5ffbf1);
}
效果圖如下:

步驟5
為.circle::after偽元素添加動(dòng)畫
使其隨時(shí)間其高度逐漸增大
只需要明確兩個(gè)關(guān)鍵幀
初始位置:height: 25% 結(jié)束位置:height: 100%
.circle::after {
animation: loadingRun 5s linear infinite;
}
@keyframes loadingRun {
0% {
height: 25%;
}
100% {
height: 100%;
}
}
效果圖如下:

步驟6
對(duì)circle設(shè)置隱藏溢出
.circle {
overflow: hidden;
}
效果圖如下:

步驟7
這里先注釋circle隱藏溢出 以及 circle::after動(dòng)畫 便于后面單獨(dú)分析
.circle {
/* overflow: hidden; */
}
.circle::after {
/* animation: loadingRun 5s linear infinite; */
}
然后我們使用wave的兩個(gè)偽元素.wave::before、.wave::afte與cirle::after產(chǎn)生波浪的效果
首先設(shè)置wave::before
絕對(duì)定位(left: -50%;) 寬度、高度均為200% z-index:1 背景色:#85f7fb border-radius: 52% 25% 62% 69%/25% 38%; 「重點(diǎn)」
.wave::before {
content: '';
position: absolute;
left: -50%;
width: 200%;
height: 200%;
z-index: 1;
background-color: #85f7fb;
border-radius: 52% 25% 62% 69%/25% 38%;/*重點(diǎn)*/
}
效果圖如下:

注:.wave::before z-index為1 大于circile(0) 小于.circle::before(2)
為.wave::before 添加動(dòng)畫
效果描述
?自身不斷旋轉(zhuǎn)的同時(shí) 也不斷上升
?
.wave::before {
animation: loadingWave 5s linear infinite;
}
@keyframes loadingWave {
0% {
top: -100%;
transform: rotate(0);
}
100% {
top: -200%;
transform: rotate(360deg);
}
}
效果圖如下:

同理,對(duì)wave::after進(jìn)行同樣的設(shè)置
不同在于?四邊圓角率與before不同、顏色淺一點(diǎn)
border-radius: 42% 38% 40% 62%/28% 35%;
background-color: #d0f4ff;
其他都一樣

當(dāng)wave::after、before運(yùn)用同樣的動(dòng)畫時(shí)
效果圖如下:

步驟8
取消circle隱藏溢出 以及 circle::after動(dòng)畫
.circle {
overflow: hidden;
}
.circle::after {
animation: loadingRun 5s linear infinite;
}
效果圖如下:

步驟9
最后為cirlce添加一個(gè)呼吸燈動(dòng)畫效果
.circle {
animation: loadingBreath 5s infinite linear;
}
```css
@keyframes loadingBreath {
0% {
box-shadow: 0 0 5px 0 #85f7fb;
}
25% {
box-shadow: 0 0 20px 0 #85f7fb;
}
50% {
box-shadow: 0 0 5px 0 #85f7fb;
}
75% {
box-shadow: 0 0 20px 0 #85f7fb;
}
100% {
box-shadow: 0 0 5px 0 #85f7fb;
}
}
得到最終效果圖

結(jié)語(yǔ)
學(xué)習(xí)參考:
?https://www.bilibili.com/video/BV1Ai4y1t7od https://developer.mozilla.org/zh-CN/docs/Web/CSS/::before
?
文章僅作為學(xué)習(xí)筆記,記錄從0到1的一個(gè)過(guò)程
希望對(duì)您有所幫助,如有錯(cuò)誤歡迎小伙伴指正~
我是 海轟?(?ˊ?ˋ)?
如果您覺(jué)得寫得可以的話,請(qǐng)點(diǎn)個(gè)贊吧
謝謝支持??
