有意思!強大的 SVG 濾鏡

想寫一篇關於 SVG 濾鏡的文章已久,SVG 濾鏡的存在,讓原本就很是強大的 CSS 如虎添翼。讓僅僅使用 CSS/HTML/SVG 創做的效果更上一層樓。題圖爲袁川老師使用 SVG 濾鏡實現的雲彩效果 -- CodePen Demo -- Cloud (SVG filter + CSS)css

什麼是 SVG 濾鏡

SVG 濾鏡與 CSS 濾鏡相似,是 SVG 中用於建立複雜效果的一種機制。不少人看到 SVG 濾鏡複雜的語法容易心生退意。本文力圖使用最簡潔明瞭的方式讓你們儘可能弄懂 SVG 濾鏡的使用方式。html

本文默認讀者已經掌握了必定 SVG 的基本概念和用法。git

SVG 濾鏡的種類

SVG 濾鏡包括了:github

feBlend
feColorMatrix
feComponentTransfer
feComposite
feConvolveMatrix
feDiffuseLighting
feDisplacementMap
feFlood
feGaussianBlur
feImage
feMerge
feMorphology
feOffset
feSpecularLighting
feTile
feTurbulence
feDistantLight
fePointLight
feSpotLight

看着內容不少,有點相似於 CSS 濾鏡中的不一樣功能:blur()、contrast()、drop-shadow() 。api

SVG 濾鏡的語法

咱們須要使用 <defs> 和 <filter> 標籤來定義一個 SVG 濾鏡。瀏覽器

一般全部的 SVG 濾鏡元素都須要定義在 <defs> 標記內。ide

如今,基本上現代瀏覽器,即便不使用 <defs> 包裹 <filter>,也可以定義一個 SVG 濾鏡。svg

這個 <defs> 標記是 definitions 這個單詞的縮寫,能夠包含不少種其它標籤,包括各類濾鏡。wordpress

其次,使用 <filter> 標記用來定義 SVG 濾鏡。 <filter> 標籤須要一個 id 屬性,它是這個濾鏡的標誌。SVG 圖形使用這個 id 來引用濾鏡。函數

看一個簡單的 DEMO:

<div class="cssFilter"></div>
<div class="svgFilter"></div>

<svg>
    <defs>
        <filter id="blur">
            <feGaussianBlur in="SourceGraphic" stdDeviation="5" />
        </filter>
    </defs>
