文出自:閃電礦工翻譯組
原文地址:Drawing Realistic Clouds with SVG and CSS
原文作者:Beau Jackson
倉庫原文鏈接:Drawing Realistic Clouds with SVG and CSS
譯者:sichenguo
希臘神話中有這樣一個故事是講述宙斯創造出來一個云女神涅斐勒,并且類似大多數的希臘神話一樣的,這個故事非常的奇異且限制級。下面一個簡短克制的版本。
我們能夠知道的是: 涅斐勒是由宙斯以他自己美麗的妻子的形象創造的。一個凡人遇見涅斐勒,陷入愛河,并且他們一起有了一個孩子,確切的說是一個半人半馬的嬰兒。
很怪誕對吧,值得慶幸的是,在瀏覽器中創建云的過程要簡單得多,而且風險要小得多。
(Demo)
最近,我發現開發者Yuan Chuan 已經實現了用代碼生成逼真的云。對我來說,瀏覽器中的云這個概念一直如同希臘神話中的那邊神秘。
讓我們來看一下這個’畫筆‘吧 (點這里),可以見到的是作者通過使用 box-shadow 作為包含兩個濾鏡的 <filter> 元素的補充實現了這個令人驚嘆的‘云圖’!
想要繪制出兼顧寫實和精致的云圖,需要搭配使用feTurbulence 和feDisplacementMap 這兩個濾鏡。這兩個濾鏡不僅可以具有強大且復雜的功能,并且還可以提供一些令人興奮的特性(其中包含奧斯卡獲獎算法))!當然,這些功能在瀏覽器‘引擎蓋’下有著令人生畏的復雜性。
雖然這些 SVG 濾鏡的物理特性超出了本文的范圍,但 MDN 和 w3.org 上提供了大量文檔供學習參考。另外還有 feTurbulence 和 feDisplacement 介紹。
對于本文,我們將專注于學習使用這些 SVG 濾鏡來實現令人驚奇的效果。濾鏡背后的實現算法并不在我們的研究范圍內,就像藝術家雖然可以繪制出美麗的景觀但卻不用懂得油漆的分子結構。
而我們需要做的只是密切關注一小部分 SVG 屬性,這些屬性使得我們可以在瀏覽器中繪制逼真的云圖。通過學習這些屬性可以讓我們在項目中按照自己的意愿更好的制作出特定的濾鏡效果。
CSS 規則 box-shadow的五個值得關注的屬性:
box-shadow: <offsetX> <offsetY> <blurRadius> <spreadRadius> <color>;
讓我們來增大這些值(可能會高于正常的開發者會做的),這樣在視圖的右下方就會有陰影出現。 !
(Demo)
#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; }
你肯定表演或者見過過皮影戲吧?
Credit: Double-M
類似于通過改變手的形狀來改變陰影的方式,我們的 HTML 中的“源形狀”可以通過移動或者變形來同步影響其在瀏覽器中呈現的陰影的形狀。box-shadow 復制原始圖形的圓角效果。SVG 濾鏡對于元素都以及元素的 shadow 的都會生效。
<svg width="0" height="0"> <filter id="filter"> <feTurbulence type="fractalNoise" baseFrequency=".01" numOctaves="10" /> <feDisplacementMap in="SourceGraphic" scale="10" /> </filter> </svg>
到目前為止,上面的 SVG 標簽不會被渲染出來的,因為我們沒有定義任何視覺樣式(更不用說零寬度、高度)。它的唯一目的是保持我們喂養的過濾器 SourceGraphic(也就是我們的<div>)。我們的源<div>和它的陰影都被濾波器獨立地扭曲。
我們通過 ID 選擇器(#cloud-circle) 將下面的 CSS 規則添加到目標元素上:
#cloud-circle { filter: url(#filter); box-shadow: 200px 200px 50px 0px #fff; }
好吧,添加上 SVG 濾鏡依舊沒能給我們帶來什么驚喜。
(Demo)
別擔心!這才僅僅只是開始,更有趣的還在后面。
使用這一屬性進行的一些實驗可以產生顯著的效果。暫時,讓我們保持它的 feTurbulence 不變,只調整 DisplacementMap 的 scale 屬性。
隨著 scale 的增加(每次增加 30 ),我們的源 <div> 開始扭曲變形且它的投下陰影更接近天空中云隨機的形狀。
<feDisplacementMap in="SourceGraphic" scale="180" />
The scale attribute incremented by values of 30. (Demo)
好的,通過改變 scale ,好像終于接近了正確云形狀的的數值范圍!讓我們稍微改變下顏色,以便看起來更像一朵 云彩 ??。
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; }
現在我們的圖形越來越接近真實的云效果了!
下面的一組圖像顯示了 blur 對 box-shadow 效果的影響。下面的圖形中 blur 的數組依次遞增。
The cloud becomes "softer" as the blur value increases.
為了使我們的云帶有一些積云效果,可以稍微擴大 <div> 的尺寸。
#cloud-circle { width: 500px; height: 275px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 200px 200px 60px 0px #fff; }
好的,但是現在的源 div 元素正在成為障礙。
等等!我們已經擴大了源元素的尺寸,但是它現在已經開始影響我們的“云(白色陰影)”了。 很簡單,只需要相距更遠的地方投影遍可以解決這個遮擋問題。
而通過通過一些 CSS 定位很好地實現源元素的隱層。<body> 元素是云 div 元素的父元素,默認情況下是靜態定位的。 將蘇設置為就絕對定位就可以將不需要展示的 #cloud-circle 隱藏。
#cloud-circle { width: 500px; height: 275px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 400px 400px 60px 0px #fff; /* Increase shadow offset */ position: absolute; /* Take the parent out of the document flow */ top: -320px; /* Move a little down */ left: -320px; /* Move a little right */ }
很棒,這樣看起來我們的云圖已經初步成型了。
codepen
平攤在屏幕之上的云彩,嗯,這應該是一個對我們繪制出的云圖一個很好的描述,總是感覺還缺少點什么,我們應該還可以做的會更好的!
這就是我們想要的:
Credit: 圖源:pcdazero
從這張照片中云的深度,質感和豐富程度來看,有一件事是清楚的:宙斯是上過藝術學校。至少,他肯定是閱讀過通用組件設計原則的,這個原則闡述了一個通用性的概念:
[...]照明偏差在深度和自然的解釋中起著重要作用,并且可以由設計師以各種方式操縱......使用明暗區域之間的對比度使得外觀具有景深。
這段話為我們提供了一個對云圖進行優化更加真實的提示。通過將不同形狀,大小和顏色的圖層堆疊在一起,我們可以在參考圖像制造對比度中以來渲染云圖。需要的只是使用 filter 制造多個圖層。
<svg width="0" height="0"> <!-- Back Layer --> <filter id="filter-back"> <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" /> <feDisplacementMap in="SourceGraphic" scale="170" /> </filter> <!-- Middle Layer --> <filter id="filter-mid"> <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="2" /> <feDisplacementMap in="SourceGraphic" scale="150" /> </filter> <!-- Front Layer --> <filter id="filter-front"> <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="2" /> <feDisplacementMap in="SourceGraphic" scale="100" /> </filter> </svg>
再加上圖層可以提供更多的角度去探索 feTurbulence 以及 實現更多的功能。 我們選擇使用更加平滑的 type :fractalNoise,然后將 numOctaves 設置為 6。
<feTurbulence type="fractalNoise" baseFrequency="n" numOctaves="6" />
現在,讓我們將注意力集中在 baseFrequency 屬性上。以下是我們在逐漸增加 baseFrequency 值的時得到的結果 :
值取兩端的值時,圖形都會趨向于圓形。區別就是越小,更模糊。值越大,圖形就更加顯得生硬。
像 turbulence,噪音,頻率和 octave 這樣的詞可能看起來很奇怪甚至令人困惑。但不要害怕!將濾鏡的效果類比為聲波實際上非常準確。我們可以將低頻率(baseFrequency=0.001)等同于低噪聲和低頻率,更高的 (baseFrequency=0.1) 值則與更清晰的音調相對應。
我們可以看到,我們對積云效果的對應的 baseFrequency 值大概位于 0.005~0.01 范圍之間。
增大 numOctaves 的值可以以極其細致的細節渲染圖像。但是這需要大量計算,因此需要注意的是:更細致的渲染也可能帶來的還有性能問題,所以如非必要,請將此值盡量控制在一定范圍內。
The higher the value we put into numOctaves the more granular detail give to our cloud.
好消息就是,在此例中,我們的云圖需要的細節并不需要使用過高的 numOctaves 值,如上圖所示,numOctaves 為 4 或者 5 就可以得到不錯的效果。
效果圖
codepen
至于 seed 屬性還可以再深入研究一下。但是,就我們的目的而言, seed 的作用可以對形狀造成影響。
Perlin Noise 函數(上文提到)會使用此值作為其隨機數生成器的初始值。如果不設置該屬性將默認 seed為零。跟 baseFrequency 的區別就是,無論我們給出什么價值 seed,都不需要擔心性能損失。
不同的 seed 值產生不同的形狀
上面的 GIF 展示了不同 seed 值時的效果。需要注意的是,每朵云都是分層的復合云。(雖然我調整了每個圖層的屬性,但我保持各自的 seed 值分布均勻。)
Credit: Brockenhexe
在這里,仔細觀察參考圖像,我將 3 個‘云’層(不透明度不同)疊加到一個 div 上。通過反復試驗和調整 seed 參數值,最終得到的下面這個類似于照片中云的形狀的效果圖。
codepen
當然,如果我們認為我們繪制的這個云彩要比宙斯創造的女神還要漂亮,肯定就是狂妄自大了。
但是,隨著我們對 CSS 和 SVG 濾鏡的更多的了解,我們就越有能力創造出在視覺上令人驚嘆的圖形,比如下面這些:
Reflecting Mist
Animated Reflecting mist
Alto-Cirrus Clouds
在這篇文章中我們沉浸在 SVG 強大功能和復雜性的海洋中,雖然 SVG 濾鏡通常看起來比較復雜且難以理解。
然而就好像A Single Div project這個項目和Diana Smith's painting techniques這個例子一樣,有趣的和有創意的方法總是可以得到令人驚艷的效果。
我相信很多開發者都有能力制作出一個云彩出來,但是一個可以輕松制作出云彩的工具會更受歡迎。因此我開發了一個小工具做這件事。
容提要:本文講解的Photoshop制作閃電效果教程主要使用到風格化濾鏡、等高線濾鏡、云彩濾鏡的綜合使用.
本文我們以在Photoshop里面為一幅海報添加制作閃電效果為案例,和大家分享。先呈現海報原圖和使用PS添加閃電效果之后的對比圖。
ps制作閃電效果分析:
教程中我們將制作電影海報中那些強大的魔法閃電效果。制作中主要利用Photoshop里面的“云彩”“等高線”等濾鏡進行制作。
PS閃電效果操作步驟:
(1)執行“文件”→“打開”命令,打開一幅電影背景圖片,如圖31。
(2)在“圖層”面板中在新建“圖層 1”并為其填充黑色,如圖32。
(3)執行“濾鏡”→“渲染”→“云彩”命令,為“圖層1”創建云彩效果,如圖33。
(4)執行“濾鏡”→“風格化”→“等高線”命令,打開“等高線”對話框,為圖像添加等高線濾鏡效果,如圖34。
(5)按Ctrl+I將圖像顏色反相,然后在“通道”調板中載入選區,參數如圖35。
(6)將選區反選,切換到“圖層”面板,將選區內的圖像刪除,如圖36。
(7)取消選區的浮動狀態,執行“圖層”→“圖層樣式”→“外發光”命令,打開“圖層樣式”對話框,為圖像添加外發光效果,如圖37。
(8)將“圖層 1”進行復制,并將復制后的圖層改名為“閃電”,然后將“圖層 1”圖層隱藏,如圖38。
(9)按快捷鍵Ctrl+T執行“自由變換”命令,然后右擊鼠標,在彈出的快捷菜單中選擇“變形”命令,如圖39。
(10)調整圖像周圍的控制柄,對圖像進行變形,調整完畢后單擊Enter鍵確認操作,如圖40。
(11)為“閃電”圖層添加圖層蒙版,并使用“畫筆”工具對蒙版進行編輯,如圖41。
(12)在“圖層”面板中復制“閃電”圖層,兩個圖層重疊后,閃電的光亮度增強。繼續使用“畫筆”工具對蒙版進行編輯,減弱一些區域的外發光效果,如圖42。
(13)將兩個閃電圖層隱藏,并將“圖層1”顯示,使用“矩形”選框工具,繪制選區,將選區內的圖像拷貝至新圖層中,如圖43。
(14)調整“圖層2”中圖像的大小、位置和旋轉角度,完畢后將其復制,如圖44。
(15)將“圖層 1”隱藏,參照以上方法,多次復制“圖層2”中的圖像,并調整大小、位置和旋轉角度,效果如下圖45。
(16)將兩個閃電圖層顯示,使用畫筆工具,設置圓形筆觸在任何一個圖層2上繪制,即可添加光斑效果,至此完成本實例的制作,如圖46。
本文的ps制作閃電效果案例教程就到此結束。如果你想和我一樣當一個懶人,當然你也可以使用一些現成的閃電效果外掛插件來制作,請看教程:www.ittribalwo.com/article/2347.html
Photoshop風格化濾鏡小結:
我們本系列的Photoshop風格化濾鏡一共制作了三個案例,分別使用了查找邊緣、浮雕效果和等高線等幾個濾鏡,讓我們對風格化濾鏡有了一個比較全面的認識,學到更多的知識。比如:“查找邊緣”濾鏡用于標識圖像中有明顯過渡的區域并強調邊緣; "等高線"濾鏡在白色背景上用深色線條勾畫圖像的邊緣,對于在圖像周圍創建邊框非常有用;“浮雕”濾鏡則是通過將圖像顏色轉換為灰色,并用原圖像的各處輪廓色描畫邊緣,從而使圖像顯得凸起或壓低。
擊右上方紅色按鈕關注“web秀”,讓你真正秀起來
好雨知時節,當春乃發生。 隨風潛入夜,潤物細無聲。
春節已經過去,新的一年剛剛開始,小伙伴們,今年你的目標是什么?定個小目標,掙它一個億?分享一下我的目標,是讓大家的web前端能力,更上一層樓。
下面進入主題,看下圖:
CSS3線性漸變、陰影、縮放實現動畫下雨效果
這個動畫效果,如果讓你來做,你會選擇什么方式?相信很多小伙伴都會用gif圖片。其實用css實現也很簡單。
如果文章中有不懂的知識點,請點擊文章最下方,推薦文章哦
很明顯這個動畫效果,是上中下結構,所以我們分3部分實現。
1、云:由多個圓拼接而成,并且有上下浮動的動畫效果
2、雨滴:多個,從上而下的動畫效果
3、陰影:橢圓,縮放動畫效果
下面我們按步驟實現
用box-shadow制作多個圓,完成拼接,行程完整的云朵。animation,添加動畫,上下浮動。
語法:box-shadow: h-shadow v-shadow blur spread color inset;
注:box-shadow,向框內添加一個或多個陰影。該屬性是由逗號分隔的陰影列表,每個陰影由 2-4 個長度值、可選的顏色值以及可選的 inset 關鍵詞來規定。省略長度的值是 0。
CSS3線性漸變、陰影、縮放實現動畫下雨效果
相關推薦CSS3 box-shadow實現背景動畫
.rainy { position: absolute; top: 30%; left: 50%; } .rainy:before { content: ""; color: #333; position: absolute; height: 50px; width: 50px; top: 30px; left: -40px; background: #CCC; transform: translate(-50%, -50%); border-radius: 50%; box-shadow: #CCC 65px -15px 0 -5px, #CCC 25px -25px, #CCC 30px 10px, #CCC 60px 15px 0 -10px, #CCC 85px 5px 0 -5px; animation: cloudy 5s ease-in-out infinite; } @keyframes cloudy { 50% { transform: translate(-50%, -70%); } 100% { transform: translate(-50%, -50%); } }
CSS3線性漸變、陰影、縮放實現動畫下雨效果
雨滴和云一樣,都是用box-shadow來實現,但是雨滴的實現要復雜的多,雨滴數量多,每個雨滴位置的改變。
.rainy { position: absolute; width: 3px; height: 6px; top: 30%; left: 50%; animation: rainy_rain .7s infinite linear; } .rainy:before { ... } @keyframes cloudy { ... } @keyframes rainy_rain { 0% { box-shadow: rgba(0, 0, 0, 0) -10px 30px, rgba(0, 0, 0, 0) 40px 40px, rgba(0, 0, 0, .3) -50px 75px, rgba(0, 0, 0, .3) 55px 50px, rgba(0, 0, 0, .3) -18px 100px, rgba(0, 0, 0, .3) 12px 95px, rgba(0, 0, 0, .3) -31px 45px, rgba(0, 0, 0, .3) 30px 35px; } 25% { box-shadow: rgba(0, 0, 0, .3) -10px 45px, rgba(0, 0, 0, .3) 40px 60px, rgba(0, 0, 0, .3) -50px 90px, rgba(0, 0, 0, .3) 55px 65px, rgba(0, 0, 0, 0) -18px 120px, rgba(0, 0, 0, 0) 12px 120px, rgba(0, 0, 0, .3) -31px 70px, rgba(0, 0, 0, .3) 30px 60px; } 26% { box-shadow: rgba(0, 0, 0, .3) -10px 45px, rgba(0, 0, 0, .3) 40px 60px, rgba(0, 0, 0, .3) -50px 90px, rgba(0, 0, 0, .3) 55px 65px, rgba(0, 0, 0, 0) -18px 40px, rgba(0, 0, 0, 0) 12px 20px, rgba(0, 0, 0, .3) -31px 70px, rgba(0, 0, 0, .3) 30px 60px; } 50% { box-shadow: rgba(0, 0, 0, .3) -10px 70px, rgba(0, 0, 0, .3) 40px 80px, rgba(0, 0, 0, 0) -50px 100px, rgba(0, 0, 0, .3) 55px 80px, rgba(0, 0, 0, .3) -18px 60px, rgba(0, 0, 0, .3) 12px 45px, rgba(0, 0, 0, .3) -31px 95px, rgba(0, 0, 0, .3) 30px 85px; } 51% { box-shadow: rgba(0, 0, 0, .3) -10px 70px, rgba(0, 0, 0, .3) 40px 80px, rgba(0, 0, 0, 0) -50px 45px, rgba(0, 0, 0, .3) 55px 80px, rgba(0, 0, 0, .3) -18px 60px, rgba(0, 0, 0, .3) 12px 45px, rgba(0, 0, 0, .3) -31px 95px, rgba(0, 0, 0, .3) 30px 85px; } 75% { box-shadow: rgba(0, 0, 0, .3) -10px 95px, rgba(0, 0, 0, .3) 40px 100px, rgba(0, 0, 0, .3) -50px 60px, rgba(0, 0, 0, 0) 55px 95px, rgba(0, 0, 0, .3) -18px 80px, rgba(0, 0, 0, .3) 12px 70px, rgba(0, 0, 0, 0) -31px 120px, rgba(0, 0, 0, 0) 30px 110px; } 76% { box-shadow: rgba(0, 0, 0, .3) -10px 95px, rgba(0, 0, 0, .3) 40px 100px, rgba(0, 0, 0, .3) -50px 60px, rgba(0, 0, 0, 0) 55px 35px, rgba(0, 0, 0, .3) -18px 80px, rgba(0, 0, 0, .3) 12px 70px, rgba(0, 0, 0, 0) -31px 25px, rgba(0, 0, 0, 0) 30px 15px; } 100% { box-shadow: rgba(0, 0, 0, 0) -10px 120px, rgba(0, 0, 0, 0) 40px 120px, rgba(0, 0, 0, .3) -50px 75px, rgba(0, 0, 0, .3) 55px 50px, rgba(0, 0, 0, .3) -18px 100px, rgba(0, 0, 0, .3) 12px 95px, rgba(0, 0, 0, .3) -31px 45px, rgba(0, 0, 0, .3) 30px 35px; } }
CSS3線性漸變、陰影、縮放實現動畫下雨效果
陰影實現是最簡單的啦,加上縮放,透明度改變就可以了,當然要和上面的云配合起來,云上,陰影變小,云下,陰影變大。
.rainy:after { content: ""; position: absolute; top: 120px; left: 50%; height: 15px; width: 120px; background: rgba(0, 0, 0, .5); border-radius: 50%; transform: translate(-50%, -50%); animation: cloudy_shadow 5s ease-in-out infinite; } @keyframes cloudy_shadow { 50% { transform: translate(-50%, -50%) scale(0.8); background: rgba(0, 0, 0, .2); } 100% { transform: translate(-50%, -50%) scale(1); background: rgba(0, 0, 0, .5); } }
演示地址:http://demo.javanx.cn/raindrop/index2.html
CSS3 box-shadow實現背景動畫
從淺到深的學習 CSS3陰影(box-shadow)
CSS3最容易混淆屬性transition transform animation translate
喜歡小編的點擊關注,了解更多知識!
源碼地址和源文件下載請點擊下方“了解更多”
*請認真填寫需求信息,我們會在24小時內與您取得聯系。