QML开发:动画元素

一、动画元素的概述

  在 QML 中,动画(Animation)元素用来让对象的属性随时间平滑变化。它们不仅能提升界面观感,还能直观地表达状态变化。QML 动画系统是基于 Qt Quick Animation Framework 的,核心思想是驱动属性值在一段时间内变化,并支持缓动曲线、循环播放、并行或顺序执行等控制。

二、常用动画元素

1. PropertyAnimation(属性动画)

1.1 什么是 PropertyAnimation?
PropertyAnimation 用来让对象的任意属性在一段时间内从一个值平滑变化到另一个值。

  • 它是通用的属性动画,支持数值、颜色、坐标、尺寸等类型。
  • NumberAnimation、ColorAnimation 等就是它的子类,它们对特定类型做了简化。
  • 适合做“单属性变化”的动画,但目标属性必须是可写的(Property 不是 readonly)。

继承结构:

Animation
  └─ PropertyAnimation
       ├─ NumberAnimation
       ├─ ColorAnimation
       └─ RotationAnimation

1.2 基本语法

PropertyAnimation {
    target: 对象ID
    property: "属性名"
    from: 起始值
    to: 结束值
    duration: 持续时间(毫秒)
    easing.type: 缓动类型
}

常用属性说明:

  • target:动画作用的对象
  • targets:动画作用的多个对象(数组)
  • property:要修改的属性名(字符串)
  • from:动画起始值(可省略,默认取当前属性值)
  • to:动画结束值
  • duration:动画时间(毫秒)
  • easing.type:缓动曲线(如 Easing.OutBounce)
  • loops:循环次数,Animation.Infinite 表示无限循环
  • running:是否正在运行

1.3 基本示例
单次执行:

Rectangle {
    width: 300; height: 200; color: "lightgray"

    Rectangle {
        id: rect
        width: 50; height: 50; color: "red"
    }

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

    PropertyAnimation {
        id: anim
        target: rect
        property: "x"
        from: 0
        to: 200
        duration: 1000
        easing.type: Easing.OutBounce
    }
}

无限循环动画:

Rectangle {
    width: 300; height: 200; color: "lightyellow"

    Rectangle {
        id: rect
        width: 50; height: 50; color: "blue"
    }

    PropertyAnimation {
        id: loopAnim
        target: rect
        property: "x"
        from: 0
        to: 200
        duration: 1000
        loops: Animation.Infinite
        easing.type: Easing.InOutQuad
        running: true // 自动开始
    }
}

同时作用多个对象:

Rectangle {
    width: 300; height: 200; color: "lightblue"

    Rectangle { id: r1; width: 30; height: 30; color: "red" }
    Rectangle { id: r2; width: 30; height: 30; color: "green"; y: 50 }

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

    PropertyAnimation {
        id: anim
        targets: [r1, r2]
        property: "x"
        from: 0
        to: 250
        duration: 800
    }
}

结合 Behavior 自动播放:

