上次和大家一起,用最簡單直白,輕松粗暴的方式學習了一遍SVG動畫,這次我們再一起來搞點不一樣的東西,SVG濾鏡的實現。
SVG濾鏡絕對稱得上是他最強大的功能之一,在不影響任何文檔結構的前提下,允許你給你的矢量圖形添加各種專業視覺效果,我個人給他的定義就是,把PS裝到了網頁上。
基本原理描述太多明顯有違我們 “輕松打開” 的目的,這里簡單的描述一下,SVG在使用了濾鏡的元素里,不會將原始圖形直接渲染出來,而是會將原始圖形的像素信息渲染到臨時位圖中,然后由 filter元素指定的操作會被應用到這個臨時位圖,最終把計算結果渲染為最終圖形輸出。
舉個例子,我們用騰訊云的CVM圖標來做一個最簡單,最常見的濾鏡效果——投影。
首先我把圖標畫出來,
然后放到一個defs里,沒有被引用之前你肯定是什么都看不到的。
接著寫filter,嘗試使用feGaussianBlur給logo生成陰影效果
用stdDeviation 來指定模糊程度,值越大,模糊效果越強,并且可以接受兩個數字,分別為X Y方向的模糊度。 然后指定SourceAlpha為他的輸入源,如果不指定將在原色值上做模糊。
現在我們看一下效果截圖,好像有哪里不對勁?
這是什么黑乎乎的一坨?原因是濾鏡返回的是一個模糊過的阿爾法通道,并不是原始圖形。
(另外當我們在瀏覽器里查看的時候,可以明顯的看到濾鏡對象的邊界明顯不同于原始對象的邊界,他的默認值為 X等于-10%,Y等于-10%,寬 120%,高120%。這樣其實是為濾鏡提供了額外的空間,產生的輸出大于輸入區域。)
那么現在我們改進一下寫法
result屬性指定當前的輸出結果,你可以在當前的filter里邊通過in調用,而且只能在當前的filter里調用,相當于輸出一個局部變量。
改進后的代碼,就是通過feMerge把輸出的阿爾法通道和原始圖形堆疊,來產生投影效果。具體的模糊度可以在stdDeviation里設置,具體的投影位置可以通過offset調整。
現在我們看一下最終的投影效果
這個實現思路是不是很眼熟?不負責任的說,CSS3的box-shadow,雖然實現有區別,但是原理和這里是一模一樣的。
現在,你就可以在任何圖形上調用這個投影的濾鏡了。
上面我通過一個黑色投影的例子簡單的說了一下SVG濾鏡的原理,但是那個黑色的投影實在太單調了啊。能不能再給投影來點顏色?
這時候另一個強大的元素 feColorMatrix 就可以出場了。
我們把上邊的投影稍微修改一下
feColorMatrix 允許我們修改任意像素點的顏色或阿爾法值,當type= matrix的時候,value 為20個數字信息,把這些數字信息按照4行5列來組合,從上到下每一行代表一個方程式,數字分別乘以RGBA和常量1,代表如何計算 R G B A,如圖
我們這里簡化一下,將所有不透明區域設置為相同,可以忽略輸入顏色和常量,只設置透明度的值
這個矩陣模型最終計算結果是 red(R)0,green(G)0.9,blue(B)0.9,alpha(A)1,生成一個明亮的青色。
然后我們調整了dx和dy,讓他從投影變成了發光。
如果要不同顏色,我們只需要調整這里的RGBA值。
feColorMatrix 的type值還有hueRotate(色相旋轉),saturate(飽和度)等,在此不一一列舉,詳細的用法下一次單獨講一下。
到目前為止我們只是把一個路徑作為濾鏡的輸入源,SVG的 feImage 元素允許我們使用JPG PNG以及其他SVG文件,現在我們給logo加個背景
背景加進來之后,先把圖標拿掉,我們用一個新的元素來處理一下——feComponentTransfer
可以在feComponentTransfer 里調整 feFuncR feFuncG feFuncB feFuncA,每個子元素都可以單獨指定一個type屬性,slope是個比例因子,intercept是基準值,具體的計算方式這里不詳細講解,畢竟是輕松打開系列,后面單獨談那些內容吧。
然后我們改變三個通道的值來看看效果
feFunc的type屬性還有另外的幾個值,gamma,table等等,用法上大同小異,不同的是參數和算法,這里就不一一列舉。
然后我們回到上面的logo,現在都是針對一個輸入源在操作,下面我們同時操作兩個源。
feComposite元素接受兩個源,分別指定在in和in2屬性中,他的operator屬性的值來決定如何合并兩個源。
常用的值有
over 生成的結果就是a層疊在b上面,和我們上面用的mergenode效果是一樣的
in 典型的蒙版效果
out 反轉蒙版的效果
atop a的一部分在b里面,b的一部分在a外面
xor 包含b的外面的a的部分和a的外面的b的部分
arithmetic 最靈活的一個值,可以提供4個參數,k1 k2 k3 k4,每個像素的每個通道結果按照這個方式計算: k1*a*b + k2*a +k3*b +k4
現在我們拿最常用的蒙版效果來舉例用法:
效果如下圖,其他的值推薦大家自己去嘗試一下
svg瘦身效果
feMorphology可以通過erode與dilate的值來對我們的SVG圖像進行瘦身和加厚,效果如下
demo8
不過效果里可以清晰的看出,對線條進行瘦身效果會造成嚴重破壞。
svg浮雕效果
feConvolveMatrix元素允許我們按照他臨近的像素計算像素新值,于是這個濾鏡就可以生成 模糊,銳化,浮雕這些效果。他的原理就是合并像素和他臨近的像素,生成結果像素。
filter元素包含一系列濾鏡基元,每個都接受一個或者多個輸入,同時提供唯一的結果供其他基元使用,這就是SVG濾鏡工作的方式。篇幅有限,并沒有把SVG濾鏡的知識全部詳細的介紹,后面會另外單獨介紹一些知識點。
使用svg必然要因為兼容性等因素考慮好fallbacks,常用的有幾種方式:
1.通過alt或者文本標簽的方式做提示
2.通過判斷或者查詢顯示一張圖片
通常都不會選擇第一種。
第二種,也有多種方案,下面我們列舉幾個:
1.html的source標簽屬性 type=”image/svg+xml” 方式,在支持的瀏覽器里使用SVG,在不支持的瀏覽器里顯示PNG,優點是type靈活,可用于SVG,WEBP等,而且保持了img標簽的特性,方便做布局操作。缺點兼容性要求高,ios9+,安卓5+,微軟Edge+
2.srcset=”svg.svg 2X” 方式,在2倍屏顯示SVG,在其他顯示PNG,缺點同上
3.svg標簽方式,缺點必須指定寬高,沒有圖片的保持寬高比例特性,優點兼容性好,兼容所有主流瀏覽器