4.6がやってきた-Qt最新事情2010

第2回 Qt 4.6のアニメーションフレームワーク[前編]

この記事を読むのに必要な時間:およそ 5 分

アニメーション可能なプロパティ

先の例では,ラベルのposプロパティを変更して,その位置を動かしました。アニメーションの時間とその開始値と終了値を指定しただけで,自動的に滑らかに動くように位置が変更されました。開始値は,QVariantAnimationクラスのstartValueプロパティで,終了値はendValueプロパティ。共に型はQVariantです。つまり,QVariant型の2つの値間を補間して,アニメーションが行われていることになります。

QVariantには,QStringやQPixmapなども格納できますが,このような型のプロパティには,自明な補間方法がないので,プロパティのアニメーションの対象ではありません。アニメーション可能なプロパティの型は,表1のようになっています。

表1 アニメーション対応のプロパティ一覧

メタタイプ実際の型
QMetaType::Intint
QMetaType::Doubledouble
QMetaType::Floatfloat
QMetaType::QLineQLine
QMetaType::QLineFQLineF
QMetaType::QPointQPoint
QMetaType::QSizeQSize
QMetaType::QSizeFQSizeF
QMetaType::QRectQRect
QMetaType::QRectFQRectF

したがってQWidgetでは,表1に挙げた型を持つプロパティ,たとえばpos(QPoint)⁠geometry(QRect)⁠windowOpacity(double)などのプロパティがアニメーションの対象になります。最初のサンプルプログラムでは,posプロパティを変更してラベルを横方向に移動しているので,xプロパティをアニメーションしても同様な効果が得られます。

キーバリューによるアニメーション速度の変更

一定の速度でラベルを移動させるのではなく,キーバリュー指定によって,アニメーションの速度を変更してみましょう。リスト1の68~73行目を次のように変更します。

リスト2 ラベル移動速度を変化させる場合の変更点

68:     d->labelAnimation = new QPropertyAnimation( movableLabel, "pos", this );
69:     d->labelAnimation->setDuration( 5 * 1000 );
70:     int movableLabelStartX = d->horizontalOffset;
71:     int movableLabelEndX = width() - movableLabel->sizeHint().width() - d->horizontalOffset;
72:     int movableLabelInterimX = movableLabelStartX + ( movableLabelEndX - movableLabelStartX ) * 9 / 10;
73:     d->labelAnimation->setKeyValueAt( 0.0, QPoint( movableLabelStartX, movableLabelY ) );
74:     d->labelAnimation->setKeyValueAt( 0.5, QPoint( movableLabelInterimX, movableLabelY ) );
75:     d->labelAnimation->setKeyValueAt( 1.0, QPoint( movableLabelEndX, movableLabelY ) );

setStartValue()とsetEndValue()の代わりにsetKeyValueAt()を用いて,第一引数で時間経過の割合を0.0から1.0の間の値で指定し,第二引数で対応する経過値を指定します。この場合には図3に示すように,アニメーション時間が5秒で,0.5の割合の時間経過での経過値を9割の位置にしているので,アニメーションの開始から 2.5秒経過した時刻で,9割の移動が行われるようになります。

図3 キーバリューによる速度変更の概要

図3 キーバリューによる速度変更の概要

この修正をしたサンプルプログラムを動作させると,次のようなアニメーションになります。

移動速度が変化するアニメーション

イージングによるアニメーション速度の変更

イージングとは,ボールが跳ねたりする動きのように,加速度を考慮したアニメーションをを実現する方法です。イージングによって,加速,減速,加減速,跳ねるなどのアニメーション効果を得られます。この場合は,リスト1の68行目~を次のように変更します。

リスト3 イージングによる速度コントロールを可能にさせる

68:     d->labelAnimation = new QPropertyAnimation( movableLabel, "pos", this );
69:     d->labelAnimation->setDuration( 5 * 1000 );
70:     int movableLabelStartX = d->horizontalOffset;
71:     int movableLabelEndX = width() - movableLabel->sizeHint().width() - d->horizontalOffset;
72:     d->labelAnimation->setStartValue( QPoint( movableLabelStartX, movableLabelY ) );
73:     d->labelAnimation->setEndValue( QPoint( movableLabelEndX, movableLabelY ) );
74:     d->labelAnimation->setEasingCurve( QEasingCurve::OutBounce );

最初のサンプルプログラム(リスト1)に74 行目の行を追加すると,横向きの移動ですが,次の動画のように,跳ねるようなアニメーション効果が得られます。

イージングを使うには,setEasingCurve() で,イージングカーブをアニメーションに指定します。ここで指定している QEasingCurve::OutBounce は,アニメーション動作が終了する前(Out)に,跳ねる(Bounce)ように位置が変わります。

Qtでは,Robert PennerのイージングカーブをQEasingCurveで実装しています。イージングは,表2の4つの加速/減速方法と10種類の補間曲線を組み合わせて,40種類あります。

表2 イージングの種類

加速と減速方法
In加速
Out減速
InOut加速後に減速
OutIn減速後に加速
補間曲線
Sine正弦曲線に沿う
Quad2 次曲線に沿う
Cubic3 次曲線に沿う
Quart4 次曲線に沿う
Quint5 次曲線に沿う
Expo指数曲線に沿う
Circ円弧に沿う
Elastic弾む動き
Back行き過ぎて戻る動き
Bounce跳ねる動き

Qtで用意されているイージングには,これらに加えLinear(加減速のない線形補間)や,ユーザ定義のCustomがあります。Qtのパッケージ中のexamples/animation/easingディレクトリにあるEasing Curves Exampleで,イージングカーブが適用されたアニメーションの動作を確かめられます。

著者プロフィール

杉田研治(すぎたけんじ)

1955年生まれ。東京都出身。株式会社SRAに勤務。プログラマ。

仕事のほとんどをMac OS XとKubuntu KDE 4でQtと供に過ごす。