Qt Quick 入門 第6回: アニメーション

前回の Qt Quick 入門「第5回: 状態遷移」では状態遷移を利用して画像の位置を変更しました。今回はその画像の移動にアニメーションを追加します。

アニメーション要素

QML でアニメーションを使うには [qml Animation] を継承している要素を用います。たとえば、画像などを移動する場合には数値を変化させてアニメーションを行う [qml NumberAnimation] を用います。代表的なアニメーション要素を以下に示します。

  • [qml PropertyAnimation] — プロパティの値を変更する汎用的なアニメーション
  • [qml NumberAnimation] — 数値を変更するアニメーション
  • [qml ColorAnimation] — 色を変化させるアニメーション
  • [qml SequentialAnimation] — 複数のアニメーションを連続して実行する
  • [qml ParallelAnimation] — 複数のアニメーションを平行して実行する
  • [qml PauseAnimation] — 静止状態のアニメーション

[qml '' x e=item] や [qml '' y e=item] プロパティを用いてある要素の位置を変化させる場合、アニメーションには通常 PropertyAnimation か NumberAnimation を使います。PropertyAnimation は汎用的なアニメーションのため、座標のような数値だけでなく、色なども変化させることが出来ます。それに対して NumberAnimation は数値の変化に特化したアニメーションです。基本的にはどちらを使っていただいてもかまいませんが、パフォーマンスを考慮する場合には NumberAnimation のように専用のアニメーションを使う方がよいでしょう。
上記以外のアニメーション要素については "[qt 'Animation Elements' l=qdeclarativeanimation m=#animation-elements]" を参照してください。

アニメーションの使い方

それでは、これらのアニメーション要素の使い方をみていきましょう。QML では様々なユースケースを想定してアニメーションが利用できるように設計されています。今回はその中から、前回のサンプルのように状態遷移でプロパティが変化した際に利用するアニメーションを説明します。その他のケースについては "[qt 'QML Animation' l=qdeclarativeanimation]" を参考にしてください。

状態遷移に対応したアニメーション(Transition)

前回使用した [qml State] 要素で定義された状態を遷移する際のアニメーションを指定するには [qml Transition] 要素を用います。Transition 要素は State 要素が [qml '' states e=item] プロパティを用いて状態を定義していたように、[qml '' transitions e=item] プロパティを用いて遷移時のアニメーションを定義します。
e.g.

transitions: [
Transition {
from: "State1"
to: "State2"
NumberAnimation { target: image1; properties: "x, y"; duration: 200 }
}
]

この例では "State1" から "State2" に遷移する際にその id が image1 であるターゲット([qml '' target e=propertyanimation])の座標(x, y プロパティ([qml '' properties e=propertyanimation]))を 200 msec([qml '' duration e=propertyanimation]) かけて移動させます。 [qml '' from e=transition] や [qml '' to e=transition] は省略可能でその場合には全ての状態("*")を指定したことになります。アニメーションさせる要素の対象が複数の場合には [qml '' targets e=propertyanimation] プロパティで複数の対象を指定します。アニメーションさせるプロパティが一つの場合には [qml '' property e=propertyanimation] プロパティで指定します。target や targets も省略が可能でその場合には適切だと思われる要素を自動的に対象にします。
本来、アニメーションの実行には始点([qml '' from e=propertyanimation] プロパティ)と終点([qml '' to e=propertyanimation] プロパティ)の値がそれぞれ必要です。しかし、状態遷移に対応してアニメーションさせる場合には、どちらの値も対応する状態(State)の値から自動的に決定されます。そのため、上記の例のように from も to も記述は不要です。単体で動作させるアニメーションや SequentialAnimation で複数のアニメーションを組み合わせる場合などには必要に応じて from や to を指定してください。
ex. SequentialAnimation と組み合わせて NumberAnimation で from, to を指定する

transitions: [
Transition {
SequentialAnimation {
NumberAnimation { to: 50; properties: "x,y"; duration: 250 }
NumberAnimation { from: 50; properties: "x,y"; duration: 250 }
}
}
]

また、上記の例ではアニメーションの内容には時間しか指定していませんが、 [qml '' easing.type e=propertyanimation] などのプロパティでアニメーションの挙動を指定することが出来ます。どのようなアニメーションが指定できるかは [qml 'easing.type のドキュメント' e=propertyanimation p=easing.type] や [qt "Easing サンプル" l=declarative-animation-easing] などを参考にしてください。
それでは前回のサンプルに Transition を用いてアニメーションを追加してみましょう。
前回の「第5回 状態遷移」のリストCをベースに進めていきます。リストBでも同様の変更でアニメーションを追加できますので、リストBをベースにしたい方は適時読み替えてください。リストCを下記にもう一度掲載します。

