目录

(放个目录方便预览。知乎不支持目录,这个目录是从博客复制过来的,点击会跳转到博客)

  • 简介
  • 关于文章
  • 暗流涌动 效果预览
  • QtQuick动画系统
    • 动画组件
    • 动画的使用
      • 用例一 直接声明动画
      • 用例二 on语法
      • 用例三 Transitions或状态机
  • ShaderEffect
  • 暗流涌动 效果源码
    • 组件的封装
    • 原理
    • 组件的使用

简介

这是《Qml特效》系列文章的第15篇,涛哥将会教大家一些Qml特效和动画相关的知识。

前12篇是进场动画效果 参考了WPS版ppt的动画,12种基本效果已经全部实现,可以到github TaoQuick项目中预览:

进场动画预览

因为效果都比较简单,就没有写太多说明。

没有13

没有13

没有13

从14篇开始,做一些特殊的效果和动画,同时会讲解相关的知识。

关于文章

文章主要发布在涛哥的博客 和 涛哥的知乎专栏-Qt进阶之路

暗流涌动 效果预览

流动的箭头,以及倒影

其中用到的知识点有: Qml路径动画。

当然还有一些预备知识:

做特效和动画,要用到QtQuick的动画系统,以及ShaderEffect特效。

QtQuick动画系统

动画组件

Qt动画系统,在帮助文档有详细的介绍,搜索关键词」Animation」,涛哥在这里说一些重点。

涛哥用思维导图列出了Qml中所有的动画组件:

  • 右边带虚线框的部分比较常用,是做动画必须要掌握的,尤其是属性动画PropertyAnimation和数值动画NumberAinmation。常见的各种坐标动画、宽高动画、透明度动画、颜色动画等等,都可以用这些组件来实现。
  • 底下的States、Behavior 和 Traisitions,也是比较常用的和动画相关的组件。可在帮助文档搜索关键词」Qt Quick States」、」Behavior」、」Animation and Transitions」。后续的文章,涛哥会专门讲解。
  • 左边的Animator系列,属于Scene Graph渲染层面的优化,其属性Change信号只在最终值时发出,不发出中间值,使用的时候需要注意。
  • 顶上的AnimationController,属于高端玩家,用来控制整个动画的进度。

动画的使用

用例一 直接声明动画

直接声明动画,指定target和property,之后可以在槽函数/js脚本中通过id控制动画的运行。

也可以通过设定loops 和 running属性来控制动画

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

用例二 on语法

on语法可以使用动画组件,也可以用Behavior,直接on某个特定的属性即可。效果一样。

on动画中,如果直接指定了running属性,默认就会执行这个动画。

也可以不指定running属性,其它地方修改这个属性时,会自动按照动画来执行。

示例代码 on动画

Rectangle {
width: 100; height: 100; color: "green"
RotationAnimation on rotation {
loops: Animation.Infinite
from: 0
to: 360
running: true
}
}

示例代码 Behavior 动画

import QtQuick 2.0

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

Behavior on width {
NumberAnimation { duration: 1000 }
}

MouseArea {
anchors.fill: parent
onClicked: rect.width = 50
}
}

用例三 Transitions或状态机

过渡动画和状态机动画,本质还是直接使用动画组件。

只不过是把动画声明并存储起来,以在状态切换时使用。

这里先不细说了,后面会有系列文章,会专门讲解。

ShaderEffect

动画只能控制组件的属性整体的变化,做特效需要精确到像素。

Qml中提供了ShaderEffect这个组件,就能实现像素级别的操作。

Qml中有一个模块QtGraphicalEffects,提供了部分特效,就是使用ShaderEffect实现的。

使用ShaderEffect实现特效,需要有一些OpenGL/DirectX知识,了解GPU渲染管线,同时也需要一些数学知识。

大名鼎鼎的ShaderToy网站,就是使用Shader实现各种像素级别的酷炫特效。

ShaderToy

作者iq大神

ShaderToy上面的特效都是可以移植到Qml中的。

暗流涌动 效果源码

组件的封装

封装了一个组件TArrow

//TArrow.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
Image {
id: root
x: 10
y: 10
source: "qrc:/EffectImage/Img/arrow.png"
visible: false
function run() {
visible = true;
pathAnimation.start();
}
PathAnimation {
id: pathAnimation
target: root
loops: -1
duration: 2400
orientation: PathAnimation.TopFirst
path: Path{
startX: 10
startY: 10
PathCurve { x: 60; y: 15}
PathCurve { x: 110; y: 205}
PathCurve { x: 210; y: 200}
PathCurve { x: 260; y: 35}
PathCurve { x: 310; y: 25}
}
}
}

原理

很简单的路径动画,使用的箭头图片是这张:

组件的使用

import QtQuick 2.12
import QtQuick.Controls 2.12
import "../Effects/"
Rectangle {
anchors.fill: parent
color: "black"
Item {
id: arrowItem
x: 10
y: 10
width: 300
height: 300
TArrow {
id: arrow1
}
TArrow {
id: arrow2
}
TArrow {
id: arrow3
}
TArrow {
id: arrow4
}
TArrow {
id: arrow5
}
TArrow {
id: arrow6
}
TArrow {
id: arrow7
}
TArrow {
id: arrow8
}
TArrow {
id: arrow9
}
}
Item {
id: mirrorItem
x: arrowItem.x
y: arrowItem.y + arrowItem.height
width: arrowItem.width
height: arrowItem.height
opacity: 0.3
layer.enabled: true
layer.effect: Component {
ShaderEffectSource {
sourceItem: arrowItem
textureMirroring: ShaderEffectSource.MirrorVertically
}
}
transform: Rotation {
origin.x: mirrorItem.width / 2
origin.y: mirrorItem.height / 2
axis {x: 1; y: 0; z: 0}
angle: 180
}
}
Component.onCompleted: {
seAnimation.start()
}
SequentialAnimation {
id: seAnimation
ScriptAction {script: arrow1.run()}
PauseAnimation {duration: 200 }
ScriptAction {script: arrow2.run()}
PauseAnimation {duration: 200 }
ScriptAction {script: arrow3.run()}

PauseAnimation {duration: 500 }

ScriptAction {script: arrow4.run()}
PauseAnimation {duration: 200 }
ScriptAction {script: arrow5.run()}
PauseAnimation {duration: 200 }
ScriptAction {script: arrow6.run()}

PauseAnimation {duration: 500 }

ScriptAction {script: arrow7.run()}
PauseAnimation {duration: 200 }
ScriptAction {script: arrow8.run()}
PauseAnimation {duration: 200 }
ScriptAction {script: arrow9.run()}
PauseAnimation {duration: 200 }
}
}

动画比较简单粗暴。

倒影这里,和《Qml特效14-跟上节奏》使用的不一样,使用的是Item的layer属性layer.enabled: truelayer.effect: Component { ShaderEffectSource { ... }}
推荐阅读:
相关文章