ShaderEffect을 이용하면 다양한 그래픽효과를 구현할 수 있다. 이를 이용해서 버튼의 클릭 효과를 구현해본다.
MyButton.qml
import QtQuick 2.2
Item{
signal clicked()
signal pressed()
property alias radius: base.radius
Rectangle{
id: base
radius: 10
anchors.fill: parent
color: "#10000000"
}
ShaderEffect {
id: shaderEffect1
opacity: 1
anchors.fill: parent
property variant source: effectSource
ShaderEffectSource {
id: effectSource
sourceItem: base
hideSource: true
}
property point normTouchPos
property real widthToHeightRatio: height / width
// animated uniform property
property real spread: 0
ParallelAnimation {
id: touchStartAnimation
UniformAnimator {
uniform: "spread";
target: shaderEffect1
from: 0; to: 1
duration: 300
easing.type: Easing.InQuad
}
onStopped: {
// animation stopped
if(!touch.pressed){
if(shaderEffect1.spread != 0)
shaderEffect1.spread = 0
}
}
}
fragmentShader: "
uniform sampler2D source;
varying mediump vec2 qt_TexCoord0;
uniform lowp float qt_Opacity;
uniform mediump vec2 normTouchPos;
uniform mediump float widthToHeightRatio;
uniform mediump float spread;
void main() {
mediump float radius = (0.5 + abs(0.5 - normTouchPos.x)) * 1.0 * spread;
mediump vec2 circleCenter =
normTouchPos + (vec2(0.5) - normTouchPos) * radius * 2.0;
mediump float circleX = (qt_TexCoord0.x - circleCenter.x);
mediump float circleY = (qt_TexCoord0.y - circleCenter.y) * widthToHeightRatio;
highp vec4 color = texture2D(source, qt_TexCoord0);
lowp vec4 tapOverlay =
color * step(circleX*circleX + circleY*circleY, radius*radius);
gl_FragColor = (color + tapOverlay) * qt_Opacity;
}
"
function touchStart(x, y) {
normTouchPos = Qt.point(x / width, y / height)
touchStartAnimation.start()
}
function touchStop() {
touchStartAnimation.stop()
}
}
MouseArea{
id: touch
anchors.fill: parent
onPressed: {
shaderEffect1.touchStop()
shaderEffect1.touchStart(mouseX, mouseY)
}
onClicked: {
parent.clicked()
shaderEffect1.spread = 0
}
onExited: {
shaderEffect1.spread = 0
}
}
}
다음은 구현된 MyButton을 사용하는 방법이다.
main.qml
import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 320
height: 240
title: qsTr("ShaderEffect Custom Button")
ColumnLayout{
anchors.centerIn: parent
spacing: 10
MyButton{
width: 100
height: 100
radius: 50
Layout.alignment: Qt.AlignHCenter
Text {
id: button0_text
anchors.centerIn: parent
text: qsTr("Hello")
font.pixelSize: 15
}
onClicked: {
if(button0_text.text == "Hello")
button0_text.text = "OK"
else{
button0_text.text = "Hello"
}
}
}
MyButton{
width: 100
height: 50
Layout.alignment: Qt.AlignHCenter
Text {
id: button1_text
anchors.centerIn: parent
text: qsTr("MyButton")
font.bold: true
}
onClicked: {
if(button1_text.text == "MyButton")
button1_text.text = "Makersweb.net"
else{
button1_text.text = "MyButton"
}
}
}
}
}