问题
Im trying to animate the top level "cont" rectangle to the right, downscale it, and move it over the right a little bit and the back to left on left swipe. At the same time it will down scale the back rectangle also, It will set the scale size to that of the screen and will place the rectangle flush to the right of the screen.
Would anyone be ale to give me some pointers on how I need to do it?
Check pictures for reference to what I'm trying to achieve
And I forgot to mention how would I apply easing to the animation as well?
(source: paisei.com)
(source: paisei.com)
import QtQuick 2.0
import QtQuick.Controls 1.1
Item {
id: root
// default size, but scalable by user
height: 450
width: 300
signal clickInit();
MouseArea{
anchors.fill: parent
signal swipeRight;
signal swipeLeft;
signal swipeUp;
signal swipeDown;
property int startX;
property int startY;
onPressed: {
startX = mouse.x;
startY = mouse.y;
}
onReleased: {
var deltax = mouse.x - startX;
var deltay = mouse.y - startY;
if (Math.abs(deltax) > 50 || Math.abs(deltay) > 50) {
if (deltax > 30 && Math.abs(deltay) < 30) {
// swipe right
console.log("swiped right");
downSizeToRight.start()
swipeRight();
} else if (deltax < -30 && Math.abs(deltay) < 30) {
console.log("swiped left")
// swipe left
upSizeFromRight.start()
swipeLeft()
} else if (Math.abs(deltax) < 30 && deltay > 30) {
console.log("swiped down")
// swipe down
swipeDown()
} else if (Math.abs(deltax) < 30 && deltay < 30) {
console.log("swiped up")
// swipe up
swipeUp()
}
}
}
Rectangle{
id: bg
gradient: Gradient {
GradientStop { position: 0.0; color: "#000000" }
GradientStop { position: 1.0; color: "#fff" }
}
height : cont.height + 80
width : cont.width + 80
y:cont.y - 40
x: cont.x - 80
}
Rectangle{
id: cont
width:parent.width
height:parent.height
transform: Scale {
id: scaleTransform
property real scale: 1
xScale: scale
yScale: scale
}
SequentialAnimation {
id: downSizeToRight
loops: 1
PropertyAnimation {
target: scaleTransform
properties: "scale"
from: 1.0
to: 0.5
duration: 300
}
}
SequentialAnimation {
id: upSizeFromRight
loops: 1
PropertyAnimation {
target: scaleTransform
properties: "scale"
from: 0.5
to: 1.0
duration: 300
}
}
Label {
id: label1
y: 226
text: qsTr("Hi this is just a load of text that i cant write in that makes no sence for testing")
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
anchors.right: parent.right
anchors.rightMargin: 5
anchors.left: parent.left
anchors.leftMargin: 5
}
}
}
}
回答1:
For the people who would be interested in doing something like this, this was my solution but I still have one error which I'm still currently trying to find a fix which is on the scale front back to the left animation the right back rectangle flies back over to the left covering the left back rectangle. Its a little hard to describe but if you compile and swipe left and right you'll see the error.
And also I'm a total beginner at qt quick so if you feel there is a better way to do anything in this code then any changes would be appreciated.
Thank you
import QtQuick 2.0
MouseArea {
id:screen
width: 320
height: 460
property int startX;property int startY
signal swipeRight;signal swipeLeft;signal swipeUp;signal swipeDown
property int size_addition:100
property bool swiped: false
property int swiped_direction:1
property int aniSpeed: 200;
states: [
State {
name: "frontToRight"
PropertyChanges {target: front;x:(screen.width - (screen.width/3) + (screen.width/24) - 25)}
PropertyChanges {target: front;scale:0.5}
PropertyChanges {target: right;x:screen.width}
PropertyChanges {target: left;scale:1}
},
State {
name: "frontToLeft"
PropertyChanges {target: front;x:-(screen.width - (screen.width/3) + (screen.width/24) - 25)}
PropertyChanges {target: front;scale:0.5}
PropertyChanges {target: right;scale:1}
}
]
onPressed: {startX=mouse.x;startY=mouse.y;}
onReleased: {
var swipe_a = 115; var deltax = mouse.x - startX; var deltay = mouse.y - startY
if (Math.abs(deltax) > 100 || Math.abs(deltay) > 100) {
if (deltax > swipe_a && Math.abs(deltay) < swipe_a) {swipeRight()}
else if (deltax < -swipe_a && Math.abs(deltay) < swipe_a){swipeLeft()}
else if (Math.abs(deltax) < swipe_a && deltay > swipe_a) {swipeDown()}
else if (Math.abs(deltax) < swipe_a && deltay < swipe_a) {swipeUp()}
}
}
onSwipeRight: {
//scale to right
if(front.height == screen.height && swiped_direction!=0 && swiped_direction!=2)
{screen.state = "frontToRight";swiped = true;swiped_direction = 0;}
//back to center from left
else if(swiped && swiped_direction!=0)
{screen.state = "";swiped = false;swiped_direction = 1;}
}
onSwipeLeft: {
//scale to left // here is where my swipe problem lies
if(front.height == screen.height && swiped_direction!=2 && swiped_direction!=0)
{screen.state = "frontToLeft";swiped = true;swiped_direction = 2;}
//back to center from right
else if(swiped && swiped_direction!=2)
{screen.state = "";screen.swiped = false;screen.swiped_direction = 1;}
}
Rectangle{
id:left
color:"#0500ff"
height:screen.height
width:screen.width
transformOrigin: Item.Right
scale:1.2
Behavior on scale{NumberAnimation{duration:aniSpeed}}
Text{
text:"Left"
anchors.fill: parent
font.pixelSize: 70
}
}
Rectangle{
id:right
color:"#028000"
height:screen.height
width:screen.width
transformOrigin: Item.Left
Behavior on scale{NumberAnimation{duration:aniSpeed}}
scale:1.2
Text{
text:"Right"
anchors.fill: parent
font.pixelSize: 70
}
}
Rectangle{
id:front
color:"red"
height:screen.height
width:screen.width
Behavior on scale{ NumberAnimation{duration:aniSpeed;}}
Behavior on x{NumberAnimation{duration:aniSpeed}}
Text{
text:"Front"
anchors.fill: parent
font.pixelSize: 70
}
}
}
回答2:
OK guys. I've got it working but it complains to me saying Imperative code is not supported in the Qt Quick Designer.
import QtQuick 2.0
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
MouseArea {
id:screen
width: 320
height: 460
property int startX;property int startY
signal swipeRight;signal swipeLeft;signal swipeUp;signal swipeDown
property int size_addition:100
property bool swiped: false
property int swiped_direction:1
property int aniSpeed: 200;
states: [
State {
name: "frontToRight"
PropertyChanges {target: front;x:(screen.width - (screen.width/3) + (screen.width/24) - 25)}
PropertyChanges {target: front;scale:0.5}
//PropertyChanges {target: right;x:screen.width}
PropertyChanges {target: left;scale:1}
},
State {
name: "frontToLeft"
PropertyChanges {target: front;x:-(screen.width - (screen.width/3) + (screen.width/24) - 25)}
PropertyChanges {target: front;scale:0.5}
PropertyChanges {target: right;scale:1}
}
]
onPressed: {startX=mouse.x;startY=mouse.y;}
onReleased: {
var swipe_a = 115; var deltax = mouse.x - startX; var deltay = mouse.y - startY
if (Math.abs(deltax) > 100 || Math.abs(deltay) > 100) {
if (deltax > swipe_a && Math.abs(deltay) < swipe_a) {swipeRight()}
else if (deltax < -swipe_a && Math.abs(deltay) < swipe_a){swipeLeft()}
else if (Math.abs(deltax) < swipe_a && deltay > swipe_a) {swipeDown()}
else if (Math.abs(deltax) < swipe_a && deltay < swipe_a) {swipeUp()}
}
}
I fixed it here by setting the z property of the left panel. Is there a better way of doing this? and also I've tried putting some easing on it to make the animation look a little better, but nothing seems to look very good. does anyone have and suggestions?
onSwipeRight: {
//scale to right
if(front.height == screen.height && swiped_direction!=0 && swiped_direction!=2)
{screen.state = "frontToRight";swiped = true;swiped_direction = 0;left.z=2}
//back to center from left
else if(swiped && swiped_direction!=0)
{screen.state = "";swiped = false;swiped_direction = 1;}
}
onSwipeLeft: {
//scale to left // here is where the righ tbg menu swipe problem lies
if(front.height == screen.height && swiped_direction!=2 && swiped_direction!=0)
{screen.state = "frontToLeft";swiped = true;swiped_direction = 2;left.z=0}
//back to center from right
else if(swiped && swiped_direction!=2)
{screen.state = "";screen.swiped = false;screen.swiped_direction = 1;}
}
Rectangle{
id:left
color:"#0500ff"
height:screen.height
width:screen.width
z:0
transformOrigin: Item.Right
scale:1.2
Behavior on scale{NumberAnimation{duration:aniSpeed}}
Text{
text:"Left"
anchors.fill: parent
font.pixelSize: 70
}
}
Rectangle{
id:right
z:1
color:"#028000"
height:screen.height
width:screen.width
transformOrigin: Item.Left
Behavior on scale{NumberAnimation{duration:aniSpeed}}
scale:1.2
Text{
text:"Right"
anchors.fill: parent
font.pixelSize: 70
}
}
Rectangle{
id:front
color:"red"
height:screen.height
width:screen.width
z:2
Behavior on scale{ NumberAnimation{duration:aniSpeed;}}
Behavior on x{NumberAnimation{duration:aniSpeed}}
Text{
text:"Front"
anchors.fill: parent
font.pixelSize: 70
}
}
}
回答3:
I fixed some other issues that I was having with this app. So I restarted it and this is the new version with no errors and works very nicely.
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.0
GestureArea {
id:main
width: 470
height: 700
property int swiped_direction:1
property bool swiped:false
property int aniSpeed: 90
onSwipeRight: {doRightSwipeProcess()}
onSwipeLeft: {doLeftSwipeProcess()}
states: [
State {
name: "toLeft"
PropertyChanges {target: front;x:(main.width - (main.width/3) + (main.width/24) - 25)}
PropertyChanges {target: front;scale:0.5}
PropertyChanges {target: left;scale:1}
},
State {
name: "toRight"
PropertyChanges {target: front;x:-(main.width - (main.width/3) + (main.width/24) - 25)}
PropertyChanges {target: front;scale:0.5}
PropertyChanges {target: right;scale:1}
}
]
Rectangle{
id:front
width:main.width
height:main.height
property int direction:1
color:"#fff"
Behavior on scale{NumberAnimation{duration:aniSpeed;}}
Behavior on x{NumberAnimation{duration:aniSpeed}}
z:2
}
Image{
id:left
source:"images/app_bg_left.png"
Behavior on scale{NumberAnimation{duration: main.aniSpeed}}
width:main.width
height:main.height
transformOrigin: Item.Right
scale:1.3
anchors.right:{if(scale<1.3){return main.right}else{return main.left}}
z:0
}
Settings{
id:right
//source:"images/app_bg_right.png"
Behavior on scale{NumberAnimation{duration: main.aniSpeed}}
width:main.width
height:main.height
transformOrigin: Item.Left
scale:1.3
anchors.left:{if(scale<1.3){return main.left}else{return main.right}}
z:1
onDoLeftSwipe: doLeftSwipeProcess()
onDoRightSwipe: doRightSwipeProcess()
}
function doRightSwipeProcess(){
//scale to right
if(front.height == main.height && swiped_direction!=0 && swiped_direction!=2)
{main.state = "toLeft";swiped = true;swiped_direction = 0;front.direction = 0}
//back to center from left
else if(swiped && swiped_direction!=0)
{main.state = "";swiped = false;swiped_direction = 1;front.direction = 1;}
}
function doLeftSwipeProcess(){
//scale to left // here is where the righ tbg menu swipe problem lies
if(front.height == main.height && swiped_direction!=2 && swiped_direction!=0)
{main.state = "toRight";swiped = true;swiped_direction = 2;front.direction = 2}
//back to center from right
else if(swiped && swiped_direction!=2)
{main.state = "";main.swiped = false;main.swiped_direction = 1;front.direction = 1}
}
}
来源:https://stackoverflow.com/questions/21509365/complex-group-animation-in-qtquick-2-0