QML 动画效果详解

属性动画(PropertyAnimation)

PropertyAnimation是QML中最基础、最常用的动画类型,它可以对任何基于数字或颜色的属性进行动画化处理,实现平滑的过渡效果。

核心属性与用法

PropertyAnimation的主要属性如下表所示:

属性类型描述默认值targetQtObject动画作用的目标对象父对象propertystring要动画化的属性名必须指定fromvariant动画起始值当前属性值tovariant动画结束值必须指定durationint动画持续时间(ms)250easing.typeenumeration缓动曲线类型Easing.Lineareasing.amplitudereal弹性动画幅度1.0easing.periodreal弹性动画周期0.3loopsint循环次数1runningbool是否自动运行falsealwaysRunToEndbool停止时是否完成动画false

基础示例

import QtQuick 2.15

Rectangle {

id: rect

width: 100; height: 100

color: "red"

x: 0

// 基本属性动画

PropertyAnimation {

target: rect

property: "x"

to: 200

duration: 1000

running: true

}

}

缓动曲线示例

PropertyAnimation支持多种缓动曲线,可以创建更自然的动画效果:

PropertyAnimation {

property: "rotation"

to: 360

easing.type: Easing.OutBounce

easing.amplitude: 2.0

duration: 1000

}

相对值动画

PropertyAnimation支持相对当前值的动画:

PropertyAnimation {

property: "x"

to: myItem.x + 50 // 相对当前位置移动50像素

duration: 500

}

多属性动画

可以同时对多个属性应用动画:

ParallelAnimation {

PropertyAnimation { property: "x"; to: 100 }

PropertyAnimation { property: "y"; to: 100 }

PropertyAnimation { property: "opacity"; to: 0.5 }

}

PropertyAnimation的强大之处在于它的通用性,几乎可以对任何QML元素的任何属性进行动画处理,是构建动态UI的基础。

数字动画(NumberAnimation)

NumberAnimation是PropertyAnimation的派生类,专门用于处理数值类型的属性动画,如位置、大小、旋转角度等。

核心属性

NumberAnimation继承了PropertyAnimation的所有属性,并特别优化了对数值类型的处理:

属性类型描述默认值fromreal动画起始值当前属性值toreal动画结束值必须指定byreal相对变化量-其他属性继承自PropertyAnimation

基本用法示例

import QtQuick 2.0

Rectangle {

width: 100; height: 100

color: "red"

// 数字动画作为属性值源

NumberAnimation on x {

to: 50

duration: 1000

}

}

三种写法对比

NumberAnimation有三种主要使用方式:

​方法1:直接绑定属性​

NumberAnimation on rotation {

id: minutePinAni

from: 0

to: 360

duration: 20000

loops: Animation.Infinite

}

​方法2:独立动画对象​

NumberAnimation {

id: minutePinAni

target: minPin

property: "rotation"

to: 360

duration: 10000

loops: Animation.Infinite

}

​方法3:通过Behavior​

Behavior on rotation {

NumberAnimation {

from: 0

to: 100

duration: 20000

loops: Animation.Infinite

}

}

与RotationAnimation的区别

虽然NumberAnimation可以用于旋转动画,但QML提供了专门的RotationAnimation类型,它比NumberAnimation多了一个旋转方向属性:

RotationAnimation {

target: item

property: "rotation"

direction: RotationAnimation.Clockwise // 顺时针方向

from: 0

to: 360

duration: 1000

}

RotationAnimation的direction属性可以是:

RotationAnimation.Numerical (默认):数值线性插值RotationAnimation.Clockwise:顺时针旋转RotationAnimation.Counterclockwise:逆时针旋转RotationAnimation.Shortest:沿最短路径旋转

NumberAnimation因其简单高效,在大多数数值动画场景中都是首选方案,特别是当需要精确控制数值变化过程时。

预定义的目标和属性动画

QML提供了一种更简洁的语法来定义属性动画,即直接在属性上声明动画,这种方式称为"预定义的目标和属性动画"或"on语法"。

基本语法

on {

// 动画属性设置

}

典型示例

import QtQuick 2.0

