QmlBook in chinese 编程之八 ---(Animations and States and Transitions)

动画分组(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 }
        }
    ]
}


动画部分这本书就讲解这莫多了,每次后面有提高篇后,上面总是写着:

 

 

好的,就这莫多了,喜欢的朋友记得关注与提问偶, 一键三联。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值