</svg>
div {
    width: 100px;
    height: 100px;
    background: #000;
}
.cssblur {
    filter: blur(5px);
}
.svgFilter{
    filter: url(#blur);
}

這裏,咱們在 defs 的 filter 標籤內,運用了 SVG 的 feGaussianBlur 濾鏡,也就是模糊濾鏡, 該濾鏡有兩個屬性 in 和 stdDeviation。其中 in="SourceGraphic" 屬性指明瞭模糊效果要應用於整個圖片,stdDeviation 屬性定義了模糊的程度。最後,在 CSS 中,使用了 filter: url(#blur) 去調用 HTML 中定義的 id 爲 blur 的濾鏡。

爲了方便理解,也使用 CSS 濾鏡 filter: blur(5px) 實現了一個相似的濾鏡,方便比較,結果圖以下:

image

CodePen Demo - SVG 濾鏡

嘿,能夠看到,使用 SVG 的模糊濾鏡,實現了一個和 CSS 模糊濾鏡同樣的效果。

CSS filter 的 url 模式

上文的例子中使用了 filter: url(#blur) 這種模式引入了一個 SVG 濾鏡效果,url 是 CSS 濾鏡屬性的關鍵字之一,url 模式是 CSS 濾鏡提供的能力之一,容許咱們引入特定的 SVG 過濾器,這極大的加強 CSS 中濾鏡的能力。

至關於全部經過 SVG 實現的濾鏡效果,均可以快速的經過 CSS 濾鏡 URL 模式一鍵引入。

多個濾鏡搭配工做

和 CSS 濾鏡同樣,SVG 濾鏡也是支持多個濾鏡搭配混合使用的。

因此咱們常常能看到一個 <filter> 標籤內有大量的代碼。很容易就懵了~

再來看個簡單的例子:

<div></div>

<svg>
    <defs>
        <!-- Filter declaration -->
        <filter id="MyFilter">

            <!-- offsetBlur -->
            <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
            <feOffset in="blur" dx="10" dy="10" result="offsetBlur" />

            <!-- merge SourceGraphic + offsetBlur -->
            <feMerge>
                <feMergeNode in="offsetBlur" />
                <feMergeNode in="SourceGraphic" />
            </feMerge>
        </filter>
    </defs>
</svg>
div {
    width: 200px;
    height: 200px;
    background: url(xxx);
    filter: url(#MyFilter);
}

咱們先來看看整個濾鏡的最終結果,結果長這樣:

image

CSS 可能一行代碼就能實現的事情,SVG 竟然用了這麼多代碼。(固然,這裏 CSS 也很差實現,不是簡單容器的陰影,而是 PNG 圖片圖形的輪廓陰影)

分解步驟

首先看這一段:

<!-- offsetBlur -->
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
<feOffset in="blur" dx="10" dy="10" result="offsetBlur" />

首先 <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" /> 這一段,咱們上面也講到了,會生成一個模糊效果,這裏多了一個新的屬性 result='blur',這個就是 SVG 的一個特性,不一樣濾鏡做用的效果能夠經過 result 產出一箇中間結果(也稱爲 primitives 圖元),其餘濾鏡可使用 in 屬性導入不一樣濾鏡產出的 result,繼續操做。

緊接着,<feOffset> 濾鏡仍是很好理解的,使用 in 拿到了上一步的結果 result = 'blur',而後作了一個簡單的位移。

這裏就有一個很是重要的知識點:在不一樣濾鏡中利用 result 和 in 屬性,能夠實如今前一個基本變換操做上創建另外一個操做,好比咱們的例子中就是添加模糊後又添加位移效果。

結合兩個濾鏡,產生的圖形效果,實際上是這樣的:

image

實際效果中還出現了原圖,因此這裏咱們還使用了 <feMerge> 標籤,合併了多個效果。也就是上述這段代碼:

<!-- merge SourceGraphic + offsetBlur -->
<feMerge>
    <feMergeNode in="offsetBlur" />
    <feMergeNode in="SourceGraphic" />
</feMerge>

feMerge 濾鏡容許同時應用濾鏡效果而不是按順序應用濾鏡效果。利用 result 存儲別的濾鏡的輸出能夠實現這一點,而後在一個 <feMergeNode> 子元素中訪問它。

  • <feMergeNode in="offsetBlur" /> 表示了上述兩個濾鏡的最終輸出結果 offsetBlur ,也就是陰影的部分
  • <feMergeNode in="SourceGraphic" /> 中的 in="SourceGraphic" 關鍵詞表示圖形元素自身將做爲 <filter> 原語的原始輸入

總體再遵循後輸入的層級越高的原則,最終獲得上述結果。示意流程圖以下:

image

至此,基本就掌握了 SVG 濾鏡的工做原理,及多個濾鏡如何搭配使用。接下來,只須要搞懂不一樣的濾鏡能產生什麼樣的效果,有什麼不一樣的屬性,就能大體對 SVG 濾鏡有個基本的掌握!

關於 SVG 濾鏡還須要知道的

上面大體過了一下 SVG 濾鏡的使用流程,過程當中提到了一些屬性,可能也漏掉了一些屬性的講解,本章節將補充說明一下。

濾鏡標籤通用屬性

有一些屬性是每個濾鏡標籤都有,均可以進行設置的。

屬性 做用
x, y 提供左上角的座標來定義在哪裏渲染濾鏡效果。 (默認值:0)
width, height 繪製濾鏡容器框的高寬(默認都爲 100%)
result 用於定義一個濾鏡效果的輸出名字,以便將其用做另外一個濾鏡效果的輸入(in)
in 指定濾鏡效果的輸入源,能夠是某個濾鏡導出的 result,也能夠是下面 6 個值

in 屬性的 6 個取值

SVG filter 中的 in 屬性,指定濾鏡效果的輸入源,能夠是某個濾鏡導出的 result,也能夠是下面 6 個值:

in 取值 做用
SourceGraphic 該關鍵詞表示圖形元素自身將做爲 <filter> 原語的原始輸入
SourceAlpha 該關鍵詞表示圖形元素自身將做爲 <filter> 原語的原始輸入。SourceAlpha 與 SourceGraphic 具備相同的規則除了 SourceAlpha 只使用元素的非透明部分
BackgroundImage 與 SourceGraphic 相似,但可在背景上使用。 須要顯式設置
BackgroundAlpha 與 SourceAlpha 相似,但可在背景上使用。 須要顯式設置
FillPaint 將其放置在無限平面上同樣使用填充油漆
StrokePaint 將其放在無限平面上同樣使用描邊繪畫

後 4 個基本用不上~

後面 4 個不太經常使用。

更多 SVG 濾鏡介紹講解

上面已經提到了幾個濾鏡,咱們簡單回顧下:

  • <feGaussianBlur > - 模糊濾鏡
  • <feOffset > - 位移濾鏡
  • <feMerge> - 多濾鏡疊加濾鏡

接下來再介紹一些比較常見,有意思的 SVG 濾鏡。

feBlend 濾鏡

<feBlend> 爲混合模式濾鏡,與 CSS 中的混合模式相相似。

在 CSS 中,咱們有混合模式 mix-blend-mode 和 background-blend-mode 。我有過很是多篇關於 CSS 混合模式相關的一些應用。若是你還不太瞭解 CSS 中的混合模式,能夠先看看這幾篇文章:

SVG 中的混合模式種類比 CSS 中的要少一些,只有 5 個,其做用與 CSS 混合模式徹底一致:

  • normal — 正常
  • multiply — 正片疊底
  • screen — 濾色
  • darken — 變暗
  • lighten— 變亮

簡單一個 Demo,咱們有兩張圖,利用不一樣的混合模式,能夠獲得不同的混合結果 :

<div></div>

<svg>
    <defs>
        <filter id="lighten" x="0" y="0" width="200" height="250">
            <feImage width="200" height="250" xlink:href="image1.jpg" result="img1" />
            <feImage width="200" height="250" xlink:href="image2.jpg" result="img2" />
            <feBlend mode="lighten" in="img1" in2="img2"/>
        </filter>
    </defs>
</svg>
.container {
    width: 200px;
    height: 250px;
    filter: url(#lighten);
}

這裏還用到了一個 <feImage> 濾鏡,它的做用是提供像素數據做爲輸出,若是外部來源是一個 SVG 圖像,這個圖像將被柵格化。

image

上述運用了 feBlend 濾鏡中的 mode="lighten" 後的結果,兩個圖像疊加做用了 lighten 混合模式:

image

看看所有 5 中混合模式的效果:

image

CodePen Demo -- SVG Filter feBlend Demo

feColorMatrix

<feColorMatrix> 濾鏡也是 SVG 濾鏡中很是有意思的一個濾鏡,顧名思義,它的名字中包含了矩陣這個單詞,表示該濾鏡基於轉換矩陣對顏色進行變換。每一像素的顏色值(一個表示爲[紅,綠,藍,透明度] 的矢量) 都通過矩陣乘法 (matrix multiplated) 計算出的新顏色。

這個濾鏡稍微有點複雜,咱們一步一步來看。

<feColorMatrix> 濾鏡有 2 個私有屬性 type 和 values,type 它支持 4 種不一樣的類型:saturate | hueRotate | luminanceToAlpha | matrix,其中部分與 CSS Filter 中的一些濾鏡效果相似。

type 類型 做用 values 的取值範圍
saturate 轉換圖像飽和度 0.0 - 1.0
hueRotate 轉換圖像色相 0.0 - 360
luminanceToAlpha 阿爾法通道亮度(不知道如何翻譯 :sad) 只有一個效果,無需改變 values 的值
matrix 使用矩陣函數進行色彩變換 須要應用一個 4 x 5 的矩陣

在這裏,我作了一個簡單的關於 <feColorMatrix> 前 3 個屬性 saturate | hueRotate | luminanceToAlpha 的效果示意 DEMO -- CodePen - feColorMatrix Demo,能夠感覺下它們的具體的效果:

1gif

saturate、hueRotate 濾鏡和 CSS 中的 filter 中的 saturate、hue-rotate 的做用是如出一轍的。

feColorMatrix 中的 type=matrix

feColorMatrix 中的 type=matrix 理解起來要稍微更復雜點,它的 values 須要傳入一個 4x5 的矩陣。

像是這樣:

<filter id="colorMatrix">
  <feColorMatrix type="matrix" values="1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0"/>
</filter>

要理解如何運用這些填寫矩陣,就不得不直面另一個問題 -- 圖像的表示。

數字圖像的本質是一個多維矩陣。在圖像顯示時,咱們把圖像的 R 份量放進紅色通道里,B 份量放進藍色通道里,G 份量放進綠色通道里。通過一系列處理,顯示在屏幕上的就是咱們所看到的彩色圖像了。

而 feColorMatrix 中的 matrix 矩陣,就是用來表示不一樣通道的值每個份量的值,最終經過計算獲得咱們熟知的 rgba() 值。

計算邏輯爲:

/* R G B A 1 */ 
1 0 0 0 0 // R = 1*R + 0*G + 0*B + 0*A + 0 
0 1 0 0 0 // G = 0*R + 1*G + 0*B + 0*A + 0 
0 0 1 0 0 // B = 0*R + 0*G + 1*B + 0*A + 0 
0 0 0 1 0 // A = 0*R + 0*G + 0*B + 1*A + 0

中文的文章,對 feColorMatrix 的 matrix 講解最好的應該就是大漠老師的這篇 -- 詳解feColorMatrix,對具體的表示法感興趣的能夠看看。

僅僅是使用的話,這裏還有一個可視化的 DEMO -- CodePen - feColorMatrix Demo,幫助你們理解記憶:

2


到目前爲止,大部分 SVG 濾鏡的展現講解都是 CSS 現有能力可以實現的,那 SVG 濾鏡的獨特與魅力到底在哪呢?有什麼是 CSS 能力沒法作到的麼?下面來看看另外幾個有意思的 SVG 濾鏡。

feSpecularLighting/feDiffuseLighting 光照濾鏡

feSpecularLighting 與 feDiffuseLighting 都意爲光照濾鏡,使用它們能夠照亮一個源圖形,不一樣的是,feSpecularLighting 爲鏡面照明,而 feDiffuseLighting 爲散射光照明。

  • feDiffuseLighting:來自外部光源,適合模擬太陽光或者燈光照明
  • feSpecularLighting:指定從反射面反射的二次光

簡單看其中一個 Demo,代碼看着有點多,可是一步一步也很好理解:

<div></div>
<div class="svg-filter"></div>
<svg>
    <defs>
        <filter id="filter">
            <!--Lighting effect-->
            <feSpecularLighting in="SourceGraphic" specularExponent="20" specularConstant="0.75" result="spec">
              <fePointLight x="0" y="0" z="200" />
            </feSpecularLighting>
            <!--Composition of inputs-->
            <feComposite in="SourceGraphic" in2="spec" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" />
        </filter>
    </defs>
</svg>
div {
    background: url(avator.png);
}
.svg-filter {
    filter: url(#filter);
}

左邊是原圖,右邊是應用了光照濾鏡以後的效果。

image

CodePen - feSpotLight SVG Light Source

feMorphology 濾鏡

feMorphology 爲形態濾鏡,它的輸入源一般是圖形的 alpha 通道,用來它的兩個操做可使源圖形腐蝕(變薄)或擴張(加粗)。

使用屬性 operator 肯定是要腐蝕效果仍是擴張效果。使用屬性 radius 表示效果的程度,能夠理解爲筆觸的大小。

  • operator:erode 腐蝕模式,dilate 爲擴張模式,默認爲 erode
  • radius:筆觸的大小,接受一個數字,表示該模式下的效果程度,默認爲 0

咱們將這個濾鏡簡單的應用到文字上看看效果:

<div class="g-text">
    <p>Normal Text</p>
    <p class="dilate">Normal Text</p>
    <p class="erode">Normal Text</p>
</div>

<svg width="0" height="0">
    <filter id="dilate">
        <feMorphology in="SourceAlpha" result="DILATED" operator="dilate" radius="3"></feMorphology>
    </filter>
    <filter id="erode">
        <feMorphology in="SourceAlpha" result="ERODE" operator="erode" radius="1"></feMorphology>
    </filter>
</svg>
p {
    font-size: 64px;
}
.dilate {
    filter: url(#dilate);
}
.erode {
    filter: url(#erode);
}

效果以下:最左邊的是正常文字,中間的是擴張的模式,右邊的是腐蝕模式,看看效果,很是好理解:

image

固然,咱們還能夠將其運用在圖片之上,這時,並不是是簡單的讓圖像的筆觸變粗或者變細,

  • 對於 erode 模式,會將圖片的每個像素向更暗更透明的方向變化,
  • 而 dilate 模式,則是將每一個向像素周圍附近更亮更不透明的方向變化

簡單看個示例動畫 DEMO,咱們有兩張圖,分別做用 operator="erode" 和 operator="dilate",而且動態的去改變它們的 radius,其中一個的代碼示意以下:

<svg width="450" height="300" viewBox="0 0 450 300">
    <filter id="morphology">
        <feMorphology operator="erode" radius="0">
            <animate attributeName="radius" from="0" to="5" dur="5s" repeatCount="indefinite" />
        </feMorphology>
    </filter>

    <image xlink:href="image.jpg" width="90%" height="90%" x="10" y="10" filter="url(#morphology)"></image>
</svg>

3

上圖左邊是擴張模式,右邊是腐蝕模式:

CodePen Demo -- SVG feMorphology Animation

feTurbulence 濾鏡

turbulence 意爲湍流,不穩定氣流,而 SVG <feTurbulence> 濾鏡可以實現半透明的煙燻或波狀圖像。 一般用於實現一些特殊的紋理。濾鏡利用 Perlin 噪聲函數建立了一個圖像。噪聲在模擬雲霧效果時很是有用,能產生很是複雜的質感,利用它能夠實現了人造紋理好比說雲紋、大理石紋的合成。

有了 feTurbulence,咱們能夠自使用 SVG 建立紋理圖形做爲置換圖,而不須要藉助外部圖形的紋理效果,便可建立複雜的圖形效果。

這個濾鏡,我我的認爲是 SVG 濾鏡中最有意思的一個,由於它容許咱們本身去創造出一些紋理,而且疊加在其餘效果之上,生成出很是有意思的動效。

feTurbulence 有三個屬性是咱們特別須要注意的:type、baseFrequency、numOctaves:

  • type:實現的濾鏡的類型,可選fractalNoise 分形噪聲,或者是 turbulence 湍流噪聲。
    • fractalNoise:分形噪聲更加的平滑,它產生的噪聲質感更接近雲霧
    • turbulence:湍流噪聲
  • baseFrequency: 表示噪聲函數的基本頻率的參數,頻率越小,產生的圖形越大,頻率越大,產生的噪聲越複雜其圖形也越小越精細,一般的取值範圍在 0.02 ~ 0.2
  • numOctaves:表示噪聲函數的精細度,數值越高,產生的噪聲更詳細。 默認值爲1

這裏有一個很是好的網站,用於示意 feTurbulence 所產生的兩種噪聲的效果:http://apike.ca/ - feTurbulence

兩種噪聲的代碼基本一致,只是 type 類型不一樣:

<filter id="fractal" >
  <feTurbulence id="fe-turb-fractal" type="fractalNoise" baseFrequency="0.00025" numOctaves="1"/>
</filter>
<filter id="turbu">
  <feTurbulence id="fe-turb-turbulence" type="turbulence" baseFrequency="0.00025" numOctaves="1"/>
</filter>

咱們經過改變 baseFrequency 和 numOctaves 參數看看實際產生的兩種噪聲的效果:

同時,baseFrequency 容許咱們傳入兩個值,咱們能夠只改變某一方向上的頻率,具體的你能夠戳這個 Demo 看看:CodePen -- feTurbulence baseFrequency & numOctaves

單單一個 <feTurbulence> 濾鏡實際上是比較難搞懂這濾鏡想幹什麼的,須要將這個濾鏡做爲紋理或者輸入,和其餘濾鏡一塊兒搭配使用,實現一些效果,下面咱們來看看:

使用 feTurbulence 濾鏡實現文字流動的效果

首先,嘗試將 feTurbulence 所產生的紋理和文字相結合。

簡單的代碼以下:

<div>Coco</div>
<div class="turbulence">Coco</div>

<svg>
    <filter id="fractal" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
        <feTurbulence id="turbulence" type="fractalNoise" baseFrequency="0.03" numOctaves="1" />
        <feDisplacementMap in="SourceGraphic" scale="50"></feDisplacementMap>
    </filter>
</svg>
.turbulence {
    filter: url(#fractal);
}

左邊是正常的效果,後邊是應用了 <feTurbulence> 的效果,你能夠試着點進 Demo,更改 baseFrequency 和 numOctaves 參數的大小,能夠看到不一樣的效果:

image

CodePen Demo -- feTurbulence text demo

feDisplacementMap 映射置換濾鏡

上面的 Demo 還用到了 feDisplacementMap 濾鏡,也須要簡單的講解下。

feDisplacementMap 爲映射置換濾鏡,想要用好這個濾鏡不太容易,須要掌握很是多的關於 PhotoShop 紋理建立或者是圖形色彩相關的知識。該濾鏡用來自圖像中從 in2 的輸入值到空間的像素值置換圖像從 in 輸入值到空間的像素值。

說人話就是 feDisplacementMap 其實是用於改變元素和圖形的像素位置的。該濾鏡經過遍歷原圖形的全部像素點,使用 feDisplacementMap 從新映射到一個新的位置,造成一個新的圖形。

在上述的 feTurbulence 濾鏡與文字的結合使用中,咱們經過 feTurbulence 噪聲獲得了噪聲圖形,而後經過 feDisplacementMap 濾鏡根據 feTurbulence 所產生的噪聲圖形進行形變,扭曲,液化,獲得最終的效果。

MDN 上有這個濾鏡轉化的一個公式(感興趣的能夠研究下,我啃不動了):

P'(x,y) ← P( x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5))

使用 feTurbulence 濾鏡實現褶皺紙張的紋理

好,咱們繼續 feTurbulence ,使用這個濾鏡,咱們能夠生成各類不一樣的紋理,咱們能夠嘗試使用 feTurbulence 濾鏡搭配光照濾鏡實現褶皺的紙張紋理效果,代碼也很是少:

<div></div>
<svg>
    <filter id='roughpaper'>
        <feTurbulence type="fractalNoise" baseFrequency='0.04' result='noise' numOctaves="5" />

        <feDiffuseLighting in='noise' lighting-color='#fff' surfaceScale='2'>
            <feDistantLight azimuth='45' elevation='60' />
        </feDiffuseLighting>
    </filter>
</svg>
div {
    width: 650px;
    height: 500px;
    filter: url(#roughpaper);
}

效果以下:

image

CodePen Demo -- Rough Paper Texture with SVG Filters

你能夠在 Sara Soueidan 的一次關於 SVG Filter 的分享上,找到製做它的教程:Youtube -- SVG Filters Crash Course

使用 feTurbulence 濾鏡實現按鈕hover效果

使用 feTurbulence 濾鏡搭配 feDisplacementMap 濾鏡,還能夠製做一些很是有意思的按鈕效果。

嘗試實現一些故障風格的按鈕,其中一個按鈕的代碼以下:

<div class="fe1">Button</div>
<div class="fe2">Button</div>

<svg>
    <defs>
        <filter id="fe1">
            <feTurbulence id="animation" type="fractalNoise" baseFrequency="0.00001 9.9999999" numOctaves="1" result="warp">
                <animate attributeName="baseFrequency" from="0.00001 9.9999" to="0.00001 0.001" dur="2s" repeatCount="indefinite"/>
            </feTurbulence>
            <feOffset dx="-90" dy="-90" result="warpOffset"></feOffset>
            <feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="30" in="SourceGraphic" in2="warpOffset"></feDisplacementMap>
        </filter>
    </defs>
</svg>
.fe1 {
    width: 200px;
    height: 64px;
    outline: 200px solid transparent;
}

.fe1:hover {
    filter: url(#fe1);
}

經過 hover 按鈕的時候,給按鈕添加濾鏡效果,而且濾鏡自己帶有一個無限循環的動畫:

完整的代碼你能夠戳這裏:CodePen Demo - SVG Filter Button Effects

使用 feTurbulence 濾鏡實現雲彩效果

最後,咱們回到題圖上的雲彩效果,使用 feTurbulence 濾鏡,咱們能夠很是逼真的使用 SVG 模擬出真實的雲彩效果。

首先,經過隨機生成的多重 box-shadow,實現這一一個圖形:

<div></div>
div {
    width: 1px;
    height: 1px;
    box-shadow: rgb(240 255 243) 80vw 11vh 34vmin 16vmin, rgb(17 203 215) 33vw 71vh 23vmin 1vmin, rgb(250 70 89) 4vw 85vh 21vmin 9vmin, rgb(198 241 231) 8vw 4vh 22vmin 12vmin, rgb(198 241 231) 89vw 11vh 31vmin 19vmin, rgb(240 255 243) 5vw 22vh 38vmin 19vmin, rgb(250 70 89) 97vw 35vh 33vmin 16vmin, rgb(250 70 89) 51vw 8vh 35vmin 14vmin, rgb(17 203 215) 75vw 57vh 40vmin 4vmin, rgb(250 70 89) 28vw 18vh 31vmin 11vmin, rgb(250 70 89) 8vw 89vh 31vmin 2vmin, rgb(17 203 215) 13vw 8vh 26vmin 19vmin, rgb(240 255 243) 98vw 12vh 35vmin 5vmin, rgb(17 203 215) 35vw 29vh 27vmin 18vmin, rgb(17 203 215) 67vw 58vh 22vmin 15vmin, rgb(198 241 231) 67vw 24vh 25vmin 7vmin, rgb(17 203 215) 76vw 52vh 22vmin 7vmin, rgb(250 70 89) 46vw 86vh 26vmin 20vmin, rgb(240 255 243) 50vw 20vh 25vmin 1vmin, rgb(250 70 89) 74vw 14vh 25vmin 16vmin, rgb(240 255 243) 31vw 100vh 29vmin 20vmin
}

這個工做,你能夠交給 SASS、LESS 或者 JavaScript 這些可以有循環函數能力的語言去生成,它的效果大概是這樣:

image

緊接着,經過 feTurbulence 產生分形噪聲圖形,使用 feDisplacementMap 進行映射置換,最後給圖形疊加上這個濾鏡效果。

<svg width="0">
  <filter id="filter">
    <feTurbulence type="fractalNoise" baseFrequency=".01" numOctaves="10" />
    <feDisplacementMap in="SourceGraphic" scale="240" />
  </filter>
</svg>
div {
    filter: url(#filter);
}

便可獲得這樣的雲彩效果:

image

完整的代碼,你能夠戳這裏到袁川老師的 CodePen 觀看:Cloud (SVG filter + CSS)

總結一下

關於 SVG 濾鏡入門的第一篇總算差很少了,本文簡單的介紹了一下 SVG 濾鏡的使用方式以及一些常見的 SVG 濾鏡並給出了最簡單的一些使用效果,但願你們看完能對 SVG 濾鏡有一個簡單的認識。

本文羅列的濾鏡效果更多的是單個效果或者不多幾個組合在一塊兒的效果,實際的使用或者應用到應用場景下其實會是更多濾鏡的的組合產生出的一個效果。

後面的文章將會更加細緻的去探討分析多個 SVG 濾鏡組合效果,探討更復雜的排列組合。

文章的題目叫SVG 濾鏡從入門到放棄由於 SVG 濾鏡學起來確實太繁瑣太累了,它不像 CSS 濾鏡或者混合模式那麼容易上手那麼簡單。固然也因爲 SVG 濾鏡的功能很是強大,定製化能力強以及它已經存在了很是之久有關。SVG 濾鏡的兼容性也很好,它們實際上是早於 CSS3 一些特殊效果以前就已經存在的。

CSS 其實一直在向 SVG 的一些特殊能力靠攏,用更簡單的語法讓人更易上手,不過 SVG 濾鏡仍是有其獨特的魅力所在。後續將會有更多關於 SVG 濾鏡的文章。也但願讀到這裏的同窗不要放棄!

參考資料

最後

好了,本文到此結束,但願對你有幫助 ????

更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。

若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。

相關文章
相關標籤/搜索