Qt Quick 中的动画和过渡#

Qt Quick 中的动画系统

动画和过渡类型#

基于数据类型动画属性的类型

qml-qtquick-parentanimation.html

动画父值的变化。

qml-qtquick-anchoranimation.html

动画锚值的变化。

qml-qtquick-pathanimation.html

沿着路径动画项目。

qml-qtquick-coloranimation.html

动画颜色值的变化。

qml-qtquick-numberanimation.html

动画 qreal 类型的值的变化。

qml-qtquick-vector3danimation.html

动画 QVector3d 值的变化。

qml-qtquick-rotationanimation.html

动画旋转值的变化。

qml-qtquick-propertyanimation.html

动画属性值的变化。

通过将动画类型应用于属性值来创建动画。动画类型将通过插值属性值来创建平滑过渡。此外,状态过渡也可以为状态更改分配动画。

要创建动画,请使用适当的动画类型,适用于要动画化的属性的类型,并根据所需行为类型应用动画。

触发动画#

有几种方法可以为对象设置动画。

直接属性动画#

通过将动画对象应用于属性值并在一段时间内逐步更改属性创建动画。这些 属性动画 通过在属性值更改之间插值值来应用平滑移动。属性动画提供时间控制,并通过 加减速曲线 允许不同的插值。

Rectangle {
    id: flashingblob
    width: 75; height: 75
    color: "blue"
    opacity: 1.0

    MouseArea {
        anchors.fill: parent
        onClicked: {
            animateColor.start()
            animateOpacity.start()
        }
    }

    PropertyAnimation {id: animateColor; target: flashingblob; properties: "color"; to: "green"; duration: 100}

    NumberAnimation {
        id: animateOpacity
        target: flashingblob
        properties: "opacity"
        from: 0.99
        to: 1.0
        loops: Animation.Infinite
        easing {type: Easing.OutBack; overshoot: 500}
   }
}

专用属性动画类型比《PropertyAnimation》类型实现更加高效。它们用于设置不同 QML 类型的动画,例如 intcolor 和旋转。同样,ParentAnimation 可以为父级变化动画。

有关不同动画属性的更多信息,请参阅《控制动画》部分。

使用预定义目标和属性#

在前面示例中,为了指定应该进行动画的对象和属性,需要指定目标属性值,使用了PropertyAnimationNumberAnimation对象。可以通过使用<Animation> on <Property>语法来避免这种情况,该语法指定动画应作为属性值源应用。

以下是以该语法指定了两个PropertyAnimation对象

动画在矩形加载时立即开始,并将自动应用于其 xy 值。由于使用了<Animation> on <Property>语法,因此不需要为PropertyAnimation对象设置rect的目标值,也不需要将xy设置为属性值。

这也可以用于分组动画,以确保组内的所有动画都应用于相同的属性。例如,前面示例可以使用SequentialAnimation先动画化矩形的颜色为黄色,然后变为蓝色。

由于在color属性上已使用<Animation> on <Property>语法指定了SequentialAnimation对象,因此其子ColorAnimation对象也自动应用于该属性,并且不需要指定目标属性动画值。

状态变化期间的过渡#

Qt Quick 状态是属性配置,其中一个属性可能具有不同的值以反映不同的状态。状态变化引入突兀的属性变化;动画通过平滑过渡来产生视觉上吸引人的状态变化。

过渡类型可以包含动画类型来插值由状态变化引起的属性更改。要将过渡分配给对象,请将其绑定到transitions属性。

按钮可能有两个状态,即用户点击按钮时的按下状态,以及用户释放按钮时的释放状态。我们可以为每种状态分配不同的属性配置。从按下状态到释放状态的转换可以通过动画实现。同样,从释放状态到按下状态的转换也会有动画效果。

Rectangle {
    width: 75; height: 75
    id: button
    state: "RELEASED"

    MouseArea {
        anchors.fill: parent
        onPressed: button.state = "PRESSED"
        onReleased: button.state = "RELEASED"
    }

    states: [
        State {
            name: "PRESSED"
            PropertyChanges { target: button; color: "lightblue"}
        },
        State {
            name: "RELEASED"
            PropertyChanges { target: button; color: "lightsteelblue"}
        }
    ]

    transitions: [
        Transition {
            from: "PRESSED"
            to: "RELEASED"
            ColorAnimation { target: button; duration: 100}
        },
        Transition {
            from: "RELEASED"
            to: "PRESSED"
            ColorAnimation { target: button; duration: 100}
        }
    ]
}