// リストC: when プロパティによる状態遷移
import Qt 4.7

Rectangle {
id: rectangle1
property bool imageLeft: true
width: 200
height: 200
Text {
x: 66
y: 175
text: "Click"

MouseArea {
id: mouse_area1
anchors.fill: parent
onClicked: imageLeft = !imageLeft
}
}

Image {
id: image1
x: 5
y: 5
source: "http://doc.qt.nokia.com/4.7/images/declarative-qtlogo.png"
}
states: [
State {
name: "1 状態"
when: !imageLeft

PropertyChanges {
target: image1
x: 108
y: 5
}
}
]
}

アニメーションを追加していきましょう。リストCの最後(39行目)の「}」の前に以下の行を追加します。

    transitions: [
Transition {
NumberAnimation {
target: image1
properties: "x,y"
duration: 300
easing.type: Easing.OutBounce
}
}
]

transitions プロパティの書式は states プロパティと似ているのでそちらの記述も参考にしてください。
Transition を使うと遷移元の状態名(from)や遷移先の状態名(to)を指定して、それぞれに別のアニメーションを設定することも可能です。今回は遷移元も遷移先も指定していないため、どの遷移においても同じアニメーションを用います。
アニメーション追加後のコード(リストD)を以下に示します。

// リストD: Transition によるアニメーション
import Qt 4.7

Rectangle {
property bool imageLeft: true
width: 200
height: 200
Text {
x: 66
y: 175
text: "Click"

MouseArea {
id: mouse_area1
anchors.fill: parent
onClicked: imageLeft = !imageLeft
}
}

Image {
id: image1
x: 5
y: 5
source: "http://doc.qt.nokia.com/4.7/images/declarative-qtlogo.png"
}
states: [
State {
name: "1 状態"
when: !imageLeft

PropertyChanges {
target: image1
x: 108
y: 5
}
}
]
transitions: [
Transition {
NumberAnimation {
target: image1
properties: "x,y"
duration: 300
easing.type: Easing.OutBounce
}
}
]
}

変更後のQMLを実行してアニメーションが追加されていることを確認してみてください。

デフォルトアニメーションを指定する(Behavior)

[qml Behavior] 要素を利用して、ある要素のプロパティが変化した場合のアニメーションを指定しておく方法です。この方法ではプロパティの値が変化した原因によらず、アニメーションが実行されます。
e.g.

Image {
source: "http://doc.qt.nokia.com/4.7/images/declarative-qtlogo.png"
Behavior on x { NumberAnimation { duration: 300; easing.type: Easing.OutBounce }}
Behavior on y { NumberAnimation { duration: 300; easing.type: Easing.OutBounce }}
}

この例では、Image 要素の位置(x, y)が変化した場合に NumberAnimation でアニメーションを行います。Transition を使う場合と違って target プロパティは使用していませんが、Behavior の親要素である Image がアニメーションの対象となります。Behavior 要素で指定できるプロパティは一つなので、x と y の双方にアニメーションを設定する場合には二つの Behavior 要素が必要となります。
このアニメーションをリストCに追加したリストは以下のようになります。

// リストE: Behavior によるアニメーション
import Qt 4.7

Rectangle {
property bool imageLeft: true
width: 200
height: 200
Text {
x: 66
y: 175
text: "Click"

MouseArea {
id: mouse_area1
anchors.fill: parent
onClicked: imageLeft = !imageLeft
}
}

Image {
id: image1
x: 5
y: 5
source: "http://doc.qt.nokia.com/4.7/images/declarative-qtlogo.png"
Behavior on x { NumberAnimation { duration: 300; easing.type: Easing.OutBounce }}
Behavior on y { NumberAnimation { duration: 300; easing.type: Easing.OutBounce }}
}
states: [
State {
name: "1 状態"
when: !imageLeft

PropertyChanges {
target: image1
x: 108
y: 5
}
}
]
}

25, 26行に Behavior 要素を追加しています。こちらのコードも実行して、リストDと同様にアニメーションが実行されることを確認してみてください。
Behavior 要素を使ったアニメーションの指定は、プロパティが変化する原因が複数ある場合にも、まとめてアニメーションを指定することが出来るのが便利です。

まとめ

QML ではアニメーションの設定は非常に簡単に行えます。今回は NumberAnimation だけを使用しましたが、 ColorAnimation などの他のアニメーションや複数のアニメーションの組み合わせも是非試してみてください。


Blog Topics:

Comments