Rectangle {

id: rect

width: 100; height: 100

color: "red"

// 预定义x属性的动画

PropertyAnimation on x {

to: 100

duration: 500

}

// 预定义y属性的动画

PropertyAnimation on y {

to: 100

duration: 500

}

}

特点与优势

​简洁性​:不需要指定target和property,代码更简洁​自动绑定​:动画自动绑定到声明它的元素的对应属性​自动运行​:这种形式的动画会在组件加载完成后自动开始运行​适用于任何属性​:可以对任何支持动画的属性使用此语法

实际应用案例

import QtQuick 2.15

Rectangle {

width: 200

height: 200

anchors.centerIn: parent

color: "lightgreen"

// 旋转动画

RotationAnimation on rotation {

from: 0

to: 360

duration: 2000

loops: Animation.Infinite

}

// 缩放动画

ScaleAnimator on scale {

from: 0.5

to: 1.5

duration: 1000

loops: Animation.Infinite

}

// 透明度动画

OpacityAnimator on opacity {

from: 0.3

to: 1.0

duration: 1500

loops: Animation.Infinite

}

}

与独立动画的对比

相比于独立的动画声明,预定义语法有以下区别:

特性预定义语法独立动画目标对象隐含(父元素)需显式指定属性绑定自动关联需显式指定执行时机自动开始需手动启动或设置running复用性较低较高代码量较少较多

预定义的目标和属性动画语法非常适合那些简单、直接的动画需求,特别是在原型设计或简单动画场景中,可以显著减少代码量并提高可读性。

过渡动画(Transition)

Transition用于定义状态变化时的动画效果,它可以在元素从一个状态切换到另一个状态时,自动应用指定的动画。

核心属性

Transition的主要属性如下:

属性类型描述默认值fromstring起始状态名"" (任何状态)tostring目标状态名"" (任何状态)reversiblebool是否可反向播放falseenabledbool是否启用过渡trueanimationslist动画列表空列表

基本用法

import QtQuick 2.15

Rectangle {

id: myRect

width: 100; height: 100

color: "red"

state: "state1"

MouseArea {

anchors.fill: parent

onPressed: myRect.state = "state2"

onReleased: myRect.state = "state1"

}

states: [

State {

name: "state1"

PropertyChanges { target: myRect; x: 0; y: 0 }

},

State {

name: "state2"

PropertyChanges { target: myRect; x: 100; y: 100 }

}

]

transitions: [

Transition {

from: "state1"

to: "state2"

NumberAnimation { properties: "x,y"; duration: 500 }

},

Transition {

from: "state2"

to: "state1"

NumberAnimation { properties: "x,y"; duration: 300 }

}

]

}

多属性过渡示例

transitions: Transition {

// 颜色过渡

ColorAnimation { duration: 1000 }

// 位置过渡

NumberAnimation {

properties: "x,y"

duration: 500

easing.type: Easing.OutBack

}

// 旋转过渡

RotationAnimation {

duration: 700

direction: RotationAnimation.Clockwise

}

}

高级用法:条件过渡

可以根据不同条件应用不同的过渡效果:

transitions: [

Transition {

from: "*"; to: "dragging"

NumberAnimation { property: "scale"; to: 1.2; duration: 200 }

},

Transition {

from: "dragging"; to: "*"

SequentialAnimation {

NumberAnimation { property: "scale"; to: 1.0; duration: 200 }

SpringAnimation { property: "rotation"; spring: 2; damping: 0.2 }

}

}

]

与Behavior的区别

Transition和Behavior都用于属性变化时的动画,但有以下区别:

特性TransitionBehavior触发条件状态变化任何属性变化作用范围状态切换期间始终有效控制粒度基于状态基于属性适用场景明确的状态机持续性的属性变化

Transition在创建有明确状态划分的界面时非常有用,如折叠/展开、激活/非激活等场景,能够提供清晰的视觉反馈和状态转换指示。

默认行为动画(Behavior)

Behavior是QML中用于对属性值变化做隐式动画的机制,它绑定到某个属性上,当该属性在运行时被修改时,会自动触发预定义的动画效果。

核心属性

Behavior的主要属性如下:

属性类型描述默认值animationAnimation属性变化时应用的动画必须指定enabledbool是否启用行为动画true