Rectangle {
    width: 300; height: 200; color: "lightgray"

    Rectangle {
        id: rect
        width: 50; height: 50; color: "orange"

        Behavior on x {
            PropertyAnimation { duration: 600; easing.type: Easing.InOutQuad }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: rect.x = rect.x === 0 ? 200 : 0
    }
}

2.NumberAnimation(数字动画)

2.1 什么是 NumberAnimation?
  NumberAnimation 是 PropertyAnimation 的特化版本,专门针对数值类型属性(int、real 等)做动画。

它的特点是:

  • 语法简洁,不用指定动画类型就能自动识别为数字插值。
  • 常用于 x、y、width、height、opacity、rotation 等属性。
  • 支持缓动曲线、循环、自动开始等功能。

继承关系:

Animation
  └─ PropertyAnimation
       └─ NumberAnimation

2.2 基本语法

NumberAnimation {
    target: 对象ID
    property: "属性名"
    from: 起始值
    to: 结束值
    duration: 持续时间(毫秒)
    easing.type: 缓动曲线类型
}

常用属性:

  • target 要做动画的对象
  • targets 多个对象(数组形式)
  • property 动画作用的属性名
  • from 起始值(可省略,默认取当前属性值)
  • to 结束值
  • duration 动画持续时间(毫秒)
  • easing.type 缓动曲线(Easing.OutBounce 等)
  • loops 循环次数(Animation.Infinite 表示无限循环)
  • running 是否运行
  • alwaysRunToEnd 如果动画被打断,是否直接跳到结束值

2.3 常用缓动曲线

  • Easing.Linear:匀速
  • Easing.InQuad:开始慢加速
  • Easing.OutQuad:结束慢减速
  • Easing.InOutQuad:两头慢中间快
  • Easing.OutBounce:回弹效果
  • Easing.InOutElastic:弹性效果

2.4 基本示例
点击按钮执行一次:

Rectangle {
    width: 300; height: 200; color: "lightgray"

    Rectangle {
        id: rect
        width: 50; height: 50; color: "red"
    }

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

    NumberAnimation {
        id: anim
        target: rect
        property: "x"
        from: 0
        to: 200
        duration: 1000
        easing.type: Easing.OutBounce
    }
}

无限循环动画:

Rectangle {
    width: 300; height: 200; color: "lightyellow"

    Rectangle {
        id: rect
        width: 50; height: 50; color: "blue"
    }

    NumberAnimation {
        target: rect
        property: "x"
        from: 0
        to: 200
        duration: 800
        loops: Animation.Infinite
        running: true
        easing.type: Easing.InOutQuad
    }
}

同时作用多个对象:

Rectangle {
    width: 300; height: 200; color: "lightblue"

    Rectangle { id: r1; width: 30; height: 30; color: "red" }
    Rectangle { id: r2; width: 30; height: 30; color: "green"; y: 50 }

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

    NumberAnimation {
        id: anim
        targets: [r1, r2]
        property: "x"
        from: 0
        to: 250
        duration: 800
    }
}

Behavior 自动动画:

Rectangle {
    width: 300; height: 200; color: "lightgray"

    Rectangle {
        id: rect
        width: 50; height: 50; color: "orange"

        Behavior on x {
            NumberAnimation { duration: 600; easing.type: Easing.InOutQuad }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: rect.x = rect.x === 0 ? 200 : 0
    }
}

3.ColorAnimation(颜色动画)

3.1 ColorAnimation 是什么?
  ColorAnimation 是 QML 中的一个动画元素,用来在一段时间内平滑地改变一个对象的 颜色属性。它可以单独使用,也可以放在 Behavior 或 Transition 中自动触发。

常用于:

  • 背景颜色渐变
  • 鼠标悬停高亮
  • 状态切换时的颜色过渡

3.2 基本属性

  • from:动画的起始颜色
  • to:动画的结束颜色
  • duration:动画持续时间(毫秒)
  • loops:循环次数,Animation.Infinite 表示无限循环
  • running:是否正在运行
  • target:绑定动画作用的对象
  • property:指定要动画的属性(通常是 “color” 或 “background.color”)

3.3 基本示例
最简单的示例:

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 300
    height: 200
    color: "red"

    ColorAnimation {
        target: parent
        property: "color"
        from: "red"
        to: "blue"
        duration: 2000
        loops: Animation.Infinite
        running: true
    }
}

这个动画会让 Rectangle 在红色和蓝色之间来回切换;loops: Animation.Infinite 表示一直循环。

结合 Behavior 自动动画:

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 300
    height: 200
    color: "red"

    Behavior on color {
        ColorAnimation { duration: 500 }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: parent.color = parent.color === "red" ? "green" : "red"
    }
}

点击矩形,颜色会自动平滑过渡,而不是立即改变;Behavior 会在属性值变化时自动触发 ColorAnimation。

鼠标悬停高亮效果:

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 300
    height: 200
    color: "lightgray"

    Behavior on color {
        ColorAnimation { duration: 300 }
    }

    MouseArea {
        anchors.fill: parent
        hoverEnabled: true
        onEntered: parent.color = "yellow"
        onExited: parent.color = "lightgray"
    }
}

鼠标进入时背景变黄,离开时变回灰色,并且有动画过渡。

4.RotationAnimation(旋转动画)

4.1 RotationAnimation 是什么?
  RotationAnimation 是 QML 中的属性动画(PropertyAnimation) 之一,用于在一段时间内平滑改变对象的旋转角度。

它可以作用于:

  • rotation 属性(2D 旋转)
  • angle 属性(部分控件的旋转参数)
  • xRotation / yRotation / zRotation(3D 旋转)

4.2 主要属性

  • from:动画起始角度
  • to:动画结束角度
  • duration:动画时长(毫秒)
  • direction:旋转方向,RotationAnimation.Clockwise / RotationAnimation.Counterclockwise / RotationAnimation.Shortest
  • running:是否正在运行
  • loops:循环次数,Animation.Infinite 表示无限循环
  • target:绑定动画作用的对象
  • property:指定要动画的属性(通常是 “rotation”)

