1,目標及展示 首先希望實現文字、圖片、控制項等在觸發後,呈現飄散並消失的效果。在QT常式《Qt Quick Particles Examples》是一個海星點擊滑鼠後呈現打散的效果,這個效果和最終需要的略有不同,所以我們在它的基礎上再加上我需要的一些元素,最終實現如下效果。 圖1(gif) 圖6 2 ...
1,目標及展示
首先希望實現文字、圖片、控制項等在觸發後,呈現飄散並消失的效果。在QT常式《Qt Quick Particles Examples》是一個海星點擊滑鼠後呈現打散的效果,這個效果和最終需要的略有不同,所以我們在它的基礎上再加上我需要的一些元素,最終實現如下效果。
圖1(gif)
圖6
2,設計分析
這個項目我們分析可以拆分成兩個部分,第一是背景飄散效果,第二是背景逐漸消失效果,然後將這兩種效果進行組合,就實現最終需要的效果。
首先先實現飄散效果,QT具有非常強大的粒子化效果,並且只需很少的幾行代碼就能實現效果。不過對於初次使用qml語言進行開發的設計人員,需要先瞭解關鍵字的含義和功能,當然我們可以在常式中微調每個關鍵字參數,根據效果變化進行快速瞭解作用,也可以直接通過強大的F1幫助鍵對關鍵字說明文檔進行全面的瞭解。
在我們這些關鍵字有一定認識後,就可以快速進行粒子化設計了。
第二就是逐步消失的效果,這裡的方法就有很多了:方法一可以使用PS技術,找個單側是過渡效果的蒙版圖片,利用動畫效果逐步遮住顯示內容;
方法二可以直接使用qml 中的 LinearGradient:線性過渡的方法來實現,從單側開始讓逐步隱藏,使10%的區域從透明度為0(全透明)過渡到1(不透明)狀態,然後讓這10%的區域逐漸擴大範圍,最終實現背景消失。如果希望過渡區間更加均勻可以把10%改成20%或更大。
還有很多方法可以實現這個效果,從適應性考慮採用的是後者。
3,設計內容
先說下我的開發環境:
qt5.4.2集成的Qt creator 3.4.1版本
首先創建Quick項目,如果自動創建了MainForm.ui.qml,直接刪除就可以了,我們直接在main.qml中開發就可以了。
我們在建粒子系統之前,先建立一個畫布,畫布大小填充父畫布。然後在這個畫布上添加粒子系統的基本元素:ParticleSystem、Emitter、ImageParticle和應用文件import QtQuick.Particles 2.0代碼如下:
import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Particles 2.0 Window { width: 800 height: 320 visible: true Rectangle { id: root anchors.fill: parent color: "#1f1f1f" ParticleSystem { id: myParticleSystem } Emitter { id: myEmitter system: myParticleSystem //發射器區域寬和高 width: 240 height: parent.height //發射頻率每秒500個元素 emitRate: 500 //每個元素的生命周期是1000毫秒 lifeSpan: 1000 //每個元素的大小是16*16像素 size: 16 } ImageParticle { system: myParticleSystem //Qt自帶粒子圖,可以換成自定義圖片 source: "qrc:///particleresources/fuzzydot.png" //粒子圖使用白色 color: "white" } } }
圖2(gif)
這個圖看來只有粒子,我們還需要動態飄動的效果,下麵在粒子發射器中增加如下代碼。
velocity: PointDirection { x: 150 } acceleration: PointDirection { x: 12 }
水平向右設置150像素/秒的速度,水平向右添加一個12像素/秒^2的加速。如果我們需要讓他向左發射時,可以讓x:-150,加速設置也是同理,添加一個符號就表示向左加速。如果我們需要向下發射可以y:150,同理向上發射時是y:-150。
這時我們就有了所有粒子向右飄動的界面,但是飄動狀態還比較單調。我們可以給他增加一些差異性的元素,讓元素更豐富。
讓元素在±8*8像素範圍內隨機變化
sizeVariation: 8
在velocity中增加x/y速度的隨機變化
xVariation: 60 yVariation: 20
在acceleration中增加x/y加速度的隨機變化
xVariation: 6 yVariation: 5
到此元素飄動就有了雪花飛舞的感覺了,飄動的層次均勻並且舒服。
現在感覺顏色稍微有點單調,我們可以在ImageParticle中對顏色增加隨機繫數
colorVariation: 0.1
顏色也有一定的波動了,如下圖顯示
圖3
現在我們的任務就是讓發射器一邊發射一邊向右移動,直到移動到界面外,實現飄散的元素飛舞過程。這裡我們可以使用動畫元素,讓發射器在1秒內從窗體的最左邊向右側視窗外移動,實現的代碼如下
NumberAnimation { id: myAnimation //設定動畫的目標 target: myEmitter //設定改變的屬性是x坐標 properties: "x" //x移動到父視窗的邊沿 to: root.width //在1秒內完成移動 duration: 1000 }
有了動畫代碼,我們還需要一個觸發這個動畫的事件,另外粒子系統創建後先不要發送,我們演示時通過滑鼠來激活動畫和粒子系統。
在粒子系統ParticleSystem添加如下代碼,讓粒子系統在創建時停止運行。
running: false
然後提那家數據觸發代碼
MouseArea { anchors.fill: parent //滑鼠點擊測試 onClicked: { //讓myEmitter視窗複位,這樣滑鼠可重覆點擊 if (myEmitter.x > 0) { myAnimation.stop() myEmitter.x = 0; } //激活粒子系統 myParticleSystem.restart() //激活動畫 myAnimation.restart() } }
由於每次動畫執行結束後,myEmitter視窗已經在顯示窗體以外了,那麼在點擊時先讓myEmitter視窗回到初始位置,我們就實現了點擊後重覆演示功能。
效果如下
圖4
到這裡我們第一項飄散的效果就完成了,下一步是實現背景元素逐漸消失的特效。
我們後續會用到LinearGradient元素,需要添加引用import QtGraphicalEffects 1.0。我們首先測試文字,添加如下內容。註意添加的位置,qml添加圖層的規則是先建立的(代碼行號偏小的)圖層在底層,後建立的(代碼行號偏大的)圖層在頂層,我們文字需要顯示在飄飛效果的下麵顯示,所以代碼儘量靠前放置。
Text { id:myText anchors.centerIn: parent text: "Hello world!" font.bold: true font.pixelSize: 120 font.family: "微軟雅黑" visible: false } LinearGradient { source: myText anchors.fill: myText start: Qt.point(0, 0) end: Qt.point(myText.width, 0) gradient: Gradient { GradientStop{id: myGradientStart; position: 0.0; color: "#FFFFFFFF"} GradientStop{id: myGradientEnd; position: 0.1; color: "#FFFFFFFF"} } }
代碼中Text項目被設置為隱藏。是因為我們下麵的漸變效果已經基於Text進行漸變覆蓋,我們需要顯示的是漸變的內容,Text的內容就不再被需要了,且當漸變被設置為透明時,會顯示背景的內容,這時Text如果顯示出了就不是我們所希望的效果了。
現在文本內容有了,下一步如何讓其逐步消失,我們可以用動畫控制漸變的定位。
圖5
如上圖所示,首先讓定位點myGradientStart在200毫秒內變成無色,然後讓定位點myGradientEnd移動到終點,這個過程同時讓myGradientStart跟隨移動到終點,但是他們之間需要有個時間差,消失邊界才會有個過渡區間。這裡我們可以使用順序動畫、並行動畫來組合完成這個功能。
最終代碼如下
import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Particles 2.0 import QtGraphicalEffects 1.0 Window { width: 800 height: 320 visible: true Rectangle { id: root anchors.fill: parent color: "#1f1f1f" Text { id:myText anchors.centerIn: parent text: "Hello world!" font.bold: true font.pixelSize: 120 font.family: "微軟雅黑" visible: false } LinearGradient { source: myText anchors.fill: myText start: Qt.point(0, 0) end: Qt.point(myText.width, 0) gradient: Gradient { GradientStop{id: myGradientStart; position: 0.0; color: "#FFFFFFFF"} GradientStop{id: myGradientEnd; position: 0.1; color: "#FFFFFFFF"} } } ParticleSystem { id: myParticleSystem running: false } Emitter { id: myEmitter system: myParticleSystem anchors.verticalCenter: parent.verticalCenter //發射器區域寬和高 width: 240 height: 180 //發射頻率每秒500個元素 emitRate: 500 //每個元素的生命周期是1000毫秒 lifeSpan: 1000 //每個元素的大小是16*16像素 size: 16 //元素可以在±8*8像素範圍內隨機變化 sizeVariation: 8 //元素髮射速度設置,使用點方向模式 velocity: PointDirection { //水平方式速度 150像素/秒 x: 150 //隨著變數調整 xVariation: 60 yVariation: 20 } //元素行進加速度設置,使用點方式模式 acceleration: PointDirection { x: 12 //隨著變數調整 xVariation: 6 yVariation: 5 } } ImageParticle { system: myParticleSystem //Qt自帶粒子圖,可以換成自定義圖片 source: "qrc:///particleresources/fuzzydot.png" //粒子圖使用白色 color: "white" //顏色隨機繫數 colorVariation: 0.1 } ParallelAnimation { id: myAnimation //數值動畫 NumberAnimation { //設定動畫的目標 target: myEmitter //設定改變的屬性是x坐標 properties: "x" //x移動到父視窗的邊沿 to: root.width //在1秒內完成移動 duration: 1000 } SequentialAnimation { PropertyAnimation { target: myGradientStart properties: "color" to: "#00FFFFFF" duration: 200 } ParallelAnimation { PropertyAnimation { target: myGradientEnd properties: "position" to: "1.0" duration: 1000 } PropertyAnimation { target: myGradientStart properties: "position" to: "0.9" duration: 1000 } } PropertyAnimation { target: myGradientEnd properties: "color" to: "#00FFFFFF" duration: 200 } } } MouseArea { anchors.fill: parent //滑鼠點擊測試 onClicked: { //讓myEmitter視窗複位,這樣滑鼠可重覆點擊 if (myEmitter.x > 0) { myAnimation.stop() myEmitter.x = 0; myGradientStart.position = 0.0 myGradientStart.color = "#FFFFFFFF" myGradientEnd.position = 0.1 myGradientEnd.color = "#FFFFFFFF" } //激活粒子系統 myParticleSystem.restart() //激活動畫 myAnimation.restart() } } } }
在以上代碼中簡單修改,就可以實現圖6的效果了。
4,總結
此常式主要使用的功能塊粒子系統,給粒子增加一些隨機設置參數,可以讓粒子系統顯示更自然。另外在粒子系統中還有很有趣的功能如精靈顯示、粒子影響器等等。另外一個主要的功能就是漸變功能,可以讓顏色A過渡到顏色B,及本常式中使用的從無色A過渡到有色B。
https://www.simbahiker.com/news/0220200428001.html