Qt Quick中的動畫和過渡簡介

語言: CN / TW / HK

theme: channing-cyan

本文已參加【新人創作禮】活動,一起開啟掘金創作之路。


📒部落格首頁:何名取 的個人主頁 - 文章 - 掘金 (juejin.cn)\ 🎉歡迎關注🔎點贊👍收藏⭐️留言📝\ ❤️期待一起交流!\ 🙏作者水平很有限,如果發現錯誤,求告知,多謝!\ 🌺有問題可私信交流!!!


Qt Quick中的動畫和過渡

前言

本節對Qt Quick中的動畫和過渡從總體角度上進行了介紹,並對其中的子型別簡單做了示例。

動畫和過渡型別

  • Transition - 在狀態變化期間用動畫來轉換
  • SequentialAnimation - 按順序執行動畫
  • ParallelAnimation - 並行執行動畫
  • Behavior - 為屬性更改指定預設動畫
  • PropertyAction - 在動畫期間立即更改屬性
  • PauseAnimation - 在動畫中引入暫停
  • SmoothedAnimation - 使屬性值平滑地改變
  • SpringAnimation - 使屬性值彈性地變動
  • ScriptAction - 在動畫中執行指令碼

基於資料型別對屬性進行動畫處理的型別: 型別|描述 ---|--- AnchorAnimationAnimates|當錨點變化時產生動畫效果。 ColorAnimationAnimates |當顏色變化時產生動畫效果。 NumberAnimationAnimates|當數值改變時產生動畫效果。 ParentAnimationAnimates |當Item的父級更改時產生動畫效果。 PathAnimationAnimates |當item沿路徑運動時產生動畫。 PropertyAnimationAnimates|當屬性時產生動畫效果。 RotationAnimationAnimates |控制旋轉方向。 Vector3dAnimationAnimates |當Vector3d值改變時產生動畫效果。

通過將動畫型別應用到屬性值來建立動畫。動畫型別將插值屬性值來建立平滑的過渡。同樣,狀態轉換也可以為狀態變化分配動畫。例如,將動畫應用到屬性x座標值的變化上,當x從0到100時,在0到100中間插入50個數來形成動畫效果,而不是直接從0變化到100。

觸發動畫

有幾種方法可以將動畫設定為物件。

直接指定屬性的動畫

動畫是通過將動畫物件應用到屬性值來建立的,以便隨著時間的推移逐漸改變屬性。這些屬性動畫通過在屬性值變化之間插入值來應用平滑的移動。屬性動畫提供了計時控制,並允許通過緩動曲線進行不同的插值。 ``` Rectangle { id: flashingblob width: 75; height: 75 color: "blue" opacity: 0.1

 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.1
     to: 1.0
     loops: Animation.Infinite
     easing {type: Easing.OutBack; overshoot: 500}
}

} ``` 最開始將矩形塊的顏色設定為藍色,透明度設定為0.1。當滑鼠點選時改變這兩個屬性。其中顏色屬性使用PropertyAnimation,透明度屬性使用NumberAnimation。 donghua1.gif

專門化的屬性動畫型別比PropertyAnimation型別有更有效的實現。它們用於將動畫設定為不同的QML型別,如int, color和rotations,對應的是NumberAnimationAnimates,ColorAnimationAnimates和RotationAnimationAnimates。類似地,ParentAnimation可以對父元素的更改進行動畫處理。

使用預定義的目標和屬性

在前面的示例中,PropertyAnimation和NumberAnimation物件需要指定特定的目標和屬性值,以指定應該被動畫化的物件和屬性。這可以通過使用\ on \語法來避免,該語法指定將動畫應用為屬性值源。

