目錄

(放個目錄方便預覽。知乎不支持目錄,這個目錄是從博客複製過來的,點擊會跳轉到博客)

  • 簡介
  • 關於文章
  • 暗流涌動 效果預覽
  • 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 { ... }}
推薦閱讀:
相关文章