tofrom属性绑定到状态名,将特定的转换分配给状态切换。对于简单或对称的转换,将to属性设置为通配符“*”,表示该转换适用于任何状态切换。

transitions:
    Transition {
        to: "*"
        ColorAnimation { target: button; duration: 100}
    }

默认动画作为行为#

默认属性动画是通过使用行为动画来设置的。在行为类型中声明的动画应用于属性,并动画化任何属性值的变化。但是,Behavior类型有一个enabled属性,可以用来有目的地启用或禁用行为动画。

球组件可能对其xycolor属性分配行为动画。行为动画可以设置为模拟弹性效果。实际上,这种行为动画会在球移动时应用于属性。

Rectangle {
    width: 75; height: 75; radius: width
    id: ball
    color: "salmon"

    component BounceAnimation : NumberAnimation {
       easing {
          type: Easing.OutElastic
          amplitude: 1.0
          period: 0.5
       }
    }

    Behavior on x {
        BounceAnimation {}
    }
    Behavior on y {
        BounceAnimation {}
    }
    Behavior on color {
        ColorAnimation { target: ball; duration: 100 }
    }
}

有几种方法可以将行为动画分配给属性。使用Behavior on <property>声明是为属性分配行为动画的一种方便的方法。

请参阅Qt Quick 示例 - 动画,以了解行为动画的演示。

并行或顺序播放动画#

动画可以并行按顺序运行。并行动画将在同一时间播放一组动画,而顺序动画将按顺序播放一组动画:一个接一个地。将动画分组到SequentialAnimationParallelAnimation中,将按顺序或并行播放动画。

一个横幅组件可能需要依次显示多个图标或标语。使用opacity属性可以将其转换为1.0,表示不透明物体。使用SequentialAnimation类型,不透明度的动画将在前面的动画结束后播放。使用ParallelAnimation类型,动画将同时播放。

Rectangle {
    id: banner
    width: 150; height: 100; border.color: "black"

    Column {
        anchors.centerIn: parent
        Text {
            id: code
            text: "Code less."
            opacity: 0.01
        }
        Text {
            id: create
            text: "Create more."
            opacity: 0.01
        }
        Text {
            id: deploy
            text: "Deploy everywhere."
            opacity: 0.01
        }
    }

    MouseArea {
        anchors.fill: parent
        onPressed: playbanner.start()
    }

    SequentialAnimation {
        id: playbanner
        running: false
        NumberAnimation { target: code; property: "opacity"; to: 1.0; duration: 200}
        NumberAnimation { target: create; property: "opacity"; to: 1.0; duration: 200}
        NumberAnimation { target: deploy; property: "opacity"; to: 1.0; duration: 200}
    }
}

一旦将个别动画放入SequentialAnimationParallelAnimation中,就再不能独立启动和停止它们了。顺序或并行动画必须作为一个组启动和停止。

顺序动画类型也非常有用,因为动画可以在转换内部并行播放 转换动画

控制动画#

控制动画有多种方法。

动画播放#

所有动画类型都继承自 Animation 类型。无法创建 Animation 对象;相反,此类型为动画类型提供基本属性和方法。动画类型具有 start()stop()resume()pause()restart()complete() – 所有这些方法都控制动画的执行。

缓和#

缓和曲线定义了动画如何优化起始值和结束值之间的插值。不同的缓和曲线可能超出定义的插值范围。缓和曲线简化了动画效果的创建,例如弹跳效果、加速、减速和循环动画。

一个 QML 对象可以具有不同的缓和曲线来动画化每个属性。还有不同的参数来控制曲线,其中一些是特定于某个曲线的。有关缓和曲线的更多信息,请参阅 easing 文档。

缓和示例直观地演示了每种不同的缓和类型。

其他动画类型
  • PauseAnimation : 允许在动画中暂停

  • ScriptAction : 允许在动画期间执行 JavaScript,可以与 StateChangeScript 一起使用以重用现有脚本

  • PropertyAction : 在动画期间立即改变属性,而无需动画化属性更改