QML元素 - OpacityMask

QML 的 OpacityMask 用于通过遮罩元素的 透明度(Alpha 通道) 裁剪源元素的可见区域,适用于创建不规则形状的 UI 元素(如圆形头像、波浪形进度条)或复杂视觉效果。以下是详细使用技巧和常见场景示例:


1. 基本用法

import QtQuick 2.15
import QtQuick.Effects 1.15  // 引入效果模块

Item {
    width: 300
    height: 300

    // 源元素(被裁剪的内容)
    Image {
        id: sourceImage
        source: "image.jpg"
        visible: false  // 隐藏源,仅用于遮罩输入
    }

    // 遮罩元素(定义可见区域)
    Rectangle {
        id: mask
        width: 200
        height: 200
        radius: 100  // 圆形遮罩
        visible: false  // 隐藏遮罩元素
    }

    // 应用透明度遮罩
    OpacityMask {
        anchors.fill: parent
        source: sourceImage  // 源内容
        maskSource: mask     // 遮罩形状
    }
}
关键属性
  • source:被遮罩的源元素(需隐藏,visible: false)。
  • maskSource:定义裁剪形状的遮罩元素(透明度决定源元素的可见性)。
  • invert:设为 true 时反转遮罩(显示原本透明的区域)。
  • cached:设为 true 缓存遮罩结果,提升性能。

2. 常见应用场景

(1) 圆形头像
Image {
    id: avatar
    source: "user.png"
    visible: false
}

OpacityMask {
    width: 100
    height: 100
    source: avatar
    maskSource: Rectangle {  // 圆形遮罩
        width: 100
        height: 100
        radius: 50
        visible: false
    }
}
(2) 渐变遮罩(文字淡出)
Text {
    id: longText
    text: "This is a long text that needs to fade out at the bottom..."
    width: 200
    wrapMode: Text.Wrap
    visible: false
}

// 渐变遮罩(从上到下透明度从1到0)
Rectangle {
    id: gradientMask
    width: 200
    height: 100
    visible: false
    gradient: Gradient {
        GradientStop { position: 0.0; color: "white" }
        GradientStop { position: 1.0; color: "transparent" }
    }
}

OpacityMask {
    source: longText
    maskSource: gradientMask
}
(3) 动态遮罩(可拖动区域)
Item {
    width: 400
    height: 400

    Image {
        id: background
        source: "map.jpg"
        visible: false
    }

    // 可拖动的圆形遮罩
    Rectangle {
        id: dynamicMask
        width: 100
        height: 100
        radius: 50
        visible: false
        x: mouseArea.mouseX - width/2
        y: mouseArea.mouseY - height/2
    }

    OpacityMask {
        source: background
        maskSource: dynamicMask
    }

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        hoverEnabled: true
    }
}

3. 进阶技巧

(1) 结合其他特效(模糊+遮罩)
OpacityMask {
    source: ShaderEffect {  // 先模糊再遮罩
        property variant src: Image { source: "image.jpg" }
        layer.enabled: true
        layer.effect: FastBlur { radius: 16 }
    }
    maskSource: Rectangle {  // 星形遮罩
        width: 200; height: 200
        visible: false
        Canvas {  // 绘制星形路径
            anchors.fill: parent
            onPaint: {
                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: 200
        radius: 100
        color: "white"
        Rectangle {  // 中心挖空
            anchors.centerIn: parent
            width: 50; height: 50
            radius: 25
            color: "transparent"
        }
        visible: false
    }
    invert: true  // 反转遮罩,显示挖空的外部
}
(3) 动画遮罩(动态形状变化)
Rectangle {
    id: animatingMask
    width: 200; height: 200
    visible: false
    radius: width/2 * (0.5 + waveAnim.value)  // 动态圆角

    NumberAnimation {
        id: waveAnim
        target: animatingMask
        property: "radius"
        from: 0.1
        to: 0.9
        duration: 2000
        loops: Animation.Infinite
        running: 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(反转遮罩)。
  • 适用场景:不规则形状裁剪、动态区域显示、渐变过渡效果。
  • 优化要点:简化遮罩结构、启用缓存、合理降采样。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千笺客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值