基本语法

Behavior on {

}

基础示例

import QtQuick 2.15

Rectangle {

width: 100; height: 100

color: "red"

// 为x坐标变化添加行为动画

Behavior on x {

NumberAnimation { duration: 500 }

}

MouseArea {

anchors.fill: parent

onClicked: parent.x = parent.x + 50

}

}

常见内置Animation类型

Behavior可以与多种动画类型配合使用:

类型可动画化属性说明NumberAnimation数值型(x, y, width...)通过线性或缓动曲线插值数值ColorAnimationcolor, border.color...在两个颜色值之间渐变RotationAnimationrotation对旋转角度做插值动画ScaleAnimationscale对缩放因子做插值SpringAnimation任意数值型弹簧阻尼动画,带回弹效果SmoothedAnimation任意数值型平滑快速跟随目标值

组合多个动画

Behavior内部可以使用组合动画实现复杂效果:

Behavior on width {

SequentialAnimation {

NumberAnimation { duration: 300; easing.type: Easing.OutQuad }

PauseAnimation { duration: 100 }

NumberAnimation { duration: 200; easing.type: Easing.InQuad }

}

}

条件性行为

可以动态启用或禁用Behavior:

Rectangle {

id: rect

property bool animationsEnabled: true

Behavior on x {

enabled: rect.animationsEnabled

NumberAnimation { duration: 200 }

}

}

注意事项

​初始化赋值不会触发​:组件创建时的初始设定不会触发Behavior动画​性能考虑​:不要对大量快速变化的属性绑定耗时动画​多重Behavior​:一个属性只能有一个Behavior,但可以在内部使用ParallelAnimation/SequentialAnimation​与visible属性​:对visible属性直接应用Behavior无效,可以改为对opacity应用动画然后绑定visible到opacity > 0

Behavior的主要优势在于它能够降低动画调用成本,无需在每次更改时手动启动动画,只需在组件声明里一次性配置,后续所有对该属性的改变都会平滑地过渡。

并行动画与序列动画(ParallelAnimation和SequentialAnimation)

QML提供了两种组合动画的方式:ParallelAnimation(并行动画)和SequentialAnimation(序列动画),它们作为容器可以嵌套其他动画元素,实现复杂的动画效果。

ParallelAnimation(并行动画)

ParallelAnimation允许所有子动画同时运行,适用于需要多个属性同步动画的场景。

核心属性

属性类型描述默认值animationslist子动画列表空列表runningbool是否运行falseloopsint循环次数1alwaysRunToEndbool停止时是否完成当前动画false

基本示例

import QtQuick 2.15

Rectangle {

id: rect

width: 100; height: 100

color: "red"

x: 0; y: 0; opacity: 1.0

ParallelAnimation {

running: true

NumberAnimation { target: rect; property: "x"; to: 200; duration: 1000 }

NumberAnimation { target: rect; property: "y"; to: 200; duration: 1500 }

PropertyAnimation { target: rect; property: "opacity"; to: 0.5; duration: 800 }

}

}

动态添加动画

ParallelAnimation支持动态添加子动画:

ParallelAnimation {

id: dynamicAnim

}

function addScaleAnimation() {

var anim = Qt.createQmlObject('import QtQuick 2.15; NumberAnimation {

property: "scale";

to: 2.0;

duration: 500

}', dynamicAnim);

dynamicAnim.addAnimation(anim);

}

SequentialAnimation(序列动画)

SequentialAnimation按顺序依次运行子动画,适用于需要多个动画按特定顺序执行的场景。

核心属性

属性类型描述默认值animationslist子动画列表空列表runningbool是否运行falseloopsint循环次数1alwaysRunToEndbool停止时是否完成当前动画falsecurrentAnimationAnimation当前正在运行的子动画null

基本示例

import QtQuick 2.15

Rectangle {

id: rect

width: 100; height: 100

color: "red"

x: 0; y: 0

SequentialAnimation {

running: true

NumberAnimation { target: rect; property: "y"; to: 200; duration: 1000 }

ColorAnimation { target: rect; property: "color"; to: "blue"; duration: 500 }

RotationAnimation { target: rect; property: "rotation"; to: 360; duration: 800 }

}

}

