一篇帶你實現(xiàn)一個會動的鴻蒙 LOGO
Hello 大家好,我是 Coco。本文將帶大家簡單實現(xiàn)一個會動的鴻蒙 LOGO。
emmm,寫本文的動機是之前在掘金看到一篇實現(xiàn)鴻蒙 LOGO 的文章 -- 產(chǎn)品經(jīng)理:鴻蒙那個開場動畫挺帥的 給咱們頁面也整一個唄[1]
鴻蒙的 LOGO 本身是這樣的:
該篇作者最終實現(xiàn)的是一個字母 O 的動畫展開過程:
而本文想嘗試的,是該 LOGO 的其他一些細節(jié),核心是倒影部分的水波效果。
實現(xiàn)主體
首先,我們需要對該結構進行簡單的一個拆解,因為上下部分的較大差異,雖然是一個圓,但是很明顯需要分成兩塊處理,這部分比較簡單且不是重點,我就略過分享,直接上代碼。
我們的結構大致如下:
- <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);
- }
- }
核心做的就是上下兩個半圓的實現(xiàn),以及對下面部分使用了模糊濾鏡 filter: blur(),我們可以初步得到這樣一個結構:
好吧,看著確實是平平無奇。
添加 SVG feTurbulence 濾鏡。實現(xiàn)水波倒影效果
OK,下面就是見證奇跡的時刻。我們給下部分的 g-bottom 添加一個 SVG feTurbulence 濾鏡,讓它產(chǎn)生水波倒影效果。
SVG feTurbulence 濾鏡在我的非常多篇文章中都有提到,turbulence 意為湍流,不穩(wěn)定氣流,而 SVG
- 如果你對 SVG 濾鏡還不算太了解,可以簡單看看我的這幾篇文章入門:有意思!強大的 SVG 濾鏡[2] 以及這篇實戰(zhàn)篇:震驚!巧用 SVG 濾鏡還能制作表情包?[3]
emmm,所以步驟是:
- 實現(xiàn)一個 SVG feTurbulence 效果
- 加上 SVG animation 動畫,
- 再通過 CSS Filter 引用至濾鏡到 DOM 結構之上
- <!-- 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 一些無法實現(xiàn)的功能。
通過漸變及 MASK 實現(xiàn)光圈
再看看原圖,還有一圈圈的藍色光圈,這個使用 repeating-radial-gradient 及 mask 可以實現(xiàn)。
簡單的代碼如下:
- <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 實現(xiàn)漸隱的光圈效果,結果如下:
把這個光圈往效果里疊加,及其他一些小細節(jié)及文字,最終可以實現(xiàn)一個這樣的 LOGO 效果(雖然也不是很像,還有很多細節(jié)沒還原):
完整的代碼你可以猛擊這里:CSS 靈感 -- SVG 濾鏡及 filter: blur 實現(xiàn)鴻蒙 LOGO[4]
腦洞一下
運用上述的 SVG feTurbulence 濾鏡,我們能不能再搞點事情呢?
我們可以利用它,嘗試去實現(xiàn)這樣的效果,實現(xiàn)圖片的部分動態(tài)波動,運用在特定的場景,能夠非常大的提升用戶體驗,讓人“哇塞”一下:
又或者是:
(圖片幀率有點低,放大看遠處的天際線)
上述兩個效果來自:tympanus - Distortion Effect[5],但是它們并非是使用 CSS + SVG 實現(xiàn),而是使用的 WebGL,但是它們確實可以用上述的方式復現(xiàn)。
假設我們有這樣一張圖:
下面,我們就利用 SVG feTurbulence 讓中間的石頭波動起來:
- 我們讓兩張一模一樣的圖疊加在一起(使用 div 及它的偽元素即可)
- 利用 clip-path 將疊在上層的圖中的石頭切割出來
- 利用 SVG feTurbulence 將濾鏡作用給上層的圖片
完整的代碼如下:
- <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);
- }
- }
這樣,我們就能得到一張動起來的石頭,我們利用一張靜態(tài)圖,實現(xiàn)了其中部分的動態(tài)波動效果:
CodePen Demo -- SVG feTurbulence Image Effect[6]
利用這個技巧,我們可以很輕松的還原上述兩個使用 WebGL 實現(xiàn)的效果。Amazing~
最后
好了,本文到此結束,希望對你有幫助 :)
參考資料
[1]產(chǎn)品經(jīng)理:鴻蒙那個開場動畫挺帥的 給咱們頁面也整一個唄:
https://juejin.cn/post/6979042510400126983
[2]有意思!強大的 SVG 濾鏡:
https://github.com/chokcoco/cnblogsArticle/issues/27
[3]震驚!巧用 SVG 濾鏡還能制作表情包?:
https://github.com/chokcoco/iCSS/issues/107
[4]CSS 靈感 -- SVG 濾鏡及 filter: blur 實現(xiàn)鴻蒙 LOGO:
https://csscoco.com/inspiration/#/./svg/svg-feTurbulence-harmony-logo.md
[5]tympanus - Distortion Effect:
https://tympanus.net/Tutorials/HeatDistortionEffect/index3.html
[6]CodePen Demo -- SVG feTurbulence Image Effect:
https://codepen.io/Chokcoco/pen/VwWKxdb