下面是兩個使用此語法指定的PropertyAnimation物件: ``` import QtQuick 2.0

Rectangle {
    id: rect
    width: 100; height: 100
    color: "red"
    MouseArea {
        anchors.fill: parent
        onClicked: {
            xp.running = true
            yp.running = true
        }
    }
    PropertyAnimation on x { id:xp; running: false; to: 100 }
    PropertyAnimation on y { id:yp; running: false; to: 100 }
}

``` 動畫在滑鼠點選後立即開始,並自動應用於它的x和y值。由於已經使用了\ on \語法,因此不需要設定要糾正的PropertyAnimation物件的目標值,也不需要將屬性值設定為x和y。

donghua2.gif

這也可以用於分組動畫,以確保組內的所有動畫都應用於相同的屬性。例如,前面的例子可以使用SequentialAnimation來使矩形的顏色先變為黃色,然後變為藍色: ``` import QtQuick 2.0

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

 SequentialAnimation on color {
     ColorAnimation { to: "yellow"; duration: 1000 }
     ColorAnimation { to: "blue"; duration: 1000 }
 }

} ``` 由於SequentialAnimation物件已在color屬性上使用\ on \語法指定,它的子ColorAnimation物件也自動應用於此屬性,不需要指定目標或屬性值。

donghua3.gif

狀態變化期間的過渡

Qt Quick States是屬性配置,其中一個屬性可以有不同的值來反映不同的狀態。太過劇烈的狀態變化會帶來突然的屬性變化,使用動畫平滑過渡會產生視覺上更吸引人的狀態變化。

過渡型別可以包含動畫型別來插值由狀態變化引起的屬性變化。若要將過渡分配給物件,請將其繫結到transitions屬性。

``` Rectangle { width: 75; height: 75 id: button state: "RELEASED"

    MouseArea {
        anchors.fill: parent
        onPressed: button.state = "PRESSED"
        onReleased: button.state = "RELEASED"
    }

    states: [
        State {
            name: "PRESSED"
            PropertyChanges { target: button; color: "DarkBlue"}
        },
        State {
            name: "RELEASED"
            PropertyChanges { target: button; color: "SkyBlue"}
        }
    ]

    transitions: [
        Transition {
            from: "PRESSED"
            to: "RELEASED"
            ColorAnimation { target: button; duration: 100}
        },
        Transition {
            from: "RELEASED"
            to: "PRESSED"
            ColorAnimation { target: button; duration: 100}
        }
    ]
}

按鈕可能有兩個狀態,當用戶單擊按鈕時為按下狀態,當用戶釋放按鈕時為釋放狀態。我們可以為每個狀態分配不同的屬性配置。轉換將使從按下狀態到釋放狀態的變化具有動畫效果。同樣,在從釋放狀態到按下狀態的變化期間,也會有一個動畫。 ![donghua4.gif](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eba0d12a786740858819d0c941477485~tplv-k3u1fbpfcp-watermark.image?) 將to和from屬性繫結到狀態名稱將把特定的過渡分配給狀態更改。對於簡單或對稱過渡,將to屬性值設定為萬用字元“*”表示該轉換適用於任何狀態更改。 transitions: Transition { to: "*" ColorAnimation { target: button; duration: 100} } ```

為行為的指定預設動畫

預設的屬性動畫是使用行為動畫設定的。在行為型別中宣告的動畫應用於屬性,並且動畫任何屬性值的變化。然而,行為型別有一個enabled屬性來有意地啟用或禁用行為動畫。

``` Rectangle { width: 75; height: 75; radius: width id: ball color: "lightsteelblue"

Behavior on x {
    NumberAnimation {
        id: bouncebehavior
        easing {
            type: Easing.OutElastic
            amplitude: 1.0
            period: 0.5
        }
    }
}
Behavior on y {
    animation: bouncebehavior
}
Behavior {
    ColorAnimation { target: ball; duration: 300 }
}

} ``` 小球元件將行為動畫分配給它的x, y和顏色屬性。行為動畫可以設定為模擬彈性效果。實際上,每當球移動時,這個行為動畫就會將彈性效果應用到屬性中。

donghua5.gif 有幾種方法可以將行為動畫分配給屬性。Behavior on \宣告是將行為動畫分配到屬性上的一種簡便方式。

並行或順序播放動畫

動畫可以並行執行,也可以順序執行。並行動畫會同時播放一組動畫,而順序動畫會依次播放一組動畫。在SequentialAnimation和ParallelAnimation中分組動畫將按順序或並行播放動畫。

``` Rectangle { id: banner width: 150; height: 100; border.color: "black"

    Column {
        anchors.centerIn: parent
        Text {
            id: code
            text: "Code less."
            opacity: 0.01
        }
        Text {
            id: create
            text: "Create more."
            opacity: 0.01
        }
        Text {
            id: deploy
            text: "Deploy everywhere."
            opacity: 0.01
        }
    }

    MouseArea {
        anchors.fill: parent
        onPressed: playbanner.start()
    }

    SequentialAnimation {
        id: playbanner
        running: false
        NumberAnimation { target: code; property: "opacity"; to: 1.0; duration: 200}
        NumberAnimation { target: create; property: "opacity"; to: 1.0; duration: 200}
        NumberAnimation { target: deploy; property: "opacity"; to: 1.0; duration: 200}
    }
}

``` 橫幅元件可以一個接一個地顯示多個圖示或口號。不透明屬性可以轉換為1.0,表示不透明物件。使用SequentialAnimation型別,不透明度動畫將在前面的動畫完成後播放。ParallelAnimation型別將同時播放動畫。

donghua6.gif 一旦單個動畫被放置到SequentialAnimation或ParallelAnimation中,它們就不能再獨立地啟動和停止了。順序或並行動畫必須作為一個組啟動和停止。

SequentialAnimation型別對於播放轉場動畫也很有用,因為動畫是在轉場內部並行播放的。

控制動畫

下面有幾種控制動畫的方法。

動畫播放

所有動畫型別都繼承自動畫型別。該型別提供了動畫型別的基本屬性和方法。動畫型別有start()、stop()、resume()、pause()、restart()和complete()——所有這些方法都控制動畫的執行。

緩動

緩動曲線定義了動畫如何在開始值和結束值之間插值。不同的緩動曲線可能會超出內插的限定範圍。緩動曲線簡化了動畫效果的建立,如反彈效果、加速、減速和迴圈動畫。

一個QML物件對於每個屬性動畫可能有不同的緩動曲線。也有不同的引數來控制曲線,其中一些是特定曲線獨有的。

其他型別的動畫

此外,QML還提供了其他一些對動畫有用的型別: - PauseAnimation: 在動畫期間啟用暫停 - ScriptAction: 允許JavaScript在動畫過程中執行,並可以與StateChangeScript一起使用來重用現有的指令碼 - PropertyAction: 在動畫期間立即更改屬性,而不對屬性更改進行動畫化

這些是特殊的動畫型別,用於動畫不同的屬性型別: - SmoothedAnimation: 一種專門的數字動畫,當目標值發生變化時,它提供動畫中的平滑變化 - SpringAnimation: 提供具有特殊屬性(如質量和阻尼)的類似彈簧的動畫 - ParentAnimation: 用於動畫父級的改變 - AnchorAnimation: 用於動畫錨的變化

動畫例項的共享

不支援在Transitions過渡或behavior行為之間共享動畫例項,這可能導致未定義的行為。在下面的例子中,矩形位置的改變很可能不會被正確的動畫化。 Rectangle { // NOT SUPPORTED: this will not work correctly as both Behaviors // try to control a single animation instance NumberAnimation { id: anim; duration: 300; easing.type: Easing.InBack } Behavior on x { animation: anim } Behavior on y { animation: anim } } 最簡單的解決方法是為兩個行為重複NumberAnimation。如果重複的動畫相當複雜,你也可以考慮建立一個自定義動畫元件,併為每個行為分配一個例項,例如: Rectangle { component MyNumberAnimation : NumberAnimation { duration: 300; easing.type: Easing.InBack } Behavior on x { MyNumberAnimation {} } Behavior on y { MyNumberAnimation {} } }

donghua7.gif