组合动画序列

可以嵌套ParallelAnimation和SequentialAnimation创建复杂动画:

SequentialAnimation {

// 第一阶段:并行移动和旋转

ParallelAnimation {

NumberAnimation { property: "x"; to: 200 }

RotationAnimation { target: rotation; to: 90 }

}

// 第二阶段:并行改变颜色和大小

ParallelAnimation {

ColorAnimation { property: "color"; to: "blue" }

NumberAnimation { property: "width"; to: 150 }

}

// 第三阶段:暂停后恢复

PauseAnimation { duration: 500 }

NumberAnimation { property: "scale"; to: 1.0; duration: 300 }

}

注意事项

​动画控制​:子动画的running属性会被容器动画控制,不应单独设置​持续时间​:ParallelAnimation的持续时间等于最长子动画的持续时间​性能考虑​:复杂的动画组合可能需要更多的CPU资源​调试技巧​:可以在动画的running和completed信号中添加console.log跟踪动画状态

ParallelAnimation和SequentialAnimation为QML动画提供了强大的组合能力,通过它们的嵌套和组合,可以构建出几乎任何复杂的动画序列,满足现代UI对动画效果的各类需求。

动画师动画(Animator)

Animator是Qt Quick 2.2及以上版本引入的一种特殊动画类型,与常规动画不同,Animator直接在Qt Quick的场景图渲染线程中执行,即使在UI线程繁忙时也能保持流畅的动画效果。

核心优势

​独立于UI线程​:在UI线程阻塞时仍能流畅运行​高性能​:直接在渲染线程执行,减少中间步骤​专有类型​:针对特定属性优化的动画类型​简单易用​:语法与PropertyAnimation类似

Animator类型

QML提供了多种专门的Animator类型:

类型作用属性描述XAnimatorx水平位置动画YAnimatory垂直位置动画ScaleAnimatorscale缩放动画RotationAnimatorrotation旋转动画OpacityAnimatoropacity透明度动画UniformAnimatoruniform着色器统一变量动画

基本用法

import QtQuick

Rectangle {

id: rect1

width: 100

height: 100

x: 10

y: 10

color: "red"

XAnimator on x {

from: 10

to: 300

duration: 2000

loops: Animator.Infinite

}

YAnimator on y {

from: 10

to: 300

duration: 2000

loops: Animator.Infinite

}

ScaleAnimator on scale {

from: 0.1

to: 1.5

duration: 2000

loops: Animator.Infinite

}

OpacityAnimator on opacity {

from: 0.1

to: 1.0

duration: 2000

loops: Animator.Infinite

}

RotationAnimator on rotation {

from: 0

to: 360

duration: 2000

loops: Animator.Infinite

}

}

与PropertyAnimation的对比

特性AnimatorPropertyAnimation执行线程渲染线程UI线程UI阻塞时继续运行可能卡顿适用版本Qt Quick 2.2+所有版本性能更高一般属性支持特定属性所有属性适用场景高性能需求通用需求

Animator类型特别适合那些需要高性能、流畅动画的场景,特别是在UI线程可能有繁重任务时,使用Animator可以确保动画不受影响,保持流畅运行。

精灵动画(SpriteAnimations)--嵌入式使用较少,了解就好

精灵动画是游戏开发和交互式应用中常见的技术,通过快速连续显示一系列图像帧来创建动画效果。QML提供了SpriteSequence和Sprite元素来实现精灵动画。

核心组件

​SpriteSequence​:精灵动画的容器,管理多个Sprite动画​Sprite​:定义单个动画序列​AnimatedSprite​:简化版的单动画精灵(后面详细介绍)

SpriteSequence属性

属性类型描述默认值currentSpritestring当前精灵动画的名称""goalSpritestring目标精灵动画""interpolatebool是否开启插值运算truerunningbool是否执行动画truespriteslist精灵动画集合空列表

Sprite属性

属性类型描述namestring动画名称sourceurl精灵图片源frameXint起始帧的x坐标frameYint起始帧的y坐标frameCountint动画帧数frameWidthint单帧宽度frameHeightint单帧高度frameDurationint每帧持续时间(ms)tomap过渡到其他动画的名称和权重

