最近,在 CodePen 上看到這樣一個非常有意思的效果:
這個效果的核心難點在于氣泡的一種特殊融合效果,
其源代碼在:CodePen Demo -- Goey footer,作者主要使用的是 SVG 濾鏡完成的該效果,感興趣的可以戳原始碼看看,
其中,要想靈活運用 SVG 中的 feGaussianBlur 濾鏡還是需要有非常強大的 SVG 知識儲備的,那么,僅僅使用 CSS 能否實作該效果呢?
嘿嘿,強大的 CSS 當然是可以的,本文,就將帶領大家一步步使用純 CSS,完成上述效果,
借助 SASS 完成大致效果
首先,如果上述效果沒有氣泡的融合效果,可能就僅僅是這樣:
要制作這樣一個效果還是比較簡單的,只是代碼會比較多,我們借助 SASS 前處理器即可,
假設我們有如下 HTML 結構:
<div >
<div >
<div ></div>
<div ></div>
// ... 200 個 g-bubble
</div>
</div>
核心要做的,僅僅是讓 200 個 .g-bubble 從底部無規律的進行向上升起的影片,
這里,就需要運用我們在 深入淺出 CSS 影片 這篇文章中所介紹的一種技巧 -- 利用 animation-duration 和 animation-delay 構建隨機效果,
利用 animation-duration 和 animation-delay 構建隨機效果
同一個影片,我們利用一定范圍內隨機的 animation-duration 和一定范圍內隨機的 animation-delay,可以有效的構建更為隨機的影片效果,讓影片更加的自然,
我們來模擬一下,如果是使用 10 個 animation-duration 和 animation-delay 都一致的圓的話,核心偽代碼:
<ul>
<li></li>
<!--共 10 個...-->
<li></li>
</ul>
ul {
display: flex;
flex-wrap: nowrap;
gap: 5px;
}
li {
background: #000;
animation: move 3s infinite 1s linear;
}
@keyframes move {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0, -100px);
}
}
這樣,小球的運動會是這樣的整齊劃一:
要讓小球的運動顯得非常的隨機,只需要讓 animation-duration 和 animation-delay 都在一定范圍內浮動即可,改造下 CSS:
@for $i from 1 to 11 {
li:nth-child(#{$i}) {
animation-duration: #{random(2000)/1000 + 2}s;
animation-delay: #{random(1000)/1000 + 1}s;
}
}
我們利用 SASS 的回圈和 random() 函式,讓 animation-duration 在 2-4 秒范圍內隨機,讓 animation-delay 在 1-2 秒范圍內隨機,這樣,我們就可以得到非常自然且不同的上升影片效果,基本不會出現重復的畫面,很好的模擬了隨機效果:
CodePen Demo -- 利用范圍隨機 animation-duration 和 animation-delay 實作隨機影片效果
好,我們把上述介紹的技巧,套用到我們本文要實作的效果中去,HTML 結構再看一眼:
<div >
<div >
<div ></div>
<div ></div>
// ... 200 個 g-bubble
</div>
</div>
核心的 CSS 代碼:
.g-footer {
position: absolute;
bottom: 0;
left: 0;
height: 86px;
width: 100%;
background: #26b4f5;
}
@for $i from 0 through 200 {
.g-bubble:nth-child(#{$i}) {
position: absolute;
background: #26b4f5;
$width: random(100) + px;
left: #{(random(100)) + '%'};
top: #{(random(100))}px;
width: $width;
height: $width;
animation: moveToTop #{(random(2500) + 1500) / 1000}s ease-in-out -#{random(5000)/1000}s infinite;
}
}
@keyframes moveToTop {
90% {
opacity: 1;
}
100% {
opacity: .08;
transform: translate(-50%, -180px) scale(.3);
}
}
這里:
- 我們利用了 SASS 隨機函式
$width: random(100) + px;,隨機生成不同大小的 div 圓形 - 利用 SASS 隨機函式
left: #{(random(100)) + '%'},top: #{(random(100))}px基于父元素隨機定位 - 最為核心的是
animation: moveToTop #{(random(2500) + 1500) / 1000}s ease-in-out -#{random(5000)/1000}s infinite,讓所有 div 圓的運動都是隨機的
上述(1)、(2)綜合結果,會生成這樣一種布局,均勻分散排布的圓形:
注:這里為了方便理解,我隱藏了最外層
g-footer的顏色,并且給g-bubble添加了黑色邊框
接著,如果我們替換一下 animation 陳述句,使用統一的影片時長,去掉負的延遲,變成 animation: moveToTop 4s ease-in-out infinite,影片就會是這樣:
整體是整齊劃一,沒有雜亂無章的感覺的,
運用上隨機效果,animation: moveToTop #{(random(2500) + 1500) / 1000}s ease-in-out -#{random(5000)/1000}s infinite,就能得到上述的,不同氣泡隨機上升的感覺:
添加融合效果
接下來,也是最重要的一步,如何讓氣泡與氣泡之間,以及氣泡和底部 .g-footer 之間產生融合效果呢?
這個技巧在此前非常多篇文章中,也頻繁提及過,就是利用 filter: contrast() 濾鏡與 filter: blur() 濾鏡,
如果你還不了解這個技巧,可以戳我的這篇文章看看:你所不知道的 CSS 濾鏡技巧與細節
簡述下該技巧:
單獨將兩個濾鏡拿出來,它們的作用分別是:
filter: blur(): 給影像設定高斯模糊效果,filter: contrast(): 調整影像的對比度,
但是,當他們“合體”的時候,產生了奇妙的融合現象,
仔細看兩圓相交的程序,在邊與邊接觸的時候,會產生一種邊界融合的效果,通過對比度濾鏡把高斯模糊的模糊邊緣給干掉,利用高斯模糊實作融合效果,
基于此,我們再簡單改造下我們的 CSS 代碼,所需要加的代碼量非常少:
.g-wrap {
background: #fff;
filter: contrast(8);
}
.g-footer {
// ... 其他保持一致
filter: blur(5px);
}
就這么簡單,父容器添加白色底色以及對比度濾鏡 filter: contrast(8),子容器添加 filter: blur(5px) 即可,這樣,我們就能得氣泡的融合效果,基本得到我們想要的效果:
利用 backdrop-filter 替代 filter 消除邊緣
但是!利用 filter: blur() 會有一個小問題,
運用了 filter: blur() 的元素,元素邊緣的模糊度不夠,會導致效果在邊緣失真,我們仔細看看影片的邊緣:
如何解決呢?也好辦,在這里,我們嘗試利用 backdrop-filter 去替換 filter,
兩者之間的差異在于,filter 是作用于元素本身,而 backdrop-filter 是作用于元素背后的區域所覆寫的所有元素,如果你想了解更多關于 backdrop-filter 的資訊,可以戳我的這篇文章:深入探討 filter 與 backdrop-filter 的異同,
簡單改造下代碼,原代碼:
.g-footer {
// ...
filter: blur(5px);
}
改造后的代碼:
.g-footer {
// ... 去掉 filter: blur(5px)
&:before {
content: "";
position: absolute;
top: -300px;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
backdrop-filter: blur(5px);
}
}
我們通過去到原來添加在 .g-footer 上的 filter: blur(5px),通過他的偽元素,疊加一層新的元素在它本身之上,并且添加了替代的 backdrop-filter: blur(5px),
當然,因為這里的 blur(5px) 還需要為氣泡與氣泡之間的融合服務,所以為了覆寫影片全區域,我們還設定了 top: -300px,擴大了它的作用范圍,
最終,我們就能完美的復刻文章一開頭,使用 SVG 濾鏡實作的效果:
在文章中,我省去了大部分基礎的 CSS 代碼,完整的代碼,你可以戳這里:CodePen Demo -- Bubble Rises
最后
本文與之前的 巧用 CSS 實作酷炫的充電影片 內使用的技巧非常類似,但本文也有一些新的知識點,大家可以結合著一起看看,
好了,本文到此結束,希望對你有幫助 ??
更多精彩 CSS 技術文章匯總在我的 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏,
如果還有什么疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/498854.html
標籤:Html/Css
