前言
使用QML差不多2年了,在使用过程中深深的感受到QML的强大与便捷,让我深陷其中,不能自拔。其中QML相比传统的界面最大的优势就是便捷的动画效果与炫酷的粒子效果,让QML做出来的界面能媲美WPF和各种JS前端框架的效果。下面我们就开始进入QML动画美妙的世界吧。
更现代的程序界面
与传统的界面相比,现代化的程序界面的特色是更加鲜艳的色彩,以及更加丰富的动画。QML设计的目的就是用来创建Fluid UIs(流体界面),所谓流体界面,就是UI组件是动态的,而不会突然出现、消失或跳转,QML的动画效果就很好的实现了流体界面的要求。
QML动画实现方法
在QML中,实现动画最常用的是State(状态)&Transactions(过渡) 与 Animating Properyty Changes(属性改变动画)这两种方法。
1、State & Transactions(状态与过渡)
QML可以在组件中声明各种State(状态),在状态中可以包含该组件所需修改的属性值,当我们想改变组件的属性值时,只需该组件的State即可。Transaction(过渡)用来设置状态改变时的动画,常与State配合使用。创建一个Transaction对象,然后将其添加到组件的transcation属性中。使用方法如下:
以下代码展示的是使用State&Transactions方法实现一个页面切换的动画效果。
Window { visible: true width: 400; height: 300 title: "Animation" Rectangle { anchors.fill: parent; color: "green" } Rectangle { id: pageA color: "red" width: parent.width; height: parent.height // 创建2个状态"show","hide"分别表示显示界面和隐藏界面 states: [ // 将PageA的属性y赋值为0,opacity赋值为1以实现显示的效果 State { name: "show"; PropertyChanges { target: pageA; y: 0; opacity: 1 } }, // 将PageA的属性y赋值为-height,opaticy赋值为0以实现窗口向上移动并消失的效果 State { name: "hide"; PropertyChanges { target: pageA; y: -height; opacity: 0 } } ] state: "show" transitions: Transition { PropertyAnimation { properties: "y,opacity"; duration: 1000; easing.type: Easing.InOutBack } } } } MouseArea { anchors.fill: parent onClicked: { if(pageA.state == "show") pageA.state = "hide" else pageA.state = "show" } } }
当pageA的状态由”show”改变为”hide”时,PropertyChanges{target:pageA;y:-height;opacity:0}执行,将属性y改为-height,opacity改为0。
当属性改变时,PropertyAnimation{properties:"y,opacity";duration:1000;easing.type:Easing.InOutBack}被执行,产生动画效果。
2、Animating Property Changes(属性改变动画)
在属性上使用Behaviors(行为)关键字,指定在该属性改变时使用动画。修改以上代码使用Behaviors实现相同的效果。
Window { visible: true width: 400 height: 300 title: qsTr("Animation") Rectangle { id: pageB color: "green" anchors.fill: parent } Rectangle { id: pageA color: "red" width: parent.width height: parent.height // 给y属性改变安装动画 Behavior on y { PropertyAnimation { duration: 1000; easing.type: Easing.InOutBack } } // 给opacity属性改变安装动画 Behavior on opacity { PropertyAnimation{ duration: 1000 } } } MouseArea { anchors.fill: parent onClicked: { if (pageA.y == 0) { pageA.y = -pageA.height pageA.opacity = 0 } else { pageA.y = 0 pageA.opacity = 1 } } }
有些情况下还可以通过enabled属性来停用Behavior。注意这里的PropertyAnimation的from和to属性是不需要定义的,因为这些值已经提供了,分别是Rectangle的当前值和onClicked处理器中设置的新值。
3、其他动画使用方法
3.1 动画作为属性值的来源
一个动画被应用为属性值的源(property value source),要使用“动画on属性”语法。
Window { visible: true width: 400 height: 300 title: qsTr("Animation") Rectangle { id: pageB color: "green" anchors.fill: parent } Rectangle { width: 100; height: 100 color: "red" //启动后开始动画 PropertyAnimation on x {to: 50; duration: 1000; loops: Animation.Infinite} PropertyAnimation on y {to: 50; duration: 1000; loops: Animation.Infinite} } }
3.2 在信号处理器中创建一个动画,并在接收到信号时触发
Window { visible: true width: 400 height: 300 title: qsTr("Animation") Rectangle { id: pageB color: "green" anchors.fill: parent } Rectangle { id: rect width: 100; height: 100 color: "red" MouseArea { anchors.fill: parent onClicked: PropertyAnimation { target: rect properties: "x,y" to: 50 duration: 1000 } } } }
因为动画没有绑定到一个特定的对象或者属性,所以必须指定target和property(或者targets和properties)属性的值。而且还需要使用to属性来指定新的x和y的值。
3.3 独立动画
动画也可以像一个普通的QML对象一样进行创建,而不需要绑定到任何特定的对象和属性。
Window { visible: true width: 400 height: 300 title: qsTr("Animation") Rectangle { id: pageB color: "green" anchors.fill: parent } Rectangle { id: rect width: 100; height: 100 color: "red" PropertyAnimation { id: animation duration: 1000 } MouseArea { anchors.fill: parent onClicked: { animation.target = rect animation.properties = "x,y" animation.to = 50 animation.start() } } } }
一个独立的动画对象默认是没有运行的,必须使用running属性或者start()和stop()函数来明确地运行它。因为动画没有绑定到一个特殊得对象或属性上,所以必须定义target和property(或者targets和properties)属性的值。也需要用to属性来指定新的x和y值。对于动画在不是一对一对象属性进行动画而且动画需要明确开始和停止的情况下是非常有用的。
动画元素
所有的动画都继承自Animation元素,尽管无法直接创建Animation对象,不过它为动画元素提供了必要的属性和函数。它允许使用running属性和start()和stop()函数来控制动画的开始和停止,也可以通过loops属性定义动画的循环次数。
PropertyAnimation是用来为属性提供动画的最基本的动画元素,可以用来为real、int、color、rect、point、size和vector3d等属性设置动画,被NumberAnimation、colorAnimation、RotationAnimation和Vector3dAnimation等元素继承。NumberAnimation对real和int属性提供了更高效的实现;Vector3dAnimation对vector3d属性提供了更高效的支持;而ColorAnimation和RotationAnimation分别对color和rotation属性变化动画提供了特定的属性支持。
1. ColorAnimation允许颜色值设置from和to属性。
Rectangle { id: rect width: 100; height: 100 color: "green" // 启动运行,由绿色变为红色 ColorAnimation on color { from: "green"; to: "red"; duration: 1000 } }
2. RotationAnimation允许设定旋转的方向。
Rectangle { id: rect width: 100; height: 100 color: "red" anchors.centerIn: parent // 启动运行,顺时针旋转90° RotationAnimation on rotation { to: 90; duration: 1000; direction: RotationAnimation.Clockwise } }
3. SmoothedAnimation: 它是一个专门的NumberAnimation,当目标值改变时在动画中为其提供了一个平滑的变化;
4. SpringAnimation: 提供了一个像弹簧一样的动画,可以设置mass、damping和epsilon等属性
5. ParentAnimation: 用来在改变父项目时产生动画(对应ParentChange元素)
6. AchorAnimation: 用来在改变锚时产生动画(对应AnchorChanges元素)
对于任何基于PropertyAnimation的动画都可以通过设置easing属性来控制在属性值动画中使用的缓和曲线。它们可以影响这些属性值的动画效果,提供一些如反弹、加速和减速等视觉效果。OutBounce来创建一个动画到达目标值时的反弹效果。
组合动画
多个动画可以组合成一个单一的动画,这可以使用ParallelAnimation或者SequentialAnimation动画组元素中的一个实现。在ParallelAnimation中的动画会同时进行,而在SequentialAnimation中的动画会一个个地运行。想要运行多个动画,可以在一个动画组中定义。以下代码分别表示串行动画和并行动画。
Window { visible: true width: 400 height: 300 title: qsTr("Animation") Rectangle { id: pageB color: "green" anchors.fill: parent } Rectangle { id: rect width: 100 height: 100 color: "red" // 串行动画 SequentialAnimation { id: animation // NumberAnimation { target: rect properties: "x,y" to: 50 duration: 1000 } ColorAnimation { target: rect properties: "color" to: "blue" duration: 1000 } } MouseArea { anchors.fill: parent onClicked: animation.start() } } }
Window { visible: true width: 400 height: 300 title: qsTr("Animation") Rectangle { id: pageB color: "green" anchors.fill: parent } Rectangle { id: rect width: 100 height: 100 color: "red" // 串行动画 ParallelAnimation { id: animation // NumberAnimation { target: rect properties: "x,y" to: 50 duration: 1000 } ColorAnimation { target: rect properties: "color" to: "blue" duration: 1000 } } MouseArea { anchors.fill: parent onClicked: animation.start() } } }
其他动画元素
QML还为动画提供了其他一些有用的元素
1. PauseAnimation: 在动画中间进行暂停
2. ScriptAnimation: 允许在动画中执行JavaScript,也可以和StateChangeScript一起使用来重用已经存在的脚本
原文地址:https://www.cnblogs.com/yccheng/p/9732589.html