4.3 基本示例
不停旋转:

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 200
    height: 200
    color: "lightblue"

    Image {
        id: img
        anchors.centerIn: parent
        source: "qrc:/logo.png"
        width: 100
        height: 100
    }

    RotationAnimation {
        target: img
        property: "rotation"
        from: 0
        to: 360
        duration: 2000
        loops: Animation.Infinite
        direction: RotationAnimation.Clockwise
        running: true
    }
}

效果:图片会以顺时针方向不停旋转,每次一圈耗时 2 秒。

结合 Behavior 自动旋转:
如果希望 属性值变化时自动带旋转动画:

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 300
    height: 300
    color: "lightgray"

    Rectangle {
        id: box
        width: 100
        height: 100
        color: "orange"
        anchors.centerIn: parent

        Behavior on rotation {
            RotationAnimation { duration: 1000; direction: RotationAnimation.Shortest }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: box.rotation += 90
    }
}

效果:

  • 每次点击都会让矩形旋转 90°
  • 使用 Shortest 方向,让动画选择最近的旋转路径

与 SequentialAnimation / ParallelAnimation 结合:

SequentialAnimation {
    RotationAnimation { target: item; from: 0; to: 90; duration: 500 }
    RotationAnimation { target: item; from: 90; to: 180; duration: 500 }
}

总结:

  • RotationAnimation 适合做旋转动画,支持循环、方向控制
  • 2D 用 rotation,3D 用 xRotation/yRotation/zRotation
  • 配合 Behavior 可以实现属性变化时的自动旋转
  • 和 SequentialAnimation/ParallelAnimation 结合可以做复杂的旋转效果

5.PauseAnimation(停止动画)

5.1 PauseAnimation 是什么?
  PauseAnimation 是 QML 动画系统里的一个特殊动画类型,它本身不改变任何属性值,只是在动画序列中插入一个暂停时间。

常用于:

  • 在多个动画之间插入延时
  • 与 SequentialAnimation 结合实现“动 → 停 → 再动”的效果

5.2 主要属性

  • duration:暂停时长(毫秒)

5.3 基本用法示例

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 300
    height: 200
    color: "lightblue"

    Rectangle {
        id: box
        width: 50
        height: 50
        color: "orange"
        y: 75
    }

    SequentialAnimation {
        loops: Animation.Infinite
        running: true

        NumberAnimation { target: box; property: "x"; from: 0; to: 250; duration: 1000 }
        PauseAnimation { duration: 500 } // 停顿 0.5 秒
        NumberAnimation { target: box; property: "x"; from: 250; to: 0; duration: 1000 }
        PauseAnimation { duration: 500 } // 再停顿 0.5 秒
    }
}

与其他动画结合:
可以把 PauseAnimation 插到 SequentialAnimation、ParallelAnimation 中,例如:

SequentialAnimation {
    RotationAnimation { target: img; from: 0; to: 180; duration: 1000 }
    PauseAnimation { duration: 300 }
    RotationAnimation { target: img; from: 180; to: 360; duration: 1000 }
}

这样可以实现旋转一半 → 停顿 → 继续旋转的效果。

总结:

  • PauseAnimation 用来在动画序列中插入停顿时间
  • 不能单独运行(没有 target、property)
  • 常与 SequentialAnimation 结合实现节奏感动画
  • 不会改变属性值,只负责时间上的延迟

6.SequentialAnimation(顺序动画)

6.1 SequentialAnimation 是什么
SequentialAnimation 是 QML 中的动画容器,用来按顺序依次执行多个动画。

  • 动画按声明顺序从上到下依次运行
  • 一个动画执行完才会执行下一个
  • 可以包含 NumberAnimation、ColorAnimation、RotationAnimation、PauseAnimation 等各种动画

6.2 主要属性

  • running:是否运行动画(true/false)
  • loops:循环次数(Animation.Infinite 表示无限循环)
  • onStarted:动画开始时触发
  • onStopped:动画结束时触发

6.3 基本示例
最简单示例:

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 300
    height: 200
    color: "lightblue"

    Rectangle {
        id: box
        width: 50
        height: 50
        color: "orange"
        y: 75
    }

    SequentialAnimation {
        running: true
        loops: Animation.Infinite

        // 1. 向右移动
        NumberAnimation { target: box; property: "x"; from: 0; to: 250; duration: 1000 }

        // 2. 停顿 0.5 秒
        PauseAnimation { duration: 500 }

        // 3. 向左移动
        NumberAnimation { target: box; property: "x"; from: 250; to: 0; duration: 1000 }

        // 4. 停顿 0.5 秒
        PauseAnimation { duration: 500 }
    }
}

