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 对象需要指定特定的 targetproperties 值来指定应该被动画化的对象和属性。这可以通过使用 on 语法来避免,该语法指定动画将作为 属性值源 应用。

以下是使用此语法指定的两个PropertyAnimation对象:

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

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

由于SequentialAnimation对象已使用 on 语法在color属性上指定,其子ColorAnimation对象也会自动应用于此属性,并且不需要指定targetproperty动画值。

状态变化期间的过渡

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

Transition 类型可以包含动画类型,用于插值由状态变化引起的属性变化。要将过渡分配给对象,请将其绑定到 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类型中声明的动画适用于属性,并对任何属性值变化进行动画处理。然而,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 声明是一种将行为动画分配给属性的便捷方式。

请参阅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中,它们就不能再独立启动和停止了。顺序或并行动画必须作为一个组来启动和停止。

SequentialAnimation 类型对于播放过渡动画也非常有用,因为动画在过渡中是并行播放的。

控制动画

有多种方法可以控制动画。

动画播放

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

缓动

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

一个QML对象可能对每个属性动画有不同的缓动曲线。还有不同的参数来控制曲线,其中一些是特定曲线独有的。有关缓动曲线的更多信息,请访问easing文档。

缓动示例直观地展示了每种不同的缓动类型。

其他动画类型

此外,QML 提供了几种其他对动画有用的类型:

这些是专门用于动画化不同属性类型的动画类型

共享动画实例

不支持在Transitions或Behaviors之间共享动画实例,这可能导致未定义的行为。在以下示例中,对Rectangle位置的更改很可能不会正确地进行动画处理。

最简单的解决方法是重复NumberAnimation给两个行为。如果重复的动画相当复杂,你也可以考虑创建一个自定义动画组件,并为每个行为分配一个实例,例如:

另请参阅

Qt Quick 示例 - 动画