1 QML Animation

上述两个章节都是用Qt Widget + C++实现的动画,在Qt Quick中,可以仅仅使用QML实现动画,不需要C++的参与(C++只负责后台,不负责GUI绘制)。

1.1 QML动画类别

在QML中,有8中不同的动画类别,需要添加动画时直接在qml文件中添加,不需要到C++代码文件添加操作:

  • Anchor animation: Animates changes in anchor values
  • Color animation: Animates changes in color values
  • Number animation: Animates changes in qreal-type values
  • Parent animation: Animates changes in parent values
  • Path animation: Animates an item along a path
  • Property animation: Animates changes in property values
  • Rotation animation: Animates changes in rotation values
  • Vector3d animation: Animates changes in QVector3D values

在qml中,这个动画类型都是属性层别的,可以针对同一个控件的不同属性设置不同的动画效果

1.2 color animation示例

  1. Rectangle{
  2. id:background;
  3. anchors.fill: parent;
  4. color: "blue";
  5. SequentialAnimation on color {
  6. ColorAnimation { to: "yellow"; duration: 1000 }
  7. ColorAnimation { to: "red"; duration: 1000 }
  8. ColorAnimation { to: "blue"; duration: 1000 }
  9. loops: Animation.Infinite;
  10. }
  11. }

在上面qml中,我们加入了一个color属性上的的顺序动画SequentialAnimation,依次变换颜色,动画不停循环,显示效果如下:
1.gif

1.3 number animation示例

  1. Text {
  2. id: txt;
  3. text: qsTr("Hello World");
  4. anchors.centerIn: parent;
  5. color: "white";
  6. font.pointSize: 15;
  7. SequentialAnimation on opacity {
  8. NumberAnimation { to: 0.0; duration: 1000}
  9. NumberAnimation { to: 1.0; duration: 1000}
  10. loops: Animation.Infinite;
  11. }
  12. }

在上面qml中,我们加入了一个opacity(透明度)属性上的顺序动画,透明度从1到0再到1,动画不停循环。效果如下:
1.gif

1.4 state machine示例

和C++的实现类似,也需要三个部分的操作,只不过全都是在qml中定义的:

  1. Rectangle{
  2. id:background;
  3. anchors.fill: parent;
  4. color: "blue";
  5. //1.add state machine
  6. states: [
  7. State {
  8. name: "PRESSED"
  9. PropertyChanges { target: background; color: "blue" }
  10. },
  11. State {
  12. name: "RELEASED"
  13. PropertyChanges { target: background; color: "red" }
  14. }
  15. ]
  16. //2.add animation transition
  17. transitions: [
  18. Transition {
  19. from: "PRESSED"
  20. to: "RELEASED"
  21. ColorAnimation { target: background; duration: 1000}
  22. },
  23. Transition {
  24. from: "RELEASED"
  25. to: "PRESSED"
  26. ColorAnimation { target: background; duration: 1000}
  27. }
  28. ]
  29. //3.bind the event to the state change
  30. MouseArea{
  31. anchors.fill: parent;
  32. onPressed: background.state = "PRESSED";
  33. onReleased: background.state = "RELEASED";
  34. }
  35. }

上面qml实现的效果如下:
1.gif

1.5 Easing curve in qml

  1. //可以添加在任何一个animation type中
  2. easing.type: Easing.InOutElastic;
  3. easing.amplitude: 2.0;
  4. easing.period: 1.5;

1.6 QML Animator

Animator是直接在Qt Quick的场景中操作的动画类型。它不像一般的动画和QML组件那样,当UI线程阻塞的时候,动画渲染线程也阻塞。这个类型的属性值,在动画运行的时候,不会发生变化。只有当动画运行完毕,其属性才会更新。我们可以像使用其它动画类型那样去使用它。
QT中包括如下具体的类型:OpacityAnimator, RotationAnimator, ScaleAnimator, UniformAnimator, XAnimator, and YAnimator

使用示例,和其他qml动画可以放在一个group中,而且格式没有太大差别:

  1. Rectangle{
  2. id:myBox;
  3. anchors.horizontalCenter: parent.horizontalCenter;
  4. anchors.verticalCenter: parent.verticalCenter;
  5. width: 50;
  6. height: 50;
  7. color: "blue";
  8. ParallelAnimation {
  9. ColorAnimation {
  10. target: myBox
  11. property: "color"
  12. from: "forestgreen"
  13. to: "lightsteelblue";
  14. duration: 1000
  15. }
  16. ScaleAnimator {
  17. target: myBox
  18. from: 2
  19. to: 1
  20. duration: 1000
  21. }
  22. running: true
  23. }
  24. }

动画效果如下:
1.gif

1.7 sprite animation

精灵图又叫帧动画,采用一张大图的形式来保存一个角色的所有帧信息(游戏中经常用)。Qt Quick可以将帧动画生成动画的形式(CSS也可以),需要用到AnimatedSprite:
一个帧动画的例子:
image.png

  1. AnimatedSprite {
  2. id: sprite;
  3. width: 128;
  4. height: 128;
  5. source: "qrc:/horse_1.png";
  6. frameCount: 11; //帧数
  7. frameWidth: 128;
  8. frameHeight: 128;
  9. frameRate: 25;
  10. loops: Animation.Infinite;
  11. running: true;
  12. NumberAnimation {//添加平移动画,x坐标移动
  13. target: sprite;
  14. property: "x";
  15. from: -128;
  16. to: 512;
  17. duration: 3000;
  18. loops: Animation.Infinite;
  19. running: true;
  20. }
  21. }
  22. MouseArea {
  23. anchors.fill: parent
  24. onClicked: {//控制sprite的暂停
  25. if (sprite.paused)
  26. sprite.resume();
  27. else
  28. sprite.pause();
  29. }
  30. }

帧动画动起来之后是这样的:
1.gif