基本示例

import QtQuick

Window {

width: 640

height: 900

visible: true

title: qsTr("Hello World")

MouseArea {

anchors.fill: parent

onClicked: {

animation.start()

}

}

SequentialAnimation {

id: animation

//脚本会在前一个动画结束后、下一个动画开始前执行

//goalSprite属性可以指定目标Sprite类型,指定该属性后会无视过渡权重,而以最短的路径到达目标动画。即从still->blink->floating->flailing->falling这个顺序播放动画

ScriptAction {

script: image.goalSprite = "falling";

}

NumberAnimation {

target: image

property: "y"

to: 500

duration: 12000

}

// 下降完成之后回到still动画

ScriptAction {

script: {

image.goalSprite = "";

image.jumpTo("still")

}

}

PropertyAction {

target: image

property: "y"

value: 0

}

}

//精灵动画的容器,管理多个Sprite动画

SpriteSequence {

id: image

width: 256

height: 256

anchors.horizontalCenter: parent.horizontalCenter

interpolate: false

goalSprite: "" //最终动画

// 权重的作用原理​

// ​数值含义​:to对象中的键值对(如"still":1)表示从当前动画切换到其他动画的相对概率。

// 例如,"still":1, "blink":0.1表示:

// 切换到still动画的概率是 1/(1+0.1) ≈ 90.9%

// 切换到blink动画的概率是 0.1/(1+0.1) ≈ 9.1%

// ​权重为0​:如"floating":0表示禁止切换到该动画

// ​行为表现​:动画播放时,系统会按权重比例随机选择下一状态,still动画有极高概率保持,偶尔触发blink,而不会切换到floating

// 静止

Sprite {

name: "still"

source: "BearSheet.png"

frameCount: 1 //帧数

frameWidth: 256 //帧的宽度和高度

frameHeight: 256

frameDuration: 100 //持续时间

to: {

"still": 1, //1代表权重

"blink": 0.1,

"floating": 0

}

}

// 眨眼

Sprite {

name: "blink"

source: "BearSheet.png"

frameCount: 3

frameX: 256

frameY: 1536

frameWidth: 256

frameHeight: 256

frameDuration: 100

to: {

"still": 1

}

}

// 漂浮

Sprite {

name: "floating"

source: "BearSheet.png"

frameCount: 9

frameX: 0

frameY: 0

frameWidth: 256

frameHeight: 256

frameDuration: 160

to: {

"still": 0,

"flailing": 1

}

}

// 摆动

Sprite {

name: "flailing"

source: "BearSheet.png"

frameCount: 8

frameX: 0

frameY: 768

frameWidth: 256

frameHeight: 256

frameDuration: 160

to: {

"falling": 1

}

}

// 下降

Sprite {

name: "falling"

source: "BearSheet.png"

frameCount: 5

frameY: 1280

frameWidth: 256

frameHeight: 256

frameDuration: 160

to: {

"falling": 1

}

}

}

}

效果:

动画过渡机制

SpriteSequence中的动画可以通过to属性定义状态转换:

​随机转换​:根据权重随机切换到其他动画​强制转换​:通过设置goalSprite强制切换到指定动画​直接跳转​:使用jumpTo()方法立即切换到指定动画

使用场景

游戏角色动画(行走、奔跑、跳跃等)复杂的状态转换动画需要随机或条件触发动画变化的场景基于精灵图的动画效果

精灵动画特别适合游戏开发和需要复杂动画序列的应用,它能够有效地组织和管理多个动画状态,并通过状态转换创建丰富的交互体验。

动态精灵动画(AnimatedSprite)--嵌入式使用较少,了解就好

AnimatedSprite是QML中用于实现帧动画的简化组件,适用于不需要复杂状态管理的单一动画序列。

核心属性

AnimatedSprite的主要属性如下:

