动画分组(Grouped Animations)
通常使用的动画比一个属性的动画更加复杂。例如你想同时运行几个动画并把他们连接起来,或者在一个一个的运行,或者在两个动画之间执行一个脚本。动画分组提供了很好的帮助,作为命名建议可以叫做一组动画。有两种方法来分组:平行与连续。你可以使用SequentialAnimation(连续动画) 和ParallelAnimation(平行动画) 来实现它们,它们作为动画的容器来包含其它的动画元素。
我们先看下SequentialAnimation的效果:
首先创建 BrightSquare.qml
import QtQuick 2.5
Rectangle {
width: 48
height: 48
color: "#f0f0f0"
border.color: Qt.lighter(color)
}
然后创建SequentialAnimation.qml:
import QtQuick 2.0
BrightSquare {
id:root
width: 600
height: 400
property int duration: 3000
property Item ufo: ufo
Image {
anchors.fill: parent
source: "assets/ufo_background.png"
}
MouseArea{
id:getset
anchors.fill: parent
onClicked: {
anim.stop()
ufo.x = 20
ufo.y = root.height-ufo.height
}
}
ClickableImageV2{
id: ufo
x:20; y:root.height - height
labelColor: "black"
text:" 吉法师 "
source: "assets/ufo.png"
onClicked: anim.restart()
}
SequentialAnimation{ //连续动画
id:anim
NumberAnimation{
target: ufo
properties: "y"
to:20
// 60% of time to travel up
duration: root.duration*0.6
}
NumberAnimation{
target: ufo
properties: "x"
to:400
// 40% of time to travel sideways
duration: root.duration*0.4
}
}
}
其中ClickableImageV2 文件的定义在上一章节定义过的,想要看到同学在博客里看一看。
SequentialAnimation 会先执行第一个NumberAnimation,然后在执行第二个NumberAnimation动画于是就是我们看到的结果。
ParallelAnimation(平行动画)的效果:
对应的代码:
import QtQuick 2.0
BrightSquare {
id:root
width: 600
height: 400
property int duration: 3000
property Item ufo: ufo
Image {
anchors.fill: parent
source: "assets/ufo_background.png"
}
MouseArea{
id:getset
anchors.fill: parent
onClicked: {
anim.stop()
ufo.x = 20
ufo.y = root.height-ufo.height
}
}
ClickableImageV2{
id: ufo
x:20; y:root.height - height
labelColor: "black"
text:" Icy "
source: "assets/ufo.png"
onClicked: anim.restart()
}
ParallelAnimation {
id: anim
NumberAnimation {
target: ufo
properties: "y"
to: 20
duration: root.duration
}
NumberAnimation {
target: ufo
properties: "x"
to: 400
duration: root.duration
}
}
}
ParallelAnimation 动画是同时进行 y与x 于是就是我们看到的样子。
组合例子
我们要执行一组动画,如下图:
动态图如下:
要弄明白这个动画我们需要剖析这个目标的运动过程。我们需要记住这个动画是通过属性变化来实现的动画,下面是不同部分的转换:
- 从左向右的x坐标转换(X1)
- 从下往上的y坐标转换(Y1) 然后跟着一个从上往下的Y坐标转换(Y2)
- 整个动画过程中360度旋转。
这个动画将会花掉3秒钟的时间。
import QtQuick 2.0
Item {
id: root
width: 800
height: 500
property int duration: 3000
//天空界面
Rectangle{
id:sky
width: parent.width
height: 300
gradient: Gradient{
GradientStop{position: 0.0; color: "#0080FF"}
GradientStop{position: 1.0; color: "#66CCFF"}
}
}
//大地界面
Rectangle {
id: ground
anchors.top: sky.bottom
anchors.bottom: root.bottom
width: parent.width
gradient: Gradient {
GradientStop { position: 0.0; color: "#00FF00" }
GradientStop { position: 1.0; color: "#00803F" }
}
}
//加载足球
Image {
id: ball
x:0; y:root.height -height
source: "assets/soccer_ball.png"
MouseArea{
anchors.fill: parent
onClicked: {
ball.x = 0;
ball.y = root.height-ball.height;
ball.rotation = 0;
anim.restart()
}
}
}
}
首先我们加载足球,加载天,加载大地
首先考虑y方向的运动,到最高点在回到地面,到地面反冲,这里可以使用 SequentialAnimation 的性质让它运动:
SequentialAnimation{
NumberAnimation{
target: ball
properties: "y"
to: 20
duration: root.duration * 0.4
easing.type: Easing.OutCirc
}
NumberAnimation {
target: ball
properties: "y"
to: root.height-ball.height
duration: root.duration * 0.6
easing.type: Easing.OutBounce
}
}
会有0.4的时间来运行向上,0.6的时间来向下运动
效果图:
我们在这个动作的基础同时执行向x 运动,使用ParallelAnimation 放在外变,同时添加向右运动:
ParallelAnimation
{
id:anim
SequentialAnimation{
NumberAnimation{
target: ball
properties: "y"
to: 20
duration: root.duration * 0.4
easing.type: Easing.OutCirc
}
NumberAnimation {
target: ball
properties: "y"
to: root.height-ball.height
duration: root.duration * 0.6
easing.type: Easing.OutBounce
}
}
NumberAnimation {
target: ball
properties: "x"
to: root.width-ball.width
duration: root.duration
// easing.type: Easing.OutCirc
}
}
效果图:
最后一步,加上让球旋转起来就可以了:
RotationAnimation{
target: ball
properties: "rotation"
to: 1080
duration: root.duration
}
全部代码:
import QtQuick 2.0
Item {
id: root
width: 800
height: 500
property int duration: 3000
//天空界面
Rectangle{
id:sky
width: parent.width
height: 300
gradient: Gradient{
GradientStop{position: 0.0; color: "#0080FF"}
GradientStop{position: 1.0; color: "#66CCFF"}
}
}
//大地界面
Rectangle {
id: ground
anchors.top: sky.bottom
anchors.bottom: root.bottom
width: parent.width
gradient: Gradient {
GradientStop { position: 0.0; color: "#00FF00" }
GradientStop { position: 1.0; color: "#00803F" }
}
}
//加载足球
Image {
id: ball
x:0; y:root.height -height
source: "assets/soccer_ball.png"
MouseArea{
anchors.fill: parent
onClicked: {
ball.x = 0;
ball.y = root.height-ball.height;
ball.rotation = 0;
anim.restart()
}
}
}
//加载动画
ParallelAnimation
{
id:anim
SequentialAnimation{
NumberAnimation{
target: ball
properties: "y"
to: 20
duration: root.duration * 0.4
easing.type: Easing.OutCirc
}
NumberAnimation {
target: ball
properties: "y"
to: root.height-ball.height
duration: root.duration * 0.6
easing.type: Easing.OutBounce
}
}
NumberAnimation {
target: ball
properties: "x"
to: root.width-ball.width
duration: root.duration
// easing.type: Easing.OutCirc
}
RotationAnimation{
target: ball
properties: "rotation"
to: 1080
duration: root.duration
}
}
}
状态与过渡(States and Transitions)
通常我们将用户界面描述为一种状态。一个状态定义了一组属性的改变,并且会在一定的条件下被触发。另外在这些状态转化的过程中可以有一个过渡,定义了这些属性的动画或者一些附加的动作。当进入一个新的状态时,动作也可以被执行。
我们的目标效果:
其实就是状态切换,记得以前学习html的时候使用的是2个图标不断切换,让你感觉是变化的,这里采用了State 与 Transition达到这样的效果。
不多说了,比较简单,直接上代码:
import QtQuick 2.0
Rectangle {
id: root
width: 150
height: 250
//定义三个色彩
property color black: '#1f1f21'
property color red: '#fc3d39'
property color green: '#53d769'
gradient: Gradient {
GradientStop { position: 0.0; color: "#2ed5fa" }
GradientStop { position: 1.0; color: "#2467ec" }
}
Rectangle{
id:light1
x:25;y:15
width: 100; height: width
radius: width/2
color: root.black
border.color: Qt.lighter(color,1.1)
}
Rectangle {
id: light2
x: 25; y: 135
width: 100; height: width
radius: width/2
color: root.black
border.color: Qt.lighter(color, 1.1)
}
//状态变化
state: "stop"
states: [
State {
name: "stop"
PropertyChanges {
target: light1
color:root.red
}
PropertyChanges{
target: light2
color:root.black
}
},
State {
name: "go"
PropertyChanges { target: light1; color: root.black }
PropertyChanges { target: light2; color: root.green }
}
]
MouseArea {
anchors.fill: parent
onClicked: parent.state = (parent.state == "stop"? "go" : "stop")
}
transitions: [
Transition {
from: "stop"; to: "go"
// from: "*"; to: "*"
ColorAnimation { target: light1; properties: "color"; duration: 2000 }
ColorAnimation { target: light2; properties: "color"; duration: 2000 }
},
Transition {
from: "go"; to:"stop"
ColorAnimation { target: light1; properties: "color"; duration: 2000 }
ColorAnimation { target: light2; properties: "color"; duration: 2000 }
}
]
}
动画部分这本书就讲解这莫多了,每次后面有提高篇后,上面总是写着:
好的,就这莫多了,喜欢的朋友记得关注与提问偶, 一键三联。