结合多种动画:

SequentialAnimation {
    running: true

    // 先移动
    NumberAnimation { target: rect; property: "x"; from: 0; to: 200; duration: 1000 }

    // 再变色
    ColorAnimation { target: rect; property: "color"; from: "red"; to: "blue"; duration: 500 }

    // 最后旋转
    RotationAnimation { target: rect; property: "rotation"; from: 0; to: 360; duration: 1000 }
}

7.ParallelAnimation(并行动画)

7.1 ParallelAnimation 是什么
ParallelAnimation 是 QML 中的动画容器,用来同时执行多个动画。

  • 它会让所有子动画一起开始执行
  • 动画之间互不等待,最长的动画结束后才算整个 ParallelAnimation 完成
  • 常和 SequentialAnimation 配合,先并行执行一组动画,再执行下一步

7.2 主要属性

  • running:是否运行动画(true/false)
  • loops:循环次数(Animation.Infinite 表示无限循环)
  • onStarted:动画开始时触发
  • onStopped:动画结束时触发

7.3 基本示例
最简单示例:

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 300
    height: 200
    color: "lightblue"

    Rectangle {
        id: box
        width: 50
        height: 50
        color: "orange"
        y: 75
    }

    ParallelAnimation {
        running: true
        loops: Animation.Infinite

        // 同时移动
        NumberAnimation { target: box; property: "x"; from: 0; to: 250; duration: 1000 }

        // 同时变色
        ColorAnimation { target: box; property: "color"; from: "orange"; to: "blue"; duration: 1000 }

        // 同时旋转
        RotationAnimation { target: box; property: "rotation"; from: 0; to: 360; duration: 1000 }
    }
}

效果:方块会同时向右移动、颜色变蓝并旋转 360°,动画结束后循环执行。

组合使用示例:

SequentialAnimation {
    // 第一步:放大 + 变色
    ParallelAnimation {
        NumberAnimation { target: box; property: "scale"; from: 1; to: 2; duration: 500 }
        ColorAnimation { target: box; property: "color"; from: "orange"; to: "green"; duration: 500 }
    }

    // 第二步:旋转
    RotationAnimation { target: box; property: "rotation"; from: 0; to: 360; duration: 1000 }
}

效果:先放大并变色(同时进行),然后旋转一圈。

8.AnchorAnimation(锚定动画)

8.1 AnchorAnimation 是什么?
  AnchorAnimation 是 QML 中专门用于平滑过渡锚点(anchors)变化的动画类型。当你用 QML 的锚定布局(anchors.top, anchors.left, anchors.centerIn 等)改变 UI 布局时,如果没有动画,元素会瞬间跳到新位置。AnchorAnimation 能让这个位置变化平滑地移动过去。

核心特点:

  • 只对 anchors 生效(如 anchors.left, anchors.right, anchors.top, anchors.horizontalCenter 等)
  • 不能单独使用,必须和状态切换(State)或 Transition 配合
  • 不能直接对 x/y 属性生效(那要用 NumberAnimation)

8.2 主要属性

  • duration:动画时长(毫秒)
  • easing:缓动曲线(Easing.InOutQuad、Easing.Linear 等)

8.3 基本用法
最常见用法是放在 Transition 里,让状态切换时锚点位置平滑过渡:

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 400
    height: 200
    color: "lightblue"

    Rectangle {
        id: box
        width: 80
        height: 80
        color: "orange"
        anchors.verticalCenter: parent.verticalCenter
        anchors.left: parent.left
    }

    states: [
        State {
            name: "right"
            AnchorChanges {
                target: box
                anchors.left: undefined
                anchors.right: parent.right
            }
        }
    ]

    transitions: [
        Transition {
            AnchorAnimation { duration: 800; easing.type: Easing.InOutQuad }
        }
    ]

    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (parent.state === "")
                parent.state = "right"
            else
                parent.state = ""
        }
    }
}

效果:点击背景,橙色方块会从左边平滑移动到右边,再点击,会平滑返回

使用注意:

  • 必须配合 State + AnchorChanges 使用,否则不会触发
  • 动画过渡的是布局锚点位置,而不是 x / y 数值
  • 如果想要锚点和属性同时动画,可以配合 ParallelAnimation
  • 不能直接写 AnchorAnimation { target: rect; property: “anchors.left” } 这样的形式

