• 《快速掌握QML》第六章 动画


    目录

    6.1 各种动画元素

    6.2 缓动曲线

    6.3 动画分组

    6.4 本章小结


    QML提供了一个强大的动画框架,其中包含很多动画元素,我们可以使用这些动画元素让界面拥有酷炫的动态效果。

    6.1 各种动画元素

    QML提供了各种动画元素用来实现不同的动画效果,笔者这里列举一些常用的元素:

    • PropertyAnimation:属性动画,通过改变某个元素属性来实现动画效果。
    • NumberAnimation:数字动画,是PropertyAnimation的派生元素,专门用来改变数字类型的属性。
    • ColorAnimation:颜色动画,是PropertyAnimation的派生元素,专门用来改变color类型的属性。
    • RotationAnimation:旋转动画,是PropertyAnimation的派生元素,专门用来改变rotation属性。
    • PauseAnimation:暂定动画,用于执行一段暂定动画。
    • PathAnimation:路径动画,让某个元素沿着自定义的路径运动。
    • SpringAnimation:弹簧动画,用于执行一段弹簧动画。
    • AnchorAnimation:锚定动画,通过改变锚点属性的值来实现移动动画。

    所有动画元素的基类都是Animation,我们来看下它内置的一些属性、信号和方法。

    属性

    • alwaysRunToEnd:属性值为true或者false,当设置为true时,即便主动调用stop()或者将running值设置为false,动画也会运行完毕。
    • loops:该属性值用来设置动画的循环次数,默认值是1,可以设置为Animation.Infinite表示无限循环动画。
    • paused:属性值为true或者false,表示动画是否处于暂停状态。true则为暂停。
    • running:属性值为true或者false,默认是false。如果设置为true,动画就会启动,反之则停止动画。我们可以在脚本中读取该属性的值,并通过该值判断动画是否正在运行。

    信号

    • finished():该信号会在动画播放结束后发射。
    • started():该信号会在动画开始时发射。
    • stopped():该信号会在动画停止时发射(手动调用stop()方法或者播放完毕后都会发射)。

    方法

    • complete():让动画结束,并跳到最后一帧。
    • pause():暂停动画。
    • restart():重新运行动画。
    • resume():继续播放动画。
    • start():开始动画。
    • stop():停止动画。

    我们现在拿PropertyAnimation举个例子,请看以下示例代码。

    1. import QtQuick 2.0
    2. import QtQuick.Controls 2.0
    3. Rectangle {
    4. id: root
    5. width: 300
    6. height: 200
    7. color: "black"
    8. PropertyAnimation {
    9. id: anim
    10. target: root // 1
    11. property: "color" // 2
    12. to: "white" // 3
    13. duration: 1000 // 4
    14. }
    15. Button {
    16. id: btn
    17. text: "运行"
    18. anchors.centerIn: root
    19. onClicked: {
    20. anim.running = true // 5
    21. }
    22. }
    23. }

    运行结果:

    代码解释:

    1. target属性填写要应用动画的目标元素。

    2. property属性填写要修改的目标元素属性。

    3. to属性填写动画运行时的目标值。

    4. duration属性填写动画执行所需时间,单位是毫秒。

    5. 将PropertyAnimation元素的running属性修改为true,运行动画。我们也可以将这行代码替换成anim.start(),这样点击按钮后,动画也会执行。

    有时候会看到这种Animation on 的写法,用这种写法的话我们可以把动画元素直接写进目标元素花括号内,不需要再编写target属性。我们把上面的代码修改下。

    1. import QtQuick 2.0
    2. import QtQuick.Controls 2.0
    3. Rectangle {
    4. id: root
    5. width: 300
    6. height: 200
    7. color: "black"
    8. PropertyAnimation on color{
    9. id: anim
    10. to: "white"
    11. duration: 1000
    12. running: false // 1
    13. }
    14. Button {
    15. id: btn
    16. text: "运行"
    17. anchors.centerIn: root
    18. onClicked: {
    19. anim.running = true
    20. }
    21. }
    22. }

    代码解释:

    1. 使用Animation on 这种写法时,running属性默认是true,也就是说程序运行后动画会立即执行,所以我们这里先将running设置为false。

    到目前为止,示例代码只是修改了一个元素的一种属性,如果我们要想修改多个元素的多种属性,只用将target和property属性写成英文复数形式:targets和properties。如下方代码所示。

    1. import QtQuick 2.0
    2. Rectangle {
    3. id: root
    4. width: 300
    5. height: 200
    6. color: "white"
    7. Rectangle {
    8. id: rect1
    9. x: 20
    10. y: 20
    11. width: 50
    12. height: 50
    13. color: "green"
    14. }
    15. Rectangle {
    16. id: rect2
    17. x: 150
    18. y: 20
    19. width: 50
    20. height: 50
    21. color: "blue"
    22. }
    23. PropertyAnimation {
    24. id: anim
    25. targets: [rect1, rect2] // 1
    26. properties: "width,height" // 2
    27. to: 80
    28. duration: 1000
    29. running: true
    30. }
    31. }

    运行结果:

    代码解释:

    1. targets属性设置为rect1和rect2,表示要将动画应用到这两个元素上。

    2. properties属性设置为"width,height",表示要修改width和height这两个属性,多个属性之间用逗号隔开。

    注:这种写法虽然能够改变多个属性的值,不过被修改的属性的最终值只能是一样的,因为to只能设置成一个值。

    6.2 缓动曲线

    不同的缓动曲线可以让同一种动画在运行时产生不同的效果,我们可以通过修改动画元素的easing.type(缓动种类)属性来改变动画的缓动值。动画的默认缓动值是Easing.Linear,其他可选值请访问该链接。我们现在通过一个示例来了解下缓动曲线,请看下方示例代码。

    1. import QtQuick 2.0
    2. Rectangle {
    3. id: root
    4. width: 300
    5. height: 200
    6. color: "white"
    7. Rectangle {
    8. id: rect
    9. x: 0
    10. y: 75
    11. width: 50
    12. height: 50
    13. color: "red"
    14. }
    15. NumberAnimation { // 1
    16. id: anim
    17. target: rect
    18. property: "x"
    19. to: 250
    20. duration: 1000
    21. }
    22. MouseArea {
    23. anchors.fill: root
    24. onClicked: {
    25. anim.start()
    26. }
    27. }
    28. }

     运行结果:

     代码解释:

    1. 用NumberAnimation动画元素修改rect1矩形元素的位置。此时NumberAnimation的easing.type属性的值是Easing.Linear,所以矩形元素会从左到右匀速运动。如果我们往NumberAnimation代码块中添加如下代码,那矩形就会先快后慢再快地向右移动了。

    easing.type: Easing.OutInQuad

    除了easing.type,很多动画还有easing.amplitude(缓冲幅度)、easing.overshoot(缓冲溢出)、easing.period(缓冲周期)这些属性,我们可以通过这些属性来对缓冲曲线进行微调。

    不过这些微调属性都有使用的缓动曲线,easing.amplitude适用于弹跳或弹性曲线:

    • Easing.InBounce
    • Easing.OutBounce
    • Easing.InOutBounce
    • Easing.OutInBounce
    • Easing.InElastic
    • Easing.OutElastic
    • Easing.InOutElastic
    • Easing.OutInElastic

    easing.overshoot适用于:

    • Easing.InBack
    • Easing.OutBack
    • Easing.InOutBack
    • Easing.OutInBack

    easing.period适用于:

    • Easing.InElastic
    • Easing.OutElastic
    • Easing.InOutElastic
    • Easing.OutInElastic

    下方示例代码使用了Easing.InBounce这种缓动曲线,其中一个NumberAnimation使用了easing.amplitude属性对缓动进行微调。通过对比两个矩形元素的动画效果我们就可以看出这些微调属性的作用了。

    1. import QtQuick 2.0
    2. Rectangle {
    3. id: root
    4. width: 300
    5. height: 200
    6. color: "white"
    7. Rectangle {
    8. id: rect1
    9. x: 0
    10. y: 0
    11. width: 50
    12. height: 50
    13. color: "red"
    14. }
    15. Rectangle {
    16. id: rect2
    17. x: 0
    18. y: 150
    19. width: 50
    20. height: 50
    21. color: "blue"
    22. }
    23. NumberAnimation {
    24. id: anim1
    25. target: rect1
    26. property: "x"
    27. to: 250
    28. duration: 3000
    29. easing.type: Easing.InElastic
    30. }
    31. NumberAnimation {
    32. id: anim2
    33. target: rect2
    34. property: "x"
    35. to: 250
    36. duration: 3000
    37. easing.type: Easing.InBounce
    38. easing.amplitude: 2.0
    39. }
    40. MouseArea {
    41. anchors.fill: root
    42. onClicked: {
    43. anim1.start()
    44. anim2.start()
    45. }
    46. }
    47. }

    运行结果:

    6.3 动画分组

    动画分组有两个:SequentialAnimation串行动画分组和ParallelAnimation并行动画分组。它们同样是Animation的派生元素,前者会按照动画添加顺序依次执行各个动画,而后者会同时执行所有动画。请看下方示例代码。

    1. import QtQuick 2.0
    2. Rectangle {
    3. id: root
    4. width: 300
    5. height: 200
    6. color: "white"
    7. Rectangle {
    8. id: rect
    9. x: 0
    10. y: 75
    11. width: 50
    12. height: 50
    13. color: "red"
    14. }
    15. SequentialAnimation { // 1
    16. id: sequentialAnim
    17. NumberAnimation {
    18. target: rect
    19. property: "x"
    20. to: 250
    21. duration: 2000
    22. }
    23. ColorAnimation {
    24. target: rect
    25. property: "color"
    26. to: "blue"
    27. duration: 2000
    28. }
    29. RotationAnimation {
    30. target: rect
    31. property: "rotation"
    32. to: 360
    33. duration: 2000
    34. }
    35. NumberAnimation {
    36. target: rect
    37. property: "radius"
    38. to: 25
    39. duration: 2000
    40. }
    41. }
    42. MouseArea {
    43. anchors.fill: root
    44. onClicked: {
    45. sequentialAnim.start() // 2
    46. }
    47. }
    48. }

    运行结果:

    代码解释: 

    1. SequentialAnimation串行动画分组元素中包含四个动画元素,分别是:修改x属性的NumberAnimation、修改color属性的ColorAnimation、修改rotation属性的RotationAnimation以及修改radius属性的NumberAnimation。矩形元素会先运动到窗口右边,再从红色编程蓝色,再旋转360度,再从矩形变成圆形。

    2. 当点击窗口后,四个动画就会按照顺序依次执行。

    现在我们使用ParallelAnimation并行动画分组元素让四个动画同时执行,请看下方代码。

    1. import QtQuick 2.0
    2. Rectangle {
    3. id: root
    4. width: 300
    5. height: 200
    6. color: "white"
    7. Rectangle {
    8. id: rect
    9. x: 0
    10. y: 75
    11. width: 50
    12. height: 50
    13. color: "red"
    14. }
    15. ParallelAnimation {
    16. id: parallelAnim
    17. NumberAnimation {
    18. target: rect
    19. property: "x"
    20. to: 250
    21. duration: 2000
    22. }
    23. ColorAnimation {
    24. target: rect
    25. property: "color"
    26. to: "blue"
    27. duration: 2000
    28. }
    29. RotationAnimation {
    30. target: rect
    31. property: "rotation"
    32. to: 360
    33. duration: 2000
    34. }
    35. NumberAnimation {
    36. target: rect
    37. property: "radius"
    38. to: 25
    39. duration: 2000
    40. }
    41. }
    42. MouseArea {
    43. anchors.fill: root
    44. onClicked: {
    45. parallelAnim.start()
    46. }
    47. }
    48. }

    运行结果:

    代码解释:

    将SequentialAnimation改成ParallelAnimation,然后再修改下id名称就可以了。此时矩形元素会在向窗口右侧移动的同时改变颜色、旋转以及变成圆形。

    6.4 本章小结

    1. 动画元素的种类有很多,不过它们的用法是相似的,很多属性也一样。

    2. 缓动曲线可以让同种动画表现出不同效果,可以通过easing.type属性修改缓动类型。

    3. 如果想让一些动画按照顺序或者同时执行,可以将它们添加到SequentialAnimation或者ParallelAnimation动画分组中。

  • 相关阅读:
    乘风而起!企业级应用软件市场迅猛发展,有哪些机会可以把握?
    C++ | Leetcode C++题解之第35题搜索插入位置
    MBR15200FAC-ASEMI插件肖特基二极管MBR15200FAC
    安防视频/集中云存储平台EasyCVR(V3.3)部分通道显示离线该如何解决?
    乐观锁和悲观锁
    45 深度学习(九):transformer
    java计算机毕业设计项目任务跟踪系统源码+系统+mysql数据库+lw文档+部署
    【无标题】
    django框架基于Python实现的三甲医院网站
    使用 PPG(光电容积描记图)估计心率和 SpO2 水平(Matlab代码实现)
  • 原文地址:https://blog.csdn.net/La_vie_est_belle/article/details/125965778