本文將帶大家簡單實現一個會動的鴻蒙 LOGO。
emmm,寫本文的動機是之前在掘金看到一篇實現鴻蒙 LOGO 的文章 -- 產品經理:鴻蒙那個開場動畫挺帥的 給咱們頁面也整一個唄
鴻蒙的 LOGO 本身是這樣的:
該篇作者最終實現的是一個字母 O 的動畫展開過程:
而本文想嘗試的,是該 LOGO 的其他一些細節,核心是倒影部分的水波效果。
首先,我們需要對該結構進行簡單的一個拆解,因為上下部分的較大差異,雖然是一個圓,但是很明顯需要分成兩塊處理,這部分比較簡單且不是重點,我就略過分享,直接上程式碼。
我們的結構大致如下:
<div class="g-container">
<div class="g-top">
</div>
<div class="g-bottom">
</div>
</div>
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;1,200&display=swap');
.g-container {
width: 100%;
height: 100%;
background: #000;
}
.g-top {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 50vh;
overflow: hidden;
&::before {
content: "";
position: absolute;
border-radius: 50%;
bottom: 0;
left: 50%;
width: 200px;
height: 200px;
transform: translate(-50%, 100px);
box-sizing: border-box;
background: #000;
border: 25px solid #fff;
z-index: 1;
box-shadow:
0 0 4px 1px rgba(255, 255, 255, .8),
0 0 8px 2px rgba(255, 255, 255, .6);
}
}
.g-bottom {
position: fixed;
top: 50vh;
left: 0;
width: 100vw;
height: 50vh;
background: #000;
overflow: hidden;
&::before {
content: "";
position: absolute;
border-radius: 50%;
top: 0;
width: 200px;
height: 200px;
background: #000;
left: 50%;
transform: translate(-50%, -100px);
box-sizing: border-box;
border: 25px solid #fff;
z-index: 2;
box-shadow:
0 0 4px rgba(255, 255, 255, .8),
0 0 8px rgba(255, 255, 255, .7),
0 0 20px rgba(255, 255, 255, .6);
filter: blur(4px);
}
}
核心做的就是上下兩個半圓的實現,以及對下面部分使用了模糊濾鏡 filter: blur()
,我們可以初步得到這樣一個結構:
好吧,看著確實是平平無奇。
OK,下面就是見證奇蹟的時刻。我們給下部分的 g-bottom
新增一個 SVG feTurbulence 濾鏡,讓它產生水波倒影效果。
SVG feTurbulence 濾鏡在我的非常多篇文章中都有提到,turbulence 意為湍流,不穩定氣流,而 SVG <feTurbulence>
濾鏡能夠實現半透明的煙燻或波狀影象。通常用於實現一些特殊的紋理。濾鏡利用 Perlin 噪聲函數建立了一個影象。噪聲在模擬雲霧效果時非常有用,能產生非常複雜的質感,利用它可以實現了人造紋理比如說雲紋、大理石紋的合成。
如果你對 SVG 濾鏡還不算太瞭解,可以簡單看看我的這幾篇文章入門:有意思!強大的 SVG 濾鏡 以及這篇實戰篇: 震驚!巧用 SVG 濾鏡還能製作表情包?
emmm,所以步驟是:
<!-- HTML 結構下的 SVG 程式碼 -->
<svg>
<filter id="fractal" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
<feTurbulence id="turbulence" type="fractalNoise" baseFrequency="0.01 0.01" numOctaves="10">
<animate
attributeName="baseFrequency"
dur="30s"
values="0.01 0.01;0.03 0.15;0.01 0.01"
repeatCount="indefinite" />
</feTurbulence>
<feDisplacementMap in="SourceGraphic" scale="15"></feDisplacementMap>
</filter>
</svg>
.g-bottom {
// 通過 Filter 參照 SVG 濾鏡到 DOM 結構之上
filter: url(#fractal);
}
Wow,僅僅是一個濾鏡的疊加,就瞬間讓動畫高大上了起來。這也是 SVG feTurbulence 濾鏡的魅力所在,完成了 CSS 一些無法實現的功能。
再看看原圖,還有一圈圈的藍色光圈,這個使用 repeating-radial-gradient
及 mask
可以實現。
簡單的程式碼如下:
<div></div>
div {
background: repeating-radial-gradient(circle at 50% 100%, transparent, transparent 5px, #2c5ec8 5.2px, #2c5ec8 6.2px, transparent 6.5px);
mask: radial-gradient(circle at 50% 100%, rgba(255, 255, 255, .8), transparent 25%, transparent);
}
repeating-radial-gradient
配合 mask
實現漸隱的光圈效果,結果如下:
把這個光圈往效果裡疊加,及其他一些小細節及文字,最終可以實現一個這樣的 LOGO 效果(雖然也不是很像,還有很多細節沒還原):
完整的程式碼你可以猛擊這裡:CSS 靈感 -- SVG 濾鏡及 filter: blur 實現鴻蒙 LOGO
運用上述的 SVG feTurbulence 濾鏡,我們能不能再搞點事情呢?
我們可以利用它,嘗試去實現這樣的效果,實現圖片的部分動態波動,運用在特定的場景,能夠非常大的提升使用者體驗,讓人「哇塞」一下:
又或者是:
上述兩個效果來自:tympanus - Distortion Effect,但是它們並非是使用 CSS + SVG 實現,而是使用的 WebGL,但是它們確實可以用上述的方式復現。
假設我們有這樣一張圖:
下面,我們就利用 SVG feTurbulence 讓中間的石頭波動起來:
clip-path
將疊在上層的圖中的石頭切割出來完整的程式碼如下:
<div></div>
<svg>
<filter id="fractal" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
<feTurbulence id="turbulence" type="fractalNoise" baseFrequency="0.005 0.005" numOctaves="10">
<animate
attributeName="baseFrequency"
dur="60s"
values="0.005 0.005;0.003 0.03;0.005 0.005"
repeatCount="indefinite" />
</feTurbulence>
<feDisplacementMap in="SourceGraphic" scale="15"></feDisplacementMap>
</filter>
</svg>
div {
position: relative;
width: 600px;
height: 400px;
background-image: url(https://z3.ax1x.com/2021/09/05/hWPVqe.jpg);
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: inherit;
clip-path: polygon(225px 50px, 320px 50px, 320px 90%, 225px 90%);
filter: url(#fractal);
}
}
這樣,我們就能得到一張動起來的石頭,我們利用一張靜態圖,實現了其中部分的動態波動效果:
CodePen Demo -- SVG feTurbulence Image Effect
利用這個技巧,我們可以很輕鬆的還原上述兩個使用 WebGL 實現的效果。Amazing~
好了,本文到此結束,希望對你有幫助