属性类型描述默认值frameCountint动画总帧数1frameRatereal每秒播放帧数-frameWidthint单帧图像宽度元素宽度frameHeightint单帧图像高度元素高度sourceurl精灵图集路径必须指定loopsint循环次数Animation.InfinitecurrentFrameint当前帧索引0frameDurationint每帧持续时间(ms)-frameSyncbool是否同步显示刷新率falseinterpolatebool是否在帧间插值truepausedbool是否暂停falsereversebool是否反向播放falserunningbool是否运行true

基本用法

import QtQuick 2.12

import QtQuick.Window 2.12

Window {

visible: true

width: 800

height: 600

color: "black"

title: "Qt基于Qml图像帧动画播放"

AnimatedSprite {

id: animated

width: 365

height: 365

anchors.centerIn: parent

source: "qrc:/numbers.png"

frameWidth: 64

frameHeight: 64

frameDuration: 1000 // 每秒播放一帧

frameCount: 10

frameX: 0

frameY: 0

onCurrentFrameChanged: {

info.text = "%1/%2".arg(animated.currentFrame).arg(animated.frameCount)

}

}

// 控制界面

Row {

spacing: 20

anchors.horizontalCenter: parent.horizontalCenter

anchors.bottom: parent.bottom

anchors.bottomMargin: 4

Text {

id: info

width: 120

height: 60

color: "red"

font.pixelSize: 38

verticalAlignment: Text.AlignVCenter

horizontalAlignment: Text.AlignRight

}

Button {

width: 120

height: 60

text: (animated.paused === true) ? "播放" : "暂停"

onClicked: (animated.paused === true) ? animated.resume() : animated.pause()

}

Button {

width: 120

height: 60

text: "单帧播放"

onClicked: animated.advance()

}

Button {

width: 120

height: 60

text: "重置"

onClicked: animated.restart()

}

}

}

与SpriteSequence的对比

特性AnimatedSpriteSpriteSequence复杂度简单复杂动画数量单一动画多动画序列状态转换不支持支持性能更高略低适用场景简单帧动画复杂动画状态机

​性能优化建议

​使用精灵图集​:将多帧打包到一个图像文件中,减少资源加载开销​合理设置帧率​:根据实际需要设置,避免不必要的渲染​适时暂停​:当动画不可见时暂停播放​预加载资源​:提前加载动画资源,避免运行时卡顿​减少插值​:对于像素艺术风格动画,关闭interpolate属性

AnimatedSprite因其简单易用和高效性能,成为实现简单帧动画的首选方案,特别适合游戏特效、加载动画、简单角色动画等场景。

弹动效果(Flickable)

Flickable是Qt Quick中用于实现可拖动和弹动效果的元素,它提供了一个可以滚动的区域,用户可以通过滑动手势浏览超出显示区域的内容。

核心属性

Flickable的主要属性如下:

属性类型描述默认值contentWidthreal内容宽度必须指定contentHeightreal内容高度必须指定contentXreal当前水平位置0contentYreal当前垂直位置0flickableDirectionenum滑动方向(Flickable.AutoFlickDirection等)AutoFlickDirectionboundsBehaviorenum边界行为(Flickable.StopAtBounds等)StopAtBoundsmaximumFlickVelocityreal最大滑动速度(像素/秒)平台相关flickDecelerationreal滑动减速度平台相关interactivebool是否允许用户交互truepixelAlignedbool是否像素对齐falsepressDelayint按下延迟时间(ms)0

基本用法

import QtQuick 2.5

import QtQuick.Window 2.2

Window {

visible: true

width: 640

height: 480

title: qsTr("Flickable Demo")

Flickable {

id: flickable

interactive: true

anchors.fill: parent

contentWidth: 1000

contentHeight: 1000

boundsBehavior: Flickable.StopAtBounds

// 内容项 - 一个大图像

Image {

id: image

source: "kun.jpg"

width: 1000

height: 1000

}

}

// 添加滚动条指示

ScrollBar {

id: vbar

width: 12

height: flickable.height

anchors.right: flickable.right

orientation: Qt.Vertical

position: flickable.visibleArea.yPosition

size : flickable.visibleArea.heightRatio

onPositionChanged: {

if (active) flickable.contentY = position * (flickable.contentHeight );

}

}

ScrollBar {

id: hbar

width: flickable.width

height: 12

anchors.bottom: flickable.bottom

orientation: Qt.Horizontal

position: flickable.visibleArea.xPosition

size : flickable.visibleArea.widthRatio

onPositionChanged: {

if (active) flickable.contentX = position * (flickable.contentWidth );

}

}

}

