前言css
這個東西呢無論看起來,聽起來都很高大上哈.鄙人比較懶,知道有這麼個東西,卻一直沒去研究.感嘆技術突飛猛進,有時候以爲本身掉隊好遠了.這不項目中便遇到了使用這傢伙的狀況.此次須要作一個音樂類app,須要有毛玻璃的高大上效果.這個效果在衆多音樂app中很是常見,也確實很是漂亮.但在網頁端見得比較少.大概是兼容性和性能問題吧(強烈吐槽性能).也沒辦法,有需求就得想辦法去實現是否是,不過最討厭跟那羣UE,PM撕逼.若是對她們說這個東西很麻煩,很差實現.而後她們一副哥哥你必定能夠的!!花癡表情強行綁架了我.哎,誰讓我是程序員呢. 其實吧我本身也挺想去實現這個東西的。默默的給本身打了一針雞血便投入無盡的搜尋,學習中.html
css3-filterios
搜索一番,找到這個屬性filter:blur(5px)。趕快去實現一把。css3
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="content-type" content="text/html; charset=utf-8"> 5 <title></title> 6 <style> 7 .d1{ 8 background-image:url('./lp.png'); 9 background-size:cover; 10 -webkit-filter:blur(10px); 11 filter:blur(10px); 12 width:300px; 13 height:300px; 14 } 15 </style> 16 </head> 17 <body> 18 19 <div class="d1"></div> 20 </body> 21 </html>
咳咳, 獻上一個萌妹子.實在找不到圖片了.O(∩_∩)O哈哈~程序員
blur的效果就是虛化圖片.值越大虛化得越厲害.web
瞬間高大上了有木有!! 算法
....canvas
....app
....ide
然而事情並無這麼簡單.濾鏡算法是對圖片的像素點作處理,也就是說你須要設置一張背景圖.當前元素設置濾鏡屬性後,元素裏面的內容也會被影響.就拿上面的例子來講,若是元素裏面有文字的話,那麼文字也看不見了.聰明的你確定會想到再疊一層不就完了嘛.事實狀況也確實如此(這不是廢話麼...)讓咱們來看下
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title></title> <style> .wrap{ position:relative; width:300px; height:300px; line-height:300px; text-align:center; } .d1{ background-image:url('./lp.png'); background-size:cover; -webkit-filter:blur(10px); filter:blur(10px); position: absolute; top:0; left:0; width:100%; height:100%; z-index:-1; } </style> </head> <body> <div class="wrap"> <div class="d1"></div> <div class="content">我愛你老婆</div> </div> </body> </html>
完美!
.....
.....
.....
然而事情並無這麼簡單!
歌詞可能是用白色字體,毛玻璃仍是太亮了,容易混淆. 嘿嘿,其實也簡單,再加上一點背景透明度就好啦.
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title></title> <style> .wrap{ position:relative; width:300px; height:300px; } .d1{ background-image:url('./lp.png'); background-size:cover; -webkit-filter:blur(10px); filter:blur(10px); position: absolute; top:0; left:0; width:100%; height:100%; z-index:-1; } .content{ width:100%; height:100%; line-height:300px; color:#fff; text-align:center; background-color:rgba(0,0,0,0.3); } </style> </head> <body> <div class="wrap"> <div class="d1"></div> <div class="content">我愛你老婆</div> </div> </body> </html>
看這下是否是好多啦. 恩比較有玻璃質感了.其實吧,還有個坑爹的問題, 加了濾鏡blur的元素就變成透明的了,雖然有背景圖也仍是透明的.因此在須要毛玻璃覆蓋底層的狀況下,得再疊一層,添加一個背景色.
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title></title> <style> .wrap{ position:relative; width:300px; height:300px; } .filter{ background-image:url('./lp.png'); background-size:cover; -webkit-filter:blur(10px); filter:blur(10px); position: absolute; top:0; left:0; width:100%; height:100%; z-index:-1; } .filter-bg{ position:absolute; top:0; left:0; width:100%; height:100%; background-color:#333; z-index:-2; } .content{ width:100%; height:100%; line-height:300px; color:#fff; text-align:center; background-color:rgba(0,0,0,0.3); } </style> </head> <body> <div class="wrap"> <div class="filter-bg"></div> <div class="filter"></div> <div class="content">我愛你老婆</div> </div> </body> </html>
我們能夠隱約的發現,在圖片的四周模糊效果不是很好,這種狀況在blur的值越大的時候越明顯,趨勢是模糊區域向圖像中顏色明顯的地方靠近,邊緣地方就顯得透明,甚至貌似沒有模糊.建議blur的值設置在30如下.
彷佛問題就這麼解決了!!
真的解決了?!
真的?
svg-<filter>
我興奮的,天真的覺得事情就這麼完了,然而當我附上動畫後,讓毛玻璃動起來時,整我的都崩潰了. fuck! 哥纔買的6s玫瑰金,卡得跟屎同樣.固然補充下前提條件,是在播放音樂的時候拖動頁面,頁面元素數量通常.但不至於播放個音樂拖垮了整個頁面性能吧.二愣子的我拖着電腦就去找pm了,你看,就是你要作這種效果,卡得跟方便麪同樣一條一條的.搞不定,砍需求!
pm礙於我憤怒的表情,打起了太極.你先冷靜冷靜.什麼事兒都好商量.你要不喝點兒飲料?
我固然接受了(大家不要用異樣的眼光看着我). 喝着飲料平靜了下心情,這事兒吧總得解決.和pm鬼扯了半天仍是以爲要保留這個效果,否則作了那麼久就白費了.何況一個好的工程師(注意我沒有用程序員!)就得迎難而上啊,創造力和解決問題的能力纔是工程師們的價值所在.首先仍是得定位問題,爲了肯定是filter屬性的鍋,我把濾鏡層給刪掉,臥槽絲滑般流暢.看來這屬性真是性能堪憂啊.那怎麼辦呢,我最終仍是抱向了google的大腿.一番搜索,果真不負衆望.原來除了css3以外,svg和canvas也是能夠實現濾鏡效果的.我試了下svg,效果然是好得出奇.很流暢.將咱們剛纔的filter層替換爲svg實現
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" baseProfile="full"> <defs> <filter id="blur"> <feGaussianBlur stdDeviation="10" /> </filter> </defs> <image xlink:href="./mm.jpg" x="0" y="0" height="200" width="200" filter="url(#blur)"/> </svg>
<filter>標籤用來描述濾鏡,其id屬性惟一標識一個濾鏡.<filter>標籤必須寫在<defs>標籤內.<defs>標籤是對特殊效果進行描述.
最終效果不卡.我猜想應該是實現機制不一樣,svg添加上濾鏡後就會把它當成一個圖片來處理,不會重複消耗cpu計算.而css3的filter屬性應該是在滾動的時候會動態計算,在作一些比較複雜的效果時候,卡頓就很明顯.
使用svg的濾鏡依然會使得svg層變得透明,在不但願透明的時候記得添加一層背景色.
canvas
用svg的時候遇到一個詭異的問題, 在手機上.把濾鏡層隱藏,或者visibility:hidden, 切換的時候,濾鏡不見了,圖片還在.可是沒有了模糊效果.懷疑是性能問題,不能及時重繪渲染.或者svg的濾鏡只渲染一次.因此考慮用canvas來作高斯模糊.由於canvas渲染完畢後就是一張圖片.不會再發生改變.
2016年04月24日補充: 後來無心中發現使用了
高斯算法參考 高斯算法原理
找到一個高斯算法庫,stackBlur.js . 裏面有一行註釋,須要關注下,是關於getImageDate.獲取本地圖片的,須要刪掉try,catch那段代碼.這裏又遇到一個問題.canvas的getImageDate有同源策略,只能操做同域的圖片資源.
處理庫API: stackBlurImage( sourceImageID, targetCanvasID, radius, blurAlphaChannel );
sourceImageID
表示要模糊的圖片的id
, 默認這個圖片要隱藏;
targetCanvasID
表示要顯示模糊圖片的canvas
元素的id
;
radius
表示模糊的半徑大小。不過,根據個人對比測試,radius
好像與CSS中filter濾鏡的模糊值不是1:1
匹配的,反卻是有些相似2:1
. 也就是這裏的20px
的半徑模糊近似於CSS中blur
濾鏡值設置爲10px
;
blurAlphaChannel
爲布爾屬性,表示aplha
透明通道是否要模糊,true
表示要模糊。
兼容性對比
我們再來對比一下兼容性,可見svg稍好,在安卓上都是4.4才支持.另外一方面,在移動端,毛玻璃效果在ios上是沒問題的. 但有至關一部分安卓不支持.
其餘濾鏡效果沒用過,彷佛也不太經常使用,也很少說了,網上都能查到.
總結
參考資料: