目錄
SVG和CSS打造逼真雲朵效果
從基礎開始
瞧!
實驗feDisplacementMapscale屬性
修改box-shadowblur
使用圖層表達深度
使用numOctaves添加細節
結果如下
使用seed屬性實現無限變化
天馬行空
成就解鎖!涅菲勒雲朵生成器
首頁 web前端 css教學 用SVG和CSS繪製逼真的雲

用SVG和CSS繪製逼真的雲

Apr 20, 2025 am 10:44 AM

SVG和CSS打造逼真雲朵效果

Drawing Realistic Clouds with SVG and CSS

希臘神話中,宙斯創造了雲仙女涅菲勒。和其它希臘神話一樣,這個故事相當離奇。這裡是一個簡短且合適的版本:

傳說中,涅菲勒是宙斯以自己美麗妻子的形象創造的。一位凡人邂逅涅菲勒,愛上了她,他們一起……最終,不可思議的是,這朵雲誕下了半人半馬的半人馬嬰兒。

很奇怪,對吧?我個人也無法理解。幸運的是,在瀏覽器中創建雲朵的過程要簡單得多,也正經得多。

最近,我發現開發者Yuan Chuan實現了代碼生成的、逼真的雲朵效果。對我來說,這種在瀏覽器中實現的效果曾經是神話故事。

只需瀏覽一下這個示例代碼,我們就能想像到,通過使用帶有<filter></filter>元素(包含兩個SVG濾鏡)的CSS box-shadow ,可以實現令人信服的單個雲朵效果。

我們想要的逼真效果是通過feTurbulencefeDisplacementMap的巧妙結合實現的。這些SVG濾鏡功能強大、複雜且提供了非常令人興奮的功能(包括一個奧斯卡獲獎算法!)。然而,其底層複雜性可能會讓人望而生畏。

雖然SVG濾鏡的物理原理超出了本文的範圍,但在MDN和w3.org上提供了大量的文檔。關於feTurbulencefeDisplacementMap的非常有益的頁面是免費提供的(並且作為這本精彩書籍的一個章節)。

在本文中,我們將專注於學習如何使用這些SVG濾鏡來獲得驚人的效果。我們不需要深入了解幕後算法的運作方式,就像藝術家不需要了解顏料的分子結構就能渲染出令人驚嘆的風景一樣。

相反,讓我們密切關注幾個對在瀏覽器中繪製令人信服的雲朵至關重要的SVG屬性。使用這些屬性,我們可以將這些強大的濾鏡運用自如,並學習如何在自己的項目中精確地自定義它們。

從基礎開始

CSS box-shadow屬性有五個值得關注的值:

 <code>box-shadow:<offsetx><offsety><blurradius><spreadradius><color> ;</color></spreadradius></blurradius></offsety></offsetx></code>
登入後複製

讓我們將這些值調高(可能高於任何理智的開發者會使用的值),這樣陰影本身就會成為舞台上的一個角色。

 <code>#cloud-square { background: turquoise; box-shadow: 200px 200px 50px 0px #000; width: 180px; height: 180px; } #cloud-circle { background: coral; border-radius: 50%; box-shadow: 200px 200px 50px 0px #000; width: 180px; height: 180px; }</code>
登入後複製

你玩過或者見過影子戲嗎?

就像用手改變形狀來改變陰影一樣,我們HTML中的“源形狀”可以移動和變形來移動和改變在瀏覽器中渲染的陰影的形狀。 box-shadow複製了原始大小和border-radius上的“變形”功能。 SVG濾鏡同時應用於元素及其陰影。

<code><svg height="0" width="0"><filter><feturbulence basefrequency=".01" numoctaves="10" type="fractalNoise"></feturbulence><fedisplacementmap in="SourceGraphic" scale="10"></fedisplacementmap></filter></svg></code>
登入後複製

這是我們目前SVG的標記。它不會渲染,因為我們還沒有定義任何視覺效果(更不用說零寬度和高度了)。它的唯一目的是保存一個濾鏡,我們將這個濾鏡提供給我們的SourceGraphic (也就是我們的<div>)。我們的源<code><div>及其陰影都由濾鏡獨立扭曲。我們將添加必要的CSS規則,使用其ID將HTML元素( <code>#cloud-circle )鏈接到SVG濾鏡:

 <code>#cloud-circle { filter: url(#filter); box-shadow: 200px 200px 50px 0px #fff; }</code>
登入後複製

瞧!

好吧,承認吧,添加SVG濾鏡相當不起眼。

別擔心!我們只是觸及了表面,還有很多好東西要看。

實驗feDisplacementMapscale屬性

對這個屬性進行一些非科學的實驗可以產生戲劇性的效果。目前,讓我們保持feTurbulence中的所有值不變,只需調整DisplacementMapscale屬性。

隨著scale值的增加(以30為增量),我們的源<div>會發生扭曲,並投射出陰影來反映雲朵在天空中的隨機形態。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">&lt;code&gt;&lt;fedisplacementmap in=&quot;SourceGraphic&quot; scale=&quot;180&quot;&gt;&lt;/fedisplacementmap&gt;&lt;/code&gt;</pre><div class="contentsignin">登入後複製</div></div> <p>好了,我們有所進展!讓我們稍微改變一下顏色,以產生更令人信服的雲朵效果,並增強效果。</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> &lt;code&gt;body { background: linear-gradient(165deg, #527785 0%, #7FB4C7 100%); } #cloud-circle { width: 180px; height: 180px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 200px 200px 50px 0px #fff; }&lt;/code&gt;</pre><div class="contentsignin">登入後複製</div></div> <p>現在我們更接近逼真的雲朵效果了!</p> <h3 id="修改-code-box-shadow-code-的-code-blur-code-值">修改<code>box-shadowblur

下面的圖像系列顯示了blur值對box-shadow的影響。在這裡, blur值以10像素為增量增加。

為了使我們的雲朵具有一些積雲般的效果,我們可以稍微加寬我們的源<div>。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> &lt;code&gt;#cloud-circle { width: 500px; height: 275px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 200px 200px 60px 0px #fff; }&lt;/code&gt;</pre><div class="contentsignin">登入後複製</div></div> <p>等等!我們加寬了源元素,現在它擋住了我們稱之為雲朵的白色陰影。讓我們將陰影“重新投射”到更遠的距離,這樣我們的雲朵就不會被源圖像遮擋。 (可以想像一下,將你的手從牆上移開,這樣就不會擋住影子戲的視線。)</p> <p>這可以通過一些CSS定位輕鬆實現。<code><div>是雲朵的父元素,默認情況下是靜態定位的。讓我們用一些絕對定位將我們的源<code><div>“塞”起來並移出文檔流。最初,這也會重新定位我們的陰影,因此我們還需要增加陰影與元素的距離,並稍微調整元素的位置。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> &lt;code&gt;#cloud-circle { width: 500px; height: 275px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 400px 400px 60px 0px #fff; /* 增加阴影偏移量*/ position: absolute; /* 将父元素移出文档流*/ top: -320px; /* 向下移动*/ left: -320px; /* 向右移动*/ }&lt;/code&gt;</pre><div class="contentsignin">登入後複製</div></div> <p>是的!我們已經得到了一個相當令人信服的雲朵。</p> <p>渲染到瀏覽器中的圖像對雲朵的描繪相當不錯——但是,我不確定……這朵雲真的能體現雲仙女涅菲勒嗎?我相信我們可以做得更好!</p> <h3 id="使用圖層表達深度">使用圖層表達深度</h3> <p>這就是我們想要的:</p> <p>從這張照片中云朵的深度、紋理和豐富性來看,有一點很清楚:宙斯上過美術學校。至少,他一定讀過《設計的普遍原則》,其中闡述了一個強大而看似普通的概念:</p> <blockquote><p> […] 照明偏差在深度和自然感的解釋中起著重要作用,並且可以通過設計師以各種方式進行操作……使用光暗區域之間的對比度來改變深度的外觀。</p></blockquote> <p>這段話為我們提供了一個線索,說明我們如何才能大大改進我們自己生成的雲朵代碼。我們可以通過將不同形狀、大小和顏色的圖層堆疊在一起,來渲染出與參考圖像中的雲朵高度相似的雲朵。這只需要根據需要多次調用我們的濾鏡即可。 </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">&lt;code&gt;&lt;svg height=&quot;0&quot; width=&quot;0&quot;&gt;&lt;filter&gt;&lt;feturbulence basefrequency=&quot;0.012&quot; numoctaves=&quot;4&quot; type=&quot;fractalNoise&quot;&gt;&lt;/feturbulence&gt;&lt;fedisplacementmap in=&quot;SourceGraphic&quot; scale=&quot;170&quot;&gt;&lt;/fedisplacementmap&gt;&lt;/filter&gt;&lt;filter&gt;&lt;feturbulence basefrequency=&quot;0.012&quot; numoctaves=&quot;2&quot; type=&quot;fractalNoise&quot;&gt;&lt;/feturbulence&gt;&lt;fedisplacementmap in=&quot;SourceGraphic&quot; scale=&quot;150&quot;&gt;&lt;/fedisplacementmap&gt;&lt;/filter&gt;&lt;filter&gt;&lt;feturbulence basefrequency=&quot;0.012&quot; numoctaves=&quot;2&quot; type=&quot;fractalNoise&quot;&gt;&lt;/feturbulence&gt;&lt;fedisplacementmap in=&quot;SourceGraphic&quot; scale=&quot;100&quot;&gt;&lt;/fedisplacementmap&gt;&lt;/filter&gt;&lt;/svg&gt;&lt;/code&gt;</pre><div class="contentsignin">登入後複製</div></div> <p>應用我們的圖層將使我們有機會探索<code>feTurbulence並實現其多功能性。我們將選擇可用的更平滑的類型: fractalNoise ,並將numOctaves調高到6。

<code><feturbulence basefrequency="n" numoctaves="6" type="fractalNoise"></feturbulence></code>
登入後複製

這意味著什麼?現在,讓我們重點關注baseFrequency屬性。以下是我們增加n的值時得到的結果:

諸如湍流噪聲頻率倍頻程之類的詞語可能顯得奇怪甚至令人困惑。但是別擔心!將這個濾鏡的效果比作聲波實際上是完全準確的。我們可以將低頻( baseFrequency=0.001 )與低沉的噪聲聯繫起來,並將高頻( baseFrequency=0.1 )與更高、更清晰的音調聯繫起來。

我們可以看到,對於積雲般的效果, baseFrequency的值可能舒適地位於~0.005和~0.01範圍內。

使用numOctaves添加細節

遞增numOctaves允許我們以極其精細的細節來渲染圖像。這需要大量的計算,因此請注意:高值會嚴重影響性能。除非你的瀏覽器戴著頭盔和護膝,否則盡量避免提高這個值。

好消息是,我們不需要將這個值調得太高就能產生細節和精細度。如上圖所示,我們可以將numOctaves值設置為4或5。

結果如下

使用seed屬性實現無限變化

關於seed屬性有很多內容需要說明,因為它暗示了幕後發生的魔法。但是,就我們的目的而言, seed的效用可以用四個字概括:“不同的值,不同的形狀”。

Perlin噪聲函數(前面提到過)使用此值作為其隨機數生成器的起點。選擇不包含此屬性將默認seed為零。但是,如果包含此屬性,無論我們賦予seed什麼值,都不需要擔心性能問題。

上面的GIF代表了seed提供的一些功能。請記住,每一朵雲都是一個分層的複合雲。 (雖然我已經調整了每個圖層的屬性,但我保持了它們各自的seed值一致。)

在這裡,仔細觀察參考圖像,我已經將3個雲<div>(不透明度不同)疊加到一個基礎<code><div>上。通過反複試驗和輸入任意<code>seed值,我最終得到了一個類似於照片中云朵形狀的形狀。

天馬行空

當然,認為我們繪製到瀏覽器上的<div>會優於宙斯的涅菲勒,那將是狂妄自大。然而,我們能夠從CSS和SVG濾鏡中挖掘出越多的奧秘,我們就越有能力創造出視覺上令人驚嘆的東西,並且與雷神最初的創造高度相似。然後,我們可以繼續進行進一步的實驗!<p>反射霧氣</p> <p>高層卷雲</p> <p>在本文中,我們只是涉足了一個充滿力量和復雜性的海洋。 SVG濾鏡通常看起來令人不知所措且難以接近。</p> <p>然而,就像A Single Div項目中的示例或Diana Smith的繪畫技巧一樣,一種輕鬆愉快的實驗方法總是會帶來驚人的結果!</p> <h4 id="成就解鎖-涅菲勒雲朵生成器">成就解鎖!涅菲勒雲朵生成器</h4> <p>我相信你們很多人很樂意深入了解製作雲朵所需的所有技術細節,但可能更喜歡一些更方便在項目中使用雲朵的方法。我開發了一個小工具來幫助生成雲朵並實驗形狀和變化。</p> <p>生成雲朵!</p> <p>有任何問題、建議或意見?請在Twitter上聯繫我,或在此帖中發表評論。</p> <p><small>非常感謝Amelia Bellamy-Royds對本文提出的寶貴建議。</small></p> </div>

以上是用SVG和CSS繪製逼真的雲的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

VUE 3 VUE 3 Apr 02, 2025 pm 06:32 PM

它的出局!恭喜Vue團隊完成了完成,我知道這是一項巨大的努力,而且很長時間。所有新文檔也是如此。

您可以從瀏覽器獲得有效的CSS屬性值嗎? 您可以從瀏覽器獲得有效的CSS屬性值嗎? Apr 02, 2025 pm 06:17 PM

我有人寫了這個非常合法的問題。 Lea只是在博客上介紹瞭如何從瀏覽器中獲得有效的CSS屬性。那樣的是這樣。

在CI/CD上有點 在CI/CD上有點 Apr 02, 2025 pm 06:21 PM

我說的“網站”比“移動應用程序”更合適,但我喜歡Max Lynch的框架:

帶有粘性定位的堆疊卡和一點點的雜物 帶有粘性定位的堆疊卡和一點點的雜物 Apr 03, 2025 am 10:30 AM

前幾天,我發現了科里·金尼文(Corey Ginnivan)網站上的這一點,當您滾動時,彼此之間的卡片堆放集。

在WordPress塊編輯器中使用Markdown和本地化 在WordPress塊編輯器中使用Markdown和本地化 Apr 02, 2025 am 04:27 AM

如果我們需要直接在WordPress編輯器中向用戶顯示文檔,那麼最佳方法是什麼?

比較瀏覽器的響應式設計 比較瀏覽器的響應式設計 Apr 02, 2025 pm 06:25 PM

這些桌面應用程序中有許多目標是同時在不同的維度上顯示您的網站。因此,例如,您可以寫作

如何將CSS網格用於粘頭和頁腳 如何將CSS網格用於粘頭和頁腳 Apr 02, 2025 pm 06:29 PM

CSS網格是一系列屬性的集合,旨在使佈局比以往任何時候都容易。像任何東西一樣,那裡有一點學習曲線,但是網格是

為什麼Flex佈局中的紫色斜線區域會被誤認為是'溢出空間”? 為什麼Flex佈局中的紫色斜線區域會被誤認為是'溢出空間”? Apr 05, 2025 pm 05:51 PM

關於Flex佈局中紫色斜線區域的疑問在使用Flex佈局時,你可能會遇到一些令人困惑的現象,比如在開發者工具(d...

See all articles