9.ParentAnimation(父元素动画)

9.1 ParentAnimation 是什么?
  在 QML 中,如果你直接改变一个元素的 parent(父项),它会瞬间跳到新父项的坐标系中。ParentAnimation 用于平滑地过渡元素从一个父元素移动到另一个父元素的过程。

它会:

  • 计算元素在两个父项坐标系中的位置和大小变化
  • 通过动画平滑地移动到新位置
  • 通常配合 ParentChange 和 Transition 一起使用

9.2 主要属性

  • via:一个可选的中间对象,表示过渡时先移动到这个容器再到目标父项(常用于跨层动画)
  • duration:动画时长
  • easing:缓动曲线类型

9.3 基本使用示例

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 400
    height: 200
    color: "#ddeeff"

    Rectangle {
        id: containerLeft
        width: parent.width / 2
        height: parent.height
        color: "#aaccee"
    }

    Rectangle {
        id: containerRight
        width: parent.width / 2
        height: parent.height
        x: parent.width / 2
        color: "#ccddaa"
    }

    Rectangle {
        id: movingBox
        width: 50
        height: 50
        color: "orange"
        anchors.centerIn: containerLeft
    }

    states: [
        State {
            name: "right"
            ParentChange {
                target: movingBox
                parent: containerRight
                anchors.centerIn: containerRight
            }
        }
    ]

    transitions: [
        Transition {
            ParentAnimation { duration: 800; easing.type: Easing.InOutQuad }
        }
    ]

    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (parent.state === "")
                parent.state = "right"
            else
                parent.state = ""
        }
    }
}

效果:初始时方块在左侧容器居中;点击背景 → 方块平滑地移动到右侧容器居中;再点击 → 平滑地回到左侧容器。

和 AnchorAnimation 的区别:
在这里插入图片描述

10.元素SmoothedAnimation(平滑动画)

10.1 SmoothedAnimation 是什么?
  SmoothedAnimation 是一种持续平滑的动画,它不是固定起点和终点的那种动画(比如 NumberAnimation),而是让一个属性在目标值变化时自动缓慢跟随到新值,就像“惯性”一样。

特点:

  • 不需要明确指定 from / to
  • 只要属性值改变,动画会自动平滑过渡
  • 可以反复改变目标值,动画会动态调整路径
  • 常用于跟随鼠标移动、惯性滑动、缓慢缩放等场景

10.2 主要属性

  • velocity 平滑移动速度(像素/秒),数值越大变化越快
  • duration 最大动画时长(毫秒),超时则直接到达目标值
  • easing 缓动曲线类型(Easing.InOutQuad、Easing.Linear 等)
  • reversingMode 反向变化时的处理方式(SmoothedAnimation.Immediate 等)

10.3 基本用法

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 400
    height: 200
    color: "#ddeeff"

    Rectangle {
        id: box
        width: 50
        height: 50
        color: "orange"
        y: height / 2 - height / 2

        // 绑定 SmoothedAnimation 到 x 属性
        Behavior on x {
            SmoothedAnimation {
                velocity: 200   // 每秒移动 200 像素
                easing.type: Easing.InOutQuad
            }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            // 每次点击,方块平滑移动到点击位置
            box.x = mouse.x - box.width / 2
        }
    }
}

效果:点击背景,方块不会瞬移,而是以设定的速度平滑移动到点击位置;多次点击时,方块会连续平滑地调整方向

和 NumberAnimation 的区别:
在这里插入图片描述

11.SpringAnimation(弹簧动画)

11.1 SpringAnimation 是什么
  SpringAnimation 是 QML 中一种基于物理模拟的动画类型,它使用弹簧力和阻尼的原理,让属性值变化时有一个带回弹、缓冲的效果,就像真实世界中的弹簧运动。

特点:

  • 有弹性(overshoot)和回弹效果
  • 模拟物理惯性和阻尼
  • 目标值变化时会自动重新计算路径
  • 适合用在按钮点击、元素移动、缩放时的“Q弹”效果

11.2 主要属性

  • spring 弹簧系数(刚度),值越大弹簧越硬,运动越快
  • damping 阻尼系数(0~1 之间),值越大减速越快,回弹幅度越小
  • epsilon 结束阈值,属性变化小于这个值时动画停止
  • modulus 如果属性是循环的(如角度 0~360°),设置这个值可避免绕远路
  • mass 物体质量,越大加速度越慢(较少使用)

