最近在試著實作 gooey 效果,看了一些介紹後知道了 gooey 的原理,本以為在實作上可以一路順風,但果然沒有這麼簡單,還好最後有找到解決方法。
先來談談 gooey 的作法,首先要先有兩層 layer,內層將物件模糊 blur,而外層處理亮度 brightness 跟對比度 contrast,接著神奇的事情就會發生了,可以參考以下範例:
See the Pen Blur vs Contrast by Chris Coyier (@chriscoyier) on CodePen.
上層是只加了模糊,可以看到因為模糊的關係,物件間的顏色互相疊加在一起;下層則是調整對比後的結果,將模糊過的結果保留重疊及原本顏色較深的部分,濾掉顏色較淺的部分,物件間的部分就因此連起來了,若是加上動畫,效果就會更好:
See the Pen Gooey Pagination by Lucas Bebber (@lbebber) on CodePen.
這樣看似已經完成了,但實際上會遇到兩個問題:
- 內部物件模糊掉,使用了
filter: blur();
後,子元素無一倖免。 - 更改顏色,所有更改顏色都會因對比而偏移掉。
原本就是卡在這裡,不管怎麼調整都沒辦法有效的解決這兩項,後來看到了 Creative Gooey Effects 這篇才知道可以利用 fliter: url();
配合 SVG filters 來解決這兩個問題,且用法也很簡單。此方法在 The Gooey Effect 中描述的更加清楚,包含在 feColorMatrix
中的 values 為什麼是下表也有描述,若是對他的敘述不清楚的話可以先看 SVG 研究之路 (11) - filter:feColorMatrix 稍微釐清一下。
簡單來說,若是沒有特別需求,就去調整 color matrix 中的 alpha channel (A) 跟 plus(+) 中值來得到自己想要的結果。
* | R | G | B | A | + |
---|---|---|---|---|---|
R | 1 | 0 | 0 | 0 | 0 |
G | 0 | 1 | 0 | 0 | 0 |
B | 0 | 0 | 1 | 0 | 0 |
A | 0 | 0 | 0 | 18 | -7 |
以下是我在測試時寫的比較:
- 用純 CSS 處理,背景與下一項的顏色設定相同,但呈現出
#0000FF
的藍色。See the Pen Rotate loading (bad with and text) by North (@ssk7833) on CodePen.
- 用 SVG 處理,上一版的改良,在元素中放文字將會正常顯示。
See the Pen Gooey rotate loading (good with background and text) by North (@ssk7833) on CodePen.
- 將第二版的顏色稍加調整,移除
feBlend
後由於失去SourceGraphic
的關係,文字將不會正常顯示,但此效果我更喜歡。See the Pen Gooey rotate loading (good with only background) by North (@ssk7833) on CodePen.
在寫上述三項測試時,自己也試過許多不同的組合,對 SVG filters 也多了許多理解,而在 gooey 相關的效果基本上就是 feGaussianBlur
、feColorMatrix
和 feBlend
的變化所組成,未來若遇到類似需求時應該都能迎刃而解~
參考資料: