我想创建一个可以被用户拖动的按钮,当释放时将返回到其原始位置。
在移动过程中,必须按照一些缓动曲线为按钮设置动画。
到目前为止我所拥有的是:
import QtQuick 2.2
import QtGraphicalEffects 1.0
Item {
property bool wasDragged: false
property real basePosX: (menuButton.width / 2) - (menuButtonIcon.width / 2) //menuButton.horizontalCenter
property real basePosY: (menuButton.height / 2) - (menuButtonIcon.height / 2) //menuButton.verticalCenter
id: menuButton
x: parent.width - 55
y: parent.height - 60
state: "Closed"
Rectangle {
id: menuButtonIcon
x: basePosX
y: basePosY
color: "#D23F31"
width: 65;
height: 65;
radius: width * 0.5
antialiasing: true
smooth: true
}
Rectangle {
id: menuButtonIconBar1
anchors.centerIn: menuButtonIcon
width: 17
height: 3
antialiasing: true
}
Rectangle {
id: menuButtonIconBar2
anchors.centerIn: menuButtonIcon
width: 17
height: 3
antialiasing: true
rotation: 90
}
MouseArea {
id: mouseArea
anchors.fill: menuButtonIcon
onPressed: menuButton.state = menuButton.state === "Open" ? "Closed" : "Open"
onReleased: {
if (wasDragged) {
wasDragged = false
menuButton.state = "Closed"
}
}
onPositionChanged:
{
wasDragged = true
var currentPosition = mapToItem(parent, mouse.x, mouse.y)
updateButtonPosition(currentPosition.x, currentPosition.y)
}
}
function updateButtonPosition(mouseX, mouseY)
{
console.log("pos change")
menuButtonIcon.x = mouseX - (menuButtonIcon.width / 2);
menuButtonIcon.y = mouseY - (menuButtonIcon.height / 2);
}
states: [
State {
name: "Closed"
PropertyChanges { target: menuButtonIcon; x: basePosX; y: basePosY}
},
State {
name: "Open"
PropertyChanges { target: menuButtonIconBar1; rotation: 135;}
PropertyChanges { target: menuButtonIconBar2; rotation: 225;}
PropertyChanges { target: menuButtonIcon; x: basePosX; y: basePosY}
}
]
transitions: [
Transition {
SpringAnimation { target: menuButtonIcon; properties: "x, y"; spring: 3; damping: 0.25; epsilon: 0.2; mass: 1; modulus: 0; velocity: 0 }
SpringAnimation { target: menuButtonIconBar1; properties: "rotation, scale"; spring: 3; damping: 0.25; epsilon: 0.5; mass: 1; modulus: 0; velocity: 0 }
SpringAnimation { target: menuButtonIconBar2; properties: "rotation, scale"; spring: 3; damping: 0.25; epsilon: 0.5; mass: 1; modulus: 0; velocity: 0 }
}
]
}
但问题是,如果你在旋转动画结束前拖动并保持静止,按钮将返回其原始位置,即使你从未发布它。
如果删除构成十字架的两个Rectangle
以及它们的动画,那么它就可以正常工作。
为什么按钮会自动返回原始位置,如何修复?
答案 0 :(得分:1)
试试这个:
import QtQuick 2.0
import QtGraphicalEffects 1.0
Item {
property bool wasDragged: false
property real basePosX: (menuButton.width / 2) - (menuButtonIcon.width / 2)
property real basePosY: (menuButton.height / 2) - (menuButtonIcon.height / 2)
property real currentPosX: (menuButton.width / 2) - (menuButtonIcon.width / 2)
property real currentPosY: (menuButton.height / 2) - (menuButtonIcon.height / 2)
id: menuButton
x: parent.width - 55
y: parent.height - 60
state: "Closed"
Rectangle {
id: menuButtonIcon
x: basePosX
y: basePosY
color: "#D23F31"
width: 65;
height: 65;
radius: width * 0.5
antialiasing: true
smooth: true
}
Rectangle {
id: menuButtonIconBar1
anchors.centerIn: menuButtonIcon
width: 17
height: 3
antialiasing: true
}
Rectangle {
id: menuButtonIconBar2
anchors.centerIn: menuButtonIcon
width: 17
height: 3
antialiasing: true
rotation: 90
}
MouseArea {
id: mouseArea
anchors.fill: menuButtonIcon
onPressed: menuButton.state = menuButton.state === "Open" ? "Closed" : "Open"
onReleased: {
if (wasDragged) {
wasDragged = false
menuButton.state = "Closed"
}
}
onPositionChanged:
{
wasDragged = true
var currentPosition = mapToItem(parent, mouse.x, mouse.y)
updateButtonPosition(currentPosition.x, currentPosition.y)
}
}
function updateButtonPosition(mouseX, mouseY)
{
console.log("pos change")
menuButtonIcon.x = mouseX - (menuButtonIcon.width / 2);
menuButtonIcon.y = mouseY - (menuButtonIcon.height / 2);
currentPosX = mouseX - (menuButtonIcon.width / 2);
currentPosY = mouseY - (menuButtonIcon.height / 2);
}
states: [
State {
name: "Closed"
PropertyChanges { target: menuButtonIcon; x: currentPosX; y: currentPosY}
},
State {
name: "Open"
PropertyChanges { target: menuButtonIconBar1; rotation: 135;}
PropertyChanges { target: menuButtonIconBar2; rotation: 225;}
PropertyChanges { target: menuButtonIcon; x: currentPosX; y: currentPosY}
}
]
onStateChanged: if(state === "Closed"){
currentPosX = basePosX
currentPosY = basePosY
}
transitions: [
Transition {
SpringAnimation {
target: menuButtonIcon;
properties: "x, y";
spring: 3;
damping: 0.25;
epsilon: 0.2;
mass: 1;
modulus: 0;
velocity: 0
}
SpringAnimation {
id:tr1;
target: menuButtonIconBar1;
properties: "rotation, scale";
spring: 3;
damping: 0.25;
epsilon: 0.5;
mass: 1;
modulus: 0;
velocity: 0
}
SpringAnimation {
id:tr2;
target: menuButtonIconBar2;
properties: "rotation, scale";
spring: 3;
damping: 0.25;
epsilon: 0.5;
mass: 1;
modulus: 0;
velocity: 0
}
}
]
}
在打开的状态下你应该在当前位置做一个x和y的propertyChanges,基础位置的绑定导致x和y的重置。你需要其他属性来获取当前的x和当前的y。 随着90%的问题得到解决,你会看到一个小的decalage大约1秒,按钮将返回到好的位置。 解决它我把属性更改置于关闭状态,x和y更改为currentPosition并在其中添加一个StateChanged插槽我重置位置。 我不知道这种奇怪行为的根本原因。但随着这种解决方法,它的工作正常。 问候