11.3 基本用法

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 400
    height: 200
    color: "#ddeeff"

    Rectangle {
        id: ball
        width: 50
        height: 50
        radius: 25
        color: "orange"
        anchors.verticalCenter: parent.verticalCenter

        // 给 x 属性加一个弹簧动画
        Behavior on x {
            SpringAnimation {
                spring: 3       // 弹簧刚度
                damping: 0.2    // 阻尼
            }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            // 每次点击,小球弹性移动到点击位置
            ball.x = mouse.x - ball.width / 2
        }
    }
}

和 SmoothedAnimation 的区别:
在这里插入图片描述

12.PathAnimation(路径动画)

12.1 PathAnimation 是什么
PathAnimation 是 QML 中用于让对象沿着预先定义的**路径(Path)**平滑移动的动画类型。

特点:

  • 路径由 PathLine、PathQuad、PathCubic 等段组成
  • 支持位置插值(元素沿路径移动)
  • 支持旋转(物体可以随着路径方向自动旋转)
  • 可以循环、反向播放

12.2 主要属性

  • target:要移动的目标对象
  • path:路径对象(Path)
  • duration:动画总时长(毫秒)
  • loops:循环次数(Animation.Infinite 表示无限循环)
  • orientation:物体旋转方式(PathAnimation.NoOrientation / PathAnimation.AlignToPath)
  • easing:缓动曲线(Easing.Linear、Easing.InOutQuad 等)
  • anchorPoint:元素锚点(决定旋转中心)

12.3 基本用法

import QtQuick 2.12
import QtQuick.Controls 2.12

Rectangle {
    width: 500
    height: 300
    color: "#ddeeff"

    Rectangle {
        id: ball
        width: 40
        height: 40
        radius: 20
        color: "orange"
    }

    PathAnimation {
        id: pathAnim
        target: ball
        duration: 4000
        loops: Animation.Infinite
        orientation: PathAnimation.AlignToPath  // 自动旋转
        anchorPoint: Qt.point(ball.width/2, ball.height/2)

        path: Path {
            startX: 50; startY: 150
            PathQuad { x: 250; y: 50; controlX: 150; controlY: 0 }
            PathQuad { x: 450; y: 150; controlX: 350; controlY: 300 }
            PathLine { x: 50; y: 150 }
        }
    }

    Component.onCompleted: pathAnim.start()
}

效果:

  • 橙色小球沿着一条曲线路径循环运动
  • 小球会随着路径方向自动旋转
  • 可以用 PathLine、PathCubic 等改变轨迹形状

路径定义方式:

  • PathLine:直线段
  • PathQuad:二次贝塞尔曲线
  • PathCubic:三次贝塞尔曲线
  • PathArc:弧线
  • PathAttribute:路径上额外的属性(如缩放、透明度变化)

13.Vector3dAnimation(3D容器动画)

13.1 基本介绍
  Vector3dAnimation 是 Qt Quick 中的一种属性动画,专门用来平滑地在两个 vector3d 值之间插值(即三维向量,包含 x、y、z 三个浮点分量)。

它的主要用途是:

  • 对 vector3d 类型属性做平滑过渡(比如 3D 旋转、3D 位移、摄像机方向)。
  • 比如:从 (0,0,0) 平滑移动到 (100,50,20),或从 (0,0,0) 旋转到 (90,45,0)。

它的类型安全是针对 vector3d 属性,而不是单个数值或颜色。

13.2 常用属性

  • from:动画的起始 vector3d 值
  • to:动画的目标 vector3d 值
  • duration:动画持续时间(毫秒)
  • easing:缓动曲线(如 Easing.InOutQuad)
  • loops:循环次数(Animation.Infinite 表示无限循环)
  • running:是否正在运行
  • target:动画作用的对象
  • property:绑定的属性名称(必须是 vector3d 类型)

13.3 使用示例
下面是一个 QML 示例,演示如何用 Vector3dAnimation 平滑改变一个 3D 对象的位置:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick3D 1.12

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Vector3dAnimation 示例")

    View3D {
        anchors.fill: parent

        PerspectiveCamera {
            position: Qt.vector3d(0, 200, 600)
            lookAt: Qt.vector3d(0, 0, 0)
        }

        DirectionalLight {
            eulerRotation: Qt.vector3d(-45, 45, 0)
        }

        Model {
            id: cube
            source: "#Cube"
            scale: Qt.vector3d(50, 50, 50)
            position: Qt.vector3d(0, 0, 0) // 初始位置

            // 动画:让立方体在两个位置之间来回移动
            Vector3dAnimation {
                id: moveAnim
                target: cube
                property: "position"
                from: Qt.vector3d(0, 0, 0)
                to: Qt.vector3d(200, 100, -150)
                duration: 2000
                easing.type: Easing.InOutQuad
                loops: Animation.Infinite
                running: true
            }
        }
    }
}

