Reputation: 415
Is it possible in QML, maybe using shader effects with layers, to create an item that makes another item (with a higher z index) visible only when the two layers overlap? I've been messing aroud with OpacityMask and ThresholdMask but have been unable to figure it out. The effect I'm looking for in the context of the example below would be if the the black circle was only visible when the two red squares are under it:
current:
desired:
Some key points are that the bottom layer (red squares) must be moveable (OpacityMask doesn't seem to let you drag the maskSource) and the bottom layer needs to also be able to contain other elements within it that the black circle responds to. Any guidance towards the right things to learn in order to achieve this would be appreciated. Here is the QML for the red squares and black circle thing. The red squares are draggable as one element:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.12
import QtGraphicalEffects 1.12
Window {
id: main_window
visible: true
width: 1500
height: 1000
title: qsTr("Hello World")
Item {
width: main_window.width
height: main_window.height
LinearGradient {
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(main_window.width, 0)
gradient: Gradient {
GradientStop { position: 0.0; color: "#003cff" }
GradientStop { position: 1.0; color: "#9afff9" }
}
}
}
Rectangle {
id: sfg
width: 175
height: 75
color: 'transparent'
RowLayout {
width: parent.width
height: parent.height
spacing: 25
Rectangle {
Layout.preferredWidth: 75
Layout.fillWidth: false
Layout.fillHeight: true
color: 'red'
}
Rectangle {
Layout.preferredWidth: 75
Layout.fillWidth: false
Layout.fillHeight: true
color: 'red'
}
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
drag {
target: sfg
}
}
}
Rectangle {
id: mask
color: 'black'
x: 400
y: 200
width: 100
height: 100
visible: true
opacity: 1
radius: 50
}
}
Upvotes: 3
Views: 1763
Reputation: 1093
Like this?
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.12
import QtGraphicalEffects 1.12
Window {
id: main_window
visible: true
width: 1500
height: 1000
title: qsTr("Hello World")
Item {
width: main_window.width
height: main_window.height
LinearGradient {
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(main_window.width, 0)
gradient: Gradient {
GradientStop { position: 0.0; color: "#003cff" }
GradientStop { position: 1.0; color: "#9afff9" }
}
}
}
Rectangle {
id: sgfBox
anchors.fill: parent
color: "transparent"
Rectangle {
id: sfg
width: 175
height: 75
color: 'transparent'
RowLayout {
width: parent.width
height: parent.height
spacing: 25
Rectangle {
Layout.preferredWidth: 75
Layout.fillWidth: false
Layout.fillHeight: true
color: 'red'
}
Rectangle {
Layout.preferredWidth: 75
Layout.fillWidth: false
Layout.fillHeight: true
color: 'red'
}
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
drag {
target: sfg
}
}
}
}
Rectangle {
id: mask
anchors.fill: parent
color: "transparent"
Rectangle {
color: 'black'
x: 400
y: 200
width: 100
height: 100
opacity: 1
radius: 50
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: sgfBox
}
}
}
Upvotes: 3