.mask()
Last updated
Last updated
一般而言,當我們使用:「view.mask(mask)
」這樣的語法時,我們是把 view 當作「要被剪裁的色紙」,而 mask 則是當作色紙「要被剪裁的形狀」,所以我們可以把 mask 想像成某種「裁刀鋼模」。
但實際上,它背後運作的機制是「把 mask 的 opacity 套用到 view 上面」,所以 mask 圖上的像素只要 opacity > 0 (前景),在它相對應的位置上的 view 的像素就會保留下來 (除非 view 上該點 opacity = 0)。反之,如果 mask 圖上的像素 opacity = 0 (背景),那麼 view 上相對應的點就會不見了,也就形同「被裁掉」了。
在預設的情況下,view 與 mask 是對齊「左上角」。
⚠️ 但注意:不管 mask 是文字或圖片,只要是設定了 .frame()、.scaledToFit()、.resizable() 等其中任何一個 (不知還有沒有其他的),馬上會變成「置中」對齊,而且這時 .frame() 所做的任何尺寸設定,完全不會改變原物件的大小,也就是對於 mask 來說,.frame() 除了可設定置中對齊外,似乎沒有任何作用。
⚠️ 注意:一個 mask 一旦設定了 .resizable() 或 .scaledToFit(),它就會縮放到它的 parent view 的大小並置中對齊,不管你有沒有設定 .frame()‼️
另外,對一般的 view 來說,做「縮放效應」(.scaleEffect) 的時候,預設情況下,是以自已的中心點為縮放中心,就算這個 view 當別人的 overlay 也是如此。但對於一個 mask 來說就不一樣了,不管 mask 是「置中對齊」還是「對齊左上角」,它的縮放中心都是「它的 parent view 的中心點」。
我們在上面的「重要觀念」有提到,就是:
如果我們對一個 mask 設定了 .resizable() 或 .scaledToFit() 之後,它就會縮放到「整個」 parent view 的大小並置中對齊,不管你有沒有設定 .frame()。
如果這樣,那麼問題就來了:
如果我們要安排 mask 在母視窗的位置,但又不希望它佔滿整個母視窗,那要怎麼辦❓
先用 ZStack 當作是 mask 的 container。
然後畫一個有「白色前景色」的 Rectangle。
最後設定 mask 的大小與位置 (如果是 ZStack 內會自動置中)。
⚠️ 注意:IconCard 📦 有修改過,所以下方的程式碼是舊版的。