14. PropertyAction(属性动作)

14.1 基本介绍
  PropertyAction 是 Qt Quick 中的一种瞬时动作动画元素,它不会产生渐变效果,而是立即将目标属性设置为指定值。

它常用于:

  • 在动画序列(SequentialAnimation)中,瞬间修改属性值。
  • 配合其他动画形成“跳变 + 过渡”的效果。
  • 在动画中间阶段切换状态,比如立即隐藏/显示控件、改变颜色、切换图像等。

简单说:PropertyAction 是动画系统的“立刻赋值”工具。

14.2 常用属性

  • target:动画作用的目标对象
  • property:需要设置的属性名
  • value:设置的目标值(立即生效)
  • targets:多个目标对象(可以替代 target)

14.3 基本示例
让一个矩形先瞬间变红,然后再平滑移动到新位置:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 400
    height: 300
    title: qsTr("PropertyAction 示例")

    Rectangle {
        id: rect
        width: 80
        height: 80
        color: "blue"
        anchors.verticalCenter: parent.verticalCenter

        SequentialAnimation {
            running: true
            loops: Animation.Infinite

            // Step 1: 立即变红
            PropertyAction {
                target: rect
                property: "color"
                value: "red"
            }

            // Step 2: 平滑移动
            NumberAnimation {
                target: rect
                property: "x"
                from: 0
                to: parent.width - rect.width
                duration: 1000
                easing.type: Easing.InOutQuad
            }

            // Step 3: 立即变蓝
            PropertyAction {
                target: rect
                property: "color"
                value: "blue"
            }

            // Step 4: 平滑移动回去
            NumberAnimation {
                target: rect
                property: "x"
                from: parent.width - rect.width
                to: 0
                duration: 1000
                easing.type: Easing.InOutQuad
            }
        }
    }
}

使用技巧:

  • PropertyAction 适合做动画的瞬间切换,不要用它做渐变。
  • 如果要设置多个属性,可以用多个 PropertyAction,或者用 ScriptAction 一次性设置多个值。
  • 也可以在 ParallelAnimation 中使用 PropertyAction,让某些属性立刻变化,同时其他属性平滑变化。

15. ScriptAction(脚本动作)

15.1 基本介绍
  ScriptAction 是 Qt Quick 中的一种瞬时动作动画元素,它允许你在动画序列中 直接执行一段 JavaScript 脚本。

特点:

  • 和 PropertyAction 类似,都是瞬时执行,不会产生过渡效果。
  • 但它更灵活,因为可以执行任意 JavaScript 逻辑,而不仅仅是修改一个属性。
  • 常用于:在动画中间调用函数;修改多个属性;进行逻辑判断;发出信号、打印调试信息

15.2 常用属性

  • script:要执行的 JavaScript 脚本(字符串)
  • scriptName:可选,方便在调试时标识脚本
  • script 块:也可以直接用大括号写多行脚本

15.3 基本示例
让一个矩形先移动,然后在中途执行脚本改变颜色并打印信息:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 400
    height: 300
    title: qsTr("ScriptAction 示例")

    Rectangle {
        id: rect
        width: 80
        height: 80
        color: "blue"
        anchors.verticalCenter: parent.verticalCenter

        SequentialAnimation {
            running: true
            loops: Animation.Infinite

            // Step 1: 平滑移动到右边
            NumberAnimation {
                target: rect
                property: "x"
                from: 0
                to: parent.width - rect.width
                duration: 1000
                easing.type: Easing.InOutQuad
            }

            // Step 2: 执行脚本
            ScriptAction {
                script: {
                    console.log("矩形到达右侧,改变颜色为红色")
                    rect.color = "red"
                }
            }

            // Step 3: 平滑移动回左边
            NumberAnimation {
                target: rect
                property: "x"
                from: parent.width - rect.width
                to: 0
                duration: 1000
                easing.type: Easing.InOutQuad
            }

            // Step 4: 执行脚本
            ScriptAction {
                script: {
                    console.log("矩形到达左侧,改变颜色为蓝色")
                    rect.color = "blue"
                }
            }
        }
    }
}