动态内容示例

Flickable常用于显示动态生成的内容:

Flickable {

anchors.fill: parent

contentWidth: col.width

contentHeight: col.height

Column {

id: col

width: parent.width

Repeater {

model: 50

delegate: Rectangle {

width: col.width

height: 60

color: index % 2 ? "lightgray" : "white"

Text {

text: "Item " + index

font.pixelSize: 20

anchors.centerIn: parent

}

}

}

}

}

高级用法:自定义回弹效果

Flickable的rebound属性允许开发者自定义内容回弹到边界时的过渡动画效果:

Flickable {

width: 200; height: 200

contentWidth: 400; contentHeight: 400

boundsBehavior: Flickable.DragOverBounds

rebound: Transition {

NumberAnimation {

properties: "x,y"

duration: 1000

easing.type: Easing.OutBounce

}

}

Rectangle {

width: 400; height: 400

gradient: Gradient {

GradientStop { position: 0.0; color: "lightsteelblue" }

GradientStop { position: 1.0; color: "blue" }

}

}

}

边界行为详解

Flickable提供了多种边界行为控制方式:

​StopAtBounds​(默认):内容不能拖动到边界之外,轻拂也不会超调​DragOverBounds​:内容可以拖动到边界之外,但轻拂不会超调​OvershootBounds​:轻拂时可以超过边界,但不能拖动到边界之外​DragAndOvershootBounds​:内容可以拖动到边界之外,轻拂时也可以超过边界

性能优化技巧

​设置clip属性​:对于非全屏Flickable,应将clip设为true以避免渲染开销​合理使用pixelAligned​:对于像素精确的内容,启用pixelAligned可避免亚像素渲染​动态加载内容​:对于超长列表,考虑使用动态加载技术​避免过度绘制​:优化内容项的绘制逻辑

翻转效果(Flipable)

Flipable是QML中用于实现3D翻转效果的元素,可以创建卡片翻转、面板切换等视觉效果。

核心属性

属性类型描述默认值frontItem正面显示的项必须指定backItem背面显示的项可选sideenumeration当前显示的面(Front或Back)Fronttransformlist应用的变换列表空列表axisvector3d旋转轴(x,y,z)(0,1,0)anglereal当前旋转角度(度)0

基本用法

import QtQuick

Window {

width: 640

height: 480

visible: true

title: qsTr("Hello World")

Flipable {

id: flipable

width: 240

height: 240

anchors.centerIn: parent

property bool flipped: falsed

front: Image {

source: "front.png"

anchors.centerIn: parent

}

back: Image {

source: "back.png"

anchors.centerIn: parent

}

transform: Rotation {

id: rotation

origin.x: flipable.width / 2

origin.y: flipable.height / 2

axis.x: 0

axis.y: 1

axis.z: 0

angle: 0

}

states: State {

name: "back"

when: flipable.flipped

PropertyChanges {

target: rotation

angle: 180

}

}

transitions: Transition {

NumberAnimation {

target: rotation

property: "angle"

duration: 500

}

}

MouseArea {

anchors.fill: parent

onClicked: {

flipable.flipped = !flipable.flipped

}

}

}

}

性能优化建议

​简化内容​:Flipable的两面内容应尽量简单,避免复杂嵌套​合理使用Perspective​:在父元素上设置Perspective变换可增强3D效果​避免频繁切换​:翻转动画较耗资源,不宜频繁触发​预渲染内容​:对于复杂内容,考虑使用ShaderEffect预渲染

总结

QML提供了丰富而强大的动画系统,从基础的属性动画到复杂的3D效果,开发者可以创建各种流畅的交互体验。关键要点包括:

​选择合适的动画类型​:根据场景选择PropertyAnimation、Behavior或Animator​组合使用动画​:利用ParallelAnimation和SequentialAnimation创建复杂序列​性能优化​:对于频繁触发的动画,优先考虑Animator类型​状态管理​:合理使用State和Transition管理界面状态变化

友情链接: