您現在的位置是:首頁 > 網頁遊戲首頁網頁遊戲

CSS mask 實現滑鼠跟隨鏤空效果

簡介wrap::before{left: calc(var(——x) * 100%)

zbrush怎麼讓物體居中

前言

偶然在某思看到這樣一個問題,如何使一個div的部分割槽域變透明而其他部分模糊掉?,最後實現效果是這樣的

CSS mask 實現滑鼠跟隨鏤空效果

進一步,還能實現任意形狀的鏤空效果

CSS mask 實現滑鼠跟隨鏤空效果

滑鼠經過的地方清晰可見,其他地方則是模糊的。

可能一開始無從下手,不要急,可以先從簡單的、類似的效果開始,一步一步嘗試,一起看看吧。

一、普通半透明的效果

比如平時開發中碰到更多的可能是一個半透明的效果,有點類似於探照燈(滑鼠外面的地方是半透明遮罩,看起來會暗一點)。如下:

CSS mask 實現滑鼠跟隨鏤空效果

那先從這種效果開始吧,假設有這樣一個佈局:

CSS mask 實現滑鼠跟隨鏤空效果
複製程式碼

那麼如何繪製一個鏤空的圓呢?先介紹一種方法

其實很簡單,只需要一個足夠大的投影就可以了,原理如下

CSS mask 實現滑鼠跟隨鏤空效果

這裡可以用偽元素::before來繪製,結構更加精簡。用程式碼實現就是

。wrap::before{ content:‘’; position: absolute; width: 100px; height: 100px; border-radius: 50%; left: 50%; top: 50%; transform: translate(-50%,-50%); /*預設居中*/ box-shadow: 0 0 0 999vw rgba(0, 0, 0, 。5); /*足夠大的投影*/}複製程式碼

可以得到這樣的效果

CSS mask 實現滑鼠跟隨鏤空效果

二、藉助 CSS 變數傳遞滑鼠位置

按照以往的經驗,可能會在 js 中直接修改元素的 style 屬性,類似這樣

img。addEventListener(‘mousemove’, (ev) => { img。style。left = ‘。。。’; img。style。top = ‘。。。’;})複製程式碼

但是這樣互動與業務邏輯混雜在一起,不利於後期維護。其實,我們只需要滑鼠的座標,在 CSS 中也能完全實現跟隨的效果。

這裡藉助 CSS 變數,那一切就好辦了!假設滑鼠的座標是 [——x,——y](範圍是[0, 1]),那麼遮罩的座標就可以使用 calc計算了

。wrap::before{ left: calc(var(——x) * 100%); top: calc(var(——y) * 100%);}複製程式碼

然後滑鼠座標的獲取可以使用 JS 來計算,也比較容易,如下

img。addEventListener(‘mousemove’, (ev) => { img。style。setProperty(‘——x’, ev。offsetX / ev。target。offsetWidth); img。style。setProperty(‘——y’, ev。offsetY / ev。target。offsetHeight);})複製程式碼

這樣,半透明效果的鏤空效果就完成了

CSS mask 實現滑鼠跟隨鏤空效果

完整程式碼可以訪問: backdrop-shadow (codepen。io)

三、漸變也能實現半透明的效果

除了上述陰影擴充套件的方式,

CSS 徑向漸變

也能實現這樣的效果

繪製一個從透明到半透明的漸變,如下

。wrap::before{ content: ‘’; position: absolute; width: 100%; height: 100%; left: 0; top: 0; background: radial-gradient( circle at center, transparent 50px, rgba(0,0,0,。5) 51px);}複製程式碼

可以得到這樣的效果

CSS mask 實現滑鼠跟隨鏤空效果

然後,把滑鼠座標對映上去就可以了。從這裡就可以看出 CSS 變數的好處,無需修改 JS,只需要在CSS中

修改漸變中心點

的位置就可以實現了

。wrap::before{ background: radial-gradient( circle at calc(var(——x) * 100% ) calc(var(——y) * 100% ), transparent 50px, rgba(0,0,0,。5) 51px);}複製程式碼

CSS mask 實現滑鼠跟隨鏤空效果

四、背景模糊的效果嘗試

CSS 中有一個專門針對背景(元素後面區域)的屬性:backdrop-filter。使用方式和 filter完全一致!

backdrop-filter: blur(10px);複製程式碼

下面是 MDN 中的一個示意效果

CSS mask 實現滑鼠跟隨鏤空效果

backdrop-filter是讓當前

元素所在區域後面的內容

模糊,要想看到效果,需要元素本身半透明或者完全透明;而filter是讓當前

元素自身

模糊。有興趣的可以檢視這篇文章: CSS backdrop-filter簡介與蘋果iOS毛玻璃效果 « 張鑫旭-鑫空間-鑫生活 (zhangxinxu。com)

需要注意的是,這種

模糊與背景的半透明度沒有任何關係

,哪怕元素本身是透明的,仍然會有效果。例如下面是去除背景後的效果 ,整塊都是模糊的

CSS mask 實現滑鼠跟隨鏤空效果

如果直接運用到上面的例子會怎麼樣呢?

1。 陰影實現

在上面第一個例子中新增 backdrop-filter

。wrap::before{ content:‘’; position: absolute; width: 100px; height: 100px; border-radius: 50%; left: 50%; top: 50%; transform: translate(-50%,-50%); /*預設居中*/ box-shadow: 0 0 0 999vw rgba(0, 0, 0, 。5); /*足夠大的投影*/ backdrop-filter: blur(5px)}複製程式碼

得到效果如下

CSS mask 實現滑鼠跟隨鏤空效果

可以看到圓形區域是模糊的,正好和希望的效果相反。其實也好理解,只有圓形區域才是真實的結構,外面都是陰影,所以最後作用的範圍也只有圓形部分

2。 漸變實現

現在在第二個例子中新增 backdrop-filter

。wrap::before{ content: ‘’; position: absolute; width: 100%; height: 100%; left: 0; top: 0; background: radial-gradient( circle at calc(var(——x) * 100% ) calc(var(——y) * 100% ), transparent 50px, rgba(0,0,0,。5) 51px); backdrop-filter: blur(5px)}複製程式碼

效果如下

CSS mask 實現滑鼠跟隨鏤空效果

已經全部都模糊了,只是圓形區域外暗一些。由於::before的尺寸佔據整個容器,所以整個背後都變模糊了,圓形外部比較暗是因為半透明漸變的影響。

總之還是不能滿足我們的需求,需要尋求新的解決方式。

五、CSS MASK 實現鏤空

與其說是讓圓形區域不模糊,還不如說是把那塊區域給鏤空了。就好比之前是一整塊磨砂玻璃,然後透過

CSS MASK

打了一個圓孔,這樣透過圓孔看到後面肯定是清晰的。

可以對第二個例子稍作修改,透過徑向漸變繪製一個透明圓,剩餘部分都是純色的遮罩層,示意如下

CSS mask 實現滑鼠跟隨鏤空效果

用程式碼實現就是

。wrap::before{ content: ‘’; position: absolute; width: 100%; height: 100%; left: 0; top: 0; -webkit-mask: radial-gradient( circle at calc(var(——x, 。5) * 100% ) calc(var(——y, 。5) * 100% ), transparent 50px, #000 51px); background: rgba(0,0,0,。3); backdrop-filter: blur(5px)}複製程式碼

這樣就實現了文章開頭的效果

CSS mask 實現滑鼠跟隨鏤空效果

完整程式碼可以檢視:backdrop-mask (codepen。io)

六、CSS MASK COMPOSITE 實現更豐富的鏤空效果

除了使用徑向漸變繪製遮罩層以外,還可以透過

CSS MASK COMPOSITE(遮罩合成)

的方式來實現。標準關鍵值如下(firefox支援):

/* Keyword values */mask-composite: add; /* 疊加(預設) */mask-composite: subtract; /* 減去,排除掉上層的區域 */mask-composite: intersect; /* 相交,只顯示重合的地方 */mask-composite: exclude; /* 排除,只顯示不重合的地方 */複製程式碼

遮罩合成是什麼意思呢?可以類比 photoshop 中的形狀合成,幾乎是一一對應的

CSS mask 實現滑鼠跟隨鏤空效果

-webkit-mask-composite 與標準下的值有所不同,屬性值非常多,如下(chorme 、safari 支援)

-webkit-mask-composite: clear; /*清除,不顯示任何遮罩*/-webkit-mask-composite: copy; /*只顯示上方遮罩,不顯示下方遮罩*/-webkit-mask-composite: source-over; -webkit-mask-composite: source-in; /*只顯示重合的地方*/-webkit-mask-composite: source-out; /*只顯示上方遮罩,重合的地方不顯示*/-webkit-mask-composite: source-atop;-webkit-mask-composite: destination-over;-webkit-mask-composite: destination-in; /*只顯示重合的地方*/-webkit-mask-composite: destination-out;/*只顯示下方遮罩,重合的地方不顯示*/-webkit-mask-composite: destination-atop;-webkit-mask-composite: xor; /*只顯示不重合的地方*/複製程式碼

是不是一臉懵?這裡做了一個對應的效果圖,如果不太熟練,使用的時候知道有這樣一個功能,然後對著找就行了

CSS mask 實現滑鼠跟隨鏤空效果

回到這裡,可以繪製一整塊背景和一個圓形背景,然後透過遮罩合成排除(mask-composite: exclude)打一個孔就行了,實現如下

。wrap::before{ content: ‘’; position: absolute; width: 100%; height: 100%; left: 0; top: 0; -webkit-mask: url(“data:image/svg+xml,%3Csvg width=‘50’ height=‘50’ viewBox=‘0 0 50 50’ fill=‘none’ xmlns=‘http://www。w3。org/2000/svg’%3E%3Ccircle cx=‘25’ cy=‘25’ r=‘25’ fill=‘%23C4C4C4’/%3E%3C/svg%3E”), linear-gradient(red, red); -webkit-mask-size: 50px, 100%; -webkit-mask-repeat: no-repeat; -webkit-mask-position: calc(var(——x, 。5) * 100% + var(——x, 。5) * 100px - 50px ) calc(var(——y, 。5) * 100% + var(——y, 。5) * 100px - 50px ), 0; -webkit-mask-composite: xor; /*只顯示不重合的地方, chorem 、safari 支援*/ mask-composite: exclude; /* 排除,只顯示不重合的地方, firefox 支援 */ background: rgba(0,0,0,。3); backdrop-filter: blur(5px)}複製程式碼

需要注意-webkit-mask-position中的計算,這樣也能很好的實現這個效果

CSS mask 實現滑鼠跟隨鏤空效果

完整程式碼可以檢視:backdrop-mask-composite (codepen。io)

你可能已經發現,上述例子中的圓是透過 svg 繪製的,還用到了遮罩合成,看著好像更加繁瑣了。其實呢,這是一種更加萬能的解決方式,可以帶來無限的可能性。比如我需要一個星星⭐️的鏤空效果,很簡單,先透過一個繪製軟體畫一個

CSS mask 實現滑鼠跟隨鏤空效果

然後把這段 svg 程式碼轉義一下,這裡推薦使用張鑫旭老師的SVG線上壓縮合並工具

CSS mask 實現滑鼠跟隨鏤空效果

替換到剛才的例子中就可以了

。wrap::before{ content: ‘’; position: absolute; width: 100%; height: 100%; left: 0; top: 0; -webkit-mask: url(“data:image/svg+xml,%3Csvg width=‘96’ height=‘91’ viewBox=‘0 0 96 91’ fill=‘none’ xmlns=‘http://www。w3。org/2000/svg’%3E%3Cpath d=‘M48 0l11。226 34。55h36。327l-29。39 21。352L77。39 90。45 48 69。098 18。61 90。451 29。837 55。9。447 34。55h36。327L48 0z’ fill=‘%23C4C4C4’/%3E%3C/svg%3E”), linear-gradient(red, red); -webkit-mask-size: 50px, 100%; -webkit-mask-repeat: no-repeat; -webkit-mask-position: calc(var(——x, 。5) * 100% + var(——x, 。5) * 100px - 50px ) calc(var(——y, 。5) * 100% + var(——y, 。5) * 100px - 50px ), 0; -webkit-mask-composite: xor; /*只顯示不重合的地方, chorem 、safari 支援*/ mask-composite: exclude; /* 排除,只顯示不重合的地方, firefox 支援 */ background: rgba(0,0,0,。3); backdrop-filter: blur(5px)}複製程式碼

星星鏤空實現效果如下

CSS mask 實現滑鼠跟隨鏤空效果

完整程式碼可以檢視:backdrop-star (codepen。io)

再比如一個心形❤,實現效果如下

CSS mask 實現滑鼠跟隨鏤空效果

完整程式碼可以檢視:backdrop-heart (codepen。io)

只有想不到,沒有做不到

七、總結和說明

以上實現了一個滑鼠跟隨鏤空的效果,從簡單到複雜,從單一到通用,雖然藉助了一點點 JS ,但是僅僅是“工具人”的角色,互動邏輯全部都由 CSS 完成,下面總結一下:

足夠大的陰影是一個實現圓形鏤空效果的小技巧

CSS 漸變也能輕易的繪製出圓形鏤空背景

藉助 CSS 變數可以很方便的利用滑鼠位置實現想要的效果

backdrop-filter 可以想象成磨砂玻璃的功能

CSS Mask 可以給磨砂玻璃打孔,實現鏤空的效果

藉助遮罩合成特性和SVG,可以實現任意形狀的鏤空效果

CSS MASK 還是非常強大的,有必要還是多掌握一下。最後,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發❤❤❤

Top