使用技巧:

  • 适合做动画过程中的逻辑插入。
  • 如果只是设置单个属性值,用 PropertyAction 更简洁。
  • 脚本中可以访问 QML 作用域里的所有对象和属性。
  • 可以结合 ParallelAnimation 使用,实现“脚本执行 + 动画”并行。

三、缓冲曲线(Easing Curves)

3.1 基本介绍
  在 QML 动画中(如 NumberAnimation、PropertyAnimation、Vector3dAnimation 等),缓冲曲线(Easing Curves)用于控制动画的速度变化方式。

  • 默认情况下,动画的属性值会匀速变化(Easing.Linear)。
  • 通过设置 easing.type,可以让动画开始更快、中间更慢、或者来回弹跳等,提升动画的自然感和视觉效果。

3.2 常用类型一览
在这里插入图片描述
3.3 关键属性
在 QML 动画元素中,可以这样设置缓冲曲线:

NumberAnimation {
    target: rect
    property: "x"
    from: 0
    to: 300
    duration: 1000
    easing.type: Easing.InOutQuad
}

可选的 easing 子属性:

  • type:缓冲曲线类型(如 Easing.OutBounce)。
  • amplitude:振幅(用于 Elastic 类型)。
  • overshoot:回弹幅度(用于 Back 类型)。
  • period:周期(用于 Elastic 类型)。

示例:不同缓冲曲线效果对比
下面的例子会让 4 个矩形以不同的缓冲曲线移动:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 500
    height: 300
    title: qsTr("Easing Curves 示例")

    Column {
        anchors.centerIn: parent
        spacing: 20

        Repeater {
            model: [
                { color: "red", easingType: Easing.Linear, label: "Linear 匀速" },
                { color: "green", easingType: Easing.OutBounce, label: "OutBounce 弹跳" },
                { color: "blue", easingType: Easing.InOutQuad, label: "InOutQuad 加速再减速" },
                { color: "orange", easingType: Easing.OutElastic, label: "OutElastic 弹簧" }
            ]

            delegate: Row {
                spacing: 10

                Rectangle {
                    id: rect
                    width: 40; height: 40
                    color: model.color
                    radius: 5

                    NumberAnimation on x {
                        from: 0
                        to: 300
                        duration: 1500
                        loops: Animation.Infinite
                        easing.type: model.easingType
                        running: true
                        onRunningChanged: if (!running) x = 0
                    }
                }

                Text {
                    text: model.label
                    verticalAlignment: Text.AlignVCenter
                }
            }
        }
    }
}

四、AnimationController(动画控制器)

4.1 基本介绍
  AnimationController 是 QML 动画系统中的一个动画进度控制器,它允许你手动控制一个动画的播放进度(而不是让它自动播放)。

特点:

  • 通过 progress 属性(范围 0.0 ~ 1.0)表示动画的完成比例。
  • 不会自动播放动画,必须由你手动设置 progress。
  • 适合做可拖拽、滑动、手势控制的动画。
  • AnimationController 里的动画不会真正运行时间,而是根据 progress 值计算当前帧。

4.2 关键属性

  • animation:被控制的动画(可为 ParallelAnimation、SequentialAnimation 等)
  • progress:动画当前进度(0.0 ~ 1.0),0 表示起点,1 表示终点
  • complete:true 表示动画已经结束(progress == 1.0)

4.3 基本示例
滑块控制矩形的移动和颜色渐变:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 400
    height: 300
    title: qsTr("AnimationController 示例")

    Rectangle {
        id: rect
        width: 80
        height: 80
        color: "red"
        anchors.verticalCenter: parent.verticalCenter
    }

    // 动画控制器
    AnimationController {
        id: controller
        progress: slider.value
        animation: ParallelAnimation {
            NumberAnimation { target: rect; property: "x"; from: 0; to: parent.width - rect.width; duration: 1000 }
            ColorAnimation { target: rect; property: "color"; from: "red"; to: "blue"; duration: 1000 }
        }
    }

    Slider {
        id: slider
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        width: parent.width - 40
        from: 0
        to: 1
        stepSize: 0.01
    }
}

使用技巧:

  • 如果需要多段动画,可以在 animation 里使用 SequentialAnimation 或 ParallelAnimation。
  • 可以和 MouseArea 结合,实现拖拽驱动。
  • 区别于普通动画:普通动画是时间驱动的,而 AnimationController 是进度驱动的。
  • 适合做 交互式动画,而不是纯装饰性动画。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值