C

动画和过渡

动画和过渡类型

根据数据类型动态属性的类型

颜色动画

动态颜色值的变化

数字动画

动态虚类型值的变化

属性动画

动态属性值的变化

旋转动画

动态旋转值的变化

通过将动画类型应用于属性值来创建动画。动画类型将插值属性值以创建平滑的过渡。此外,状态过渡还可以将动画分配给状态变化。

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

触发动画

设置动画到对象的方式有很多。

直接属性动画

动画是通过将动画对象应用于属性值来创建的,以在一段时间内逐渐更改属性。这些 属性动画 通过在属性值变化之间插值来应用平滑的运动。属性动画提供定时控制,并允许通过 减速曲线 进行不同插值。

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.5
        to: 1.0
        loops: Animation.Infinite
        easing {type: Easing.OutQuad}
   }
}

专门的属性动画类型比 PropertyAnimation 类型的实现更有效。它们用于设置不同 QML 类型的动画,例如 intcolor 和旋转。

控制动画 部分了解更多有关不同动画属性的信息。

使用预定义的目标和属性

在上一例中,需要指定特定属性动画数字动画对象的目标属性值来指定要动画化的对象和属性。通过使用<Animation> on <Property>语法可以避免这种情况,该语法指定动画将作为属性值来源应用。

以下是使用此语法指定的两个属性动画对象。

import QtQuick 2.15

Rectangle {
    id: rect
    width: 100; height: 100
    color: "red"

    PropertyAnimation on x { to: 100 }
    PropertyAnimation on y { to: 100 }
}

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

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

import QtQuick 2.15

Rectangle {
    width: 100; height: 100
    color: "red"

    SequentialAnimation on color {
        ColorAnimation { to: "yellow"; duration: 1000 }
        ColorAnimation { to: "blue"; duration: 1000 }
    }
}

由于已在color属性上使用<Animation> on <Property>语法指定了顺序动画对象,因此其子颜色动画对象也自动应用于此属性,无需指定目标属性动画值。

状态变化期间的过渡

状态是属性配置,其中属性可能具有不同的值来反映不同的状态。状态更改会引入突发的属性变化;动画则平滑过渡以产生视觉上吸引人的状态变化。

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

按钮可能有两个状态:当用户单击按钮时的pressed状态和当用户释放按钮时的released状态。我们可以为每个状态分配不同的属性配置。过渡将动画化从pressed状态到released状态的变化。同样,当从released状态变为pressed状态时,也会有动画发生。

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}
        }

默认动画作为行为

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

球组件可能被分配了其 xycolor 属性的行为动画。此行为动画可以被设置为模拟弹性效果。实际上,当球移动时,这种行为动画会应用于这些属性,使其产生弹性效果。

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

    Behavior on x {
        NumberAnimation {
            id: bouncebehavior
            easing {
                type: Easing.OutSine
            }
        }
    }
    Behavior on y {
        animation: bouncebehavior
    }
    Behavior {
        ColorAnimation { target: ball; duration: 100 }
    }
}

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

并行或顺序播放动画

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

横幅组件可能显示几个图标或口号,一个接一个。使用 SequentialAnimation 类型,在不透明对象 1.0 转换的 opacity 属性动画会在前一个动画完成后播放。使用 ParallelAnimation 类型将同时播放这些动画。

Rectangle {
    id: banner

    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() 方法 -- 这些方法控制动画的执行。

缓动

缓动曲线定义动画如何从起始值插值到终止值。不同的缓动曲线可能会超出插值定义的范围。缓动曲线简化了动画效果的创建,比如弹跳效果、加速度、减速度和循环动画。

QML对象可以为每个属性动画指定不同的缓动曲线。也有不同的参数来控制曲线,其中一些参数仅适用于特定曲线。有关缓动曲线的更多信息,请访问 easing 文档。

其他动画类型

除了这些,QML还提供了其他几种对动画有用的类型

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

共享动画实例

在转换或行为之间共享动画实例不受支持,可能引发未知行为。在以下示例中,更改正方形位置的动画可能无法正确执行。

Rectangle {
    // NOT SUPPORTED: this will not work correctly as both Behaviors
    // try to control a single animation instance
    NumberAnimation { id: anim; duration: 300; easing.type: Easing.InBack }
    Behavior on x { animation: anim }
    Behavior on y { animation: anim }
}

最简单的修复方法是重复NumberAnimation用于两种行为。如果重复的动画相当复杂,您还可以考虑创建自定义动画组件,并为每个行为分配一个实例,例如

// MyNumberAnimation.qml
NumberAnimation { id: anim; duration: 300; easing.type: Easing.InBack }
// main.qml
Rectangle {
    Behavior on x { MyNumberAnimation {} }
    Behavior on y { MyNumberAnimation {} }
}

在某些Qt许可下提供。
了解更多信息。