來寫個有煙霧特效的網頁吧
利用 css 結合 <video /> 產生動態煙霧特效
最近在寫 JS地下城
第 14 關, 題目的要求是寫一個線上求籤 (占卜) 的網頁。在看完 UI 設計稿提供的背景圖後,我覺得加個煙霧特效應該還不錯,會有廟宇的香正在燃燒的錯覺。
但是在測試過一些產生煙霧的 JS library 後,總覺得效果都不太自然,或者說需要開發者自己去設計出自然的感覺。後來偶然看到這個教學影片,才發現一個比較簡單的做法: 先找個有煙霧特效的影片,再利用 css 的 opacity
或 mix-blend-mode
屬性讓影片與背景的圖層融合在一起,就可以在背景上產生自然的煙霧特效,效果可以參考最後的 成品。
什麼是 mix-blend-mode
mix-blend-mode
是一個比較少見的 css 屬性,它可以讓某個 DOM 元素的圖層與下層 DOM 元素的圖層混合在一起。
舉例來說,我們先在圖片上放一段文字:
如果在文字上加上 css 屬性: mix-blend-mode: exclusion
,就會讓背景的圖層與文字混合:
mix-blend-mode
混合圖層的模式目前有 16 種,詳細的參數與效果可以參考這個網站。
將 mix-blend-mode 與 <video /> 整合
有了上面的基礎,就可以開始嘗試與 <video />
整合了。
首先先寫個 .bg
包住影片與背景圖,並且讓影片放在背景圖之下:
出來的結果會長這樣:
因為背景圖完全擋住了影片,所以目前只看到圖片是正常的。
接下來,我們就對背景圖補上 mix-blend-mode
屬性,就可以讓背景圖與底下的影片檔的圖層混合在一起:
接者繼續調整其他細節。在 .bg-video
上補上 opacity: 0.7
讓影片的圖層顯示淡一點,然後設定 <video />
屬性讓影片可以自動播放並無限循環:
修改的效果就會長這樣:
<video /> 的解析度問題
到目前為止都跟預想的差不多,唯一的問題就是無論怎麼調整 <video />
的大小,影像都會維持原始解析度的長寬比。因此如果背景的長寬比與影像的長寬比不同,就會有部分位置沒有煙霧特效。
一個簡單的解決方法,就是故意拉大影像再用外層容器的 css 屬性 overflow: hidden
把超出的部分隱藏起來:
為了方便說明,上面的範例還沒加上 overflow: hidden
。這個做法還可以再優化,比如說把影像調整到置中位置、每當視窗 resize 的時候都重新比較 <video />
與背景的長寬比再決定要拉大影像的哪個維度。
如果不能接受部分影像被裁切,另一種做法是把影像繪製到 <canvas />
上,再把 <canvas />
延展到與背景相同大小。修改 html 如下:
然後修改 css 把 <video />
隱藏起來,並且把 canvas 放到圖片下方:
最後再加上繪製影片到 canvas 的程式碼:
這樣就完成了 🎉
結語
最後在結束前再聊一下瀏覽器兼容的問題吧。
mix-blend-mode
在 IE 或 Edge 上都不支援,如果需要兼容這些瀏覽器可以考慮只用 opacity
來疊加影片與背景圖片,當然這樣可以玩的特效就會少很多。
另外部分瀏覽器並不允許載入網頁後自動播放影片,如果一樣需要兼容….那這篇介紹的方法可能就不太適合 😅。
以上,如果有任何問題都歡迎討論喔~