QML 的?OpacityMask
?用于通過遮罩元素的?透明度(Alpha 通道)?裁剪源元素的可見區域,適用于創建不規則形狀的 UI 元素(如圓形頭像、波浪形進度條)或復雜視覺效果。以下是詳細使用技巧和常見場景示例:
1. 基本用法
import QtQuick 2.15
import QtQuick.Effects 1.15 // 引入效果模塊Item {width: 300height: 300// 源元素(被裁剪的內容)Image {id: sourceImagesource: "image.jpg"visible: false // 隱藏源,僅用于遮罩輸入}// 遮罩元素(定義可見區域)Rectangle {id: maskwidth: 200height: 200radius: 100 // 圓形遮罩visible: false // 隱藏遮罩元素}// 應用透明度遮罩OpacityMask {anchors.fill: parentsource: sourceImage // 源內容maskSource: mask // 遮罩形狀}
}
關鍵屬性:
source
:被遮罩的源元素(需隱藏,visible: false
)。maskSource
:定義裁剪形狀的遮罩元素(透明度決定源元素的可見性)。invert
:設為?true
?時反轉遮罩(顯示原本透明的區域)。cached
:設為?true
?緩存遮罩結果,提升性能。
2. 常見應用場景
(1) 圓形頭像
Image {id: avatarsource: "user.png"visible: false
}OpacityMask {width: 100height: 100source: avatarmaskSource: Rectangle { // 圓形遮罩width: 100height: 100radius: 50visible: false}
}
(2) 漸變遮罩(文字淡出)
Text {id: longTexttext: "This is a long text that needs to fade out at the bottom..."width: 200wrapMode: Text.Wrapvisible: false
}// 漸變遮罩(從上到下透明度從1到0)
Rectangle {id: gradientMaskwidth: 200height: 100visible: falsegradient: Gradient {GradientStop { position: 0.0; color: "white" }GradientStop { position: 1.0; color: "transparent" }}
}OpacityMask {source: longTextmaskSource: gradientMask
}
(3) 動態遮罩(可拖動區域)
Item {width: 400height: 400Image {id: backgroundsource: "map.jpg"visible: false}// 可拖動的圓形遮罩Rectangle {id: dynamicMaskwidth: 100height: 100radius: 50visible: falsex: mouseArea.mouseX - width/2y: mouseArea.mouseY - height/2}OpacityMask {source: backgroundmaskSource: dynamicMask}MouseArea {id: mouseAreaanchors.fill: parenthoverEnabled: true}
}
3. 進階技巧
(1) 結合其他特效(模糊+遮罩)
OpacityMask {source: ShaderEffect { // 先模糊再遮罩property variant src: Image { source: "image.jpg" }layer.enabled: truelayer.effect: FastBlur { radius: 16 }}maskSource: Rectangle { // 星形遮罩width: 200; height: 200visible: falseCanvas { // 繪制星形路徑anchors.fill: parentonPaint: {var ctx = getContext("2d");ctx.beginPath();// ... 繪制星形路徑ctx.fillStyle = "white";ctx.fill();}}}
}
(2) 反轉遮罩(顯示外部區域)
OpacityMask {source: Image { source: "image.jpg"; visible: false }maskSource: Rectangle { // 中心透明的圓形width: 200; height: 200radius: 100color: "white"Rectangle { // 中心挖空anchors.centerIn: parentwidth: 50; height: 50radius: 25color: "transparent"}visible: false}invert: true // 反轉遮罩,顯示挖空的外部
}
(3) 動畫遮罩(動態形狀變化)
Rectangle {id: animatingMaskwidth: 200; height: 200visible: falseradius: width/2 * (0.5 + waveAnim.value) // 動態圓角NumberAnimation {id: waveAnimtarget: animatingMaskproperty: "radius"from: 0.1to: 0.9duration: 2000loops: Animation.Infiniterunning: true}
}OpacityMask {source: Image { source: "texture.jpg"; visible: false }maskSource: animatingMask
}
4. 性能優化
- 啟用緩存:對靜態遮罩設置?
cached: true
。 - 簡化遮罩元素:避免使用復雜?
Canvas
?或動態生成的遮罩。 - 降采樣處理:縮小遮罩和源的紋理尺寸:
layer.textureSize: Qt.size(width/2, height/2)
5. 常見問題
(1) 遮罩不顯示
- 檢查?
source
?和?maskSource
?是否已正確隱藏(visible: false
)。 - 確認遮罩元素的 Alpha 通道非全透明(至少部分區域為可見)。
(2) 邊緣鋸齒
- 啟用?
layer.smooth: true
?抗鋸齒。 - 使用高分辨率遮罩或增加遮罩元素的?
layer.textureSize
。
(3) 動態遮罩卡頓
- 減少遮罩元素的復雜度(如避免實時繪制?
Canvas
)。 - 限制遮罩屬性更新的頻率(如節流動畫幀率)。
總結
- 核心作用:通過遮罩的透明度通道控制源元素的可見區域。
- 關鍵屬性:
source
(源內容)、maskSource
(遮罩形狀)、invert
(反轉遮罩)。 - 適用場景:不規則形狀裁剪、動態區域顯示、漸變過渡效果。
- 優化要點:簡化遮罩結構、啟用緩存、合理降采樣。