カバーフロー風のエフェクト

先日作成したウィンドウを使ってカバーフロー風のエフェクトを作ってみました。

動作サンプルソースコードはそれぞれリンク先にて。

エフェクト時のアニメーションのアルゴリズム(計算式?)はJavaFXサンプルを参考にしました。

PerspectiveTransform

今回のポイントは透視変換(Perspective Transform)です。
透視変換とは遠近法などを使いオブジェクトを立体的に見せる手法です。JavaFXでは平面(シーングラフ)を簡単に3D風に変換するエフェクトであるPerspectiveTransformが用意されているので、これを使用します。
本来の透視変換では視点・焦点などを元に行列を作成し座標変換する・・・というものですが、JavaFXでは非常にシンプルな形で定義できます。

effect: bind PerspectiveTransform {
    ulx: bind lx, uly: bind uly
    urx: bind rx, ury: bind ury
    llx: bind lx, lly: bind ury + height
    lrx: bind rx, lry: bind uly + height
}

ここではbindを使っているので良くわからないかもしれませんが、ulx(upper left X)、uly(upper left Y)...uly(under left Y)という4点を指定するだけです。この4点で囲まれた矩形の中に投射するような形でシーングラフが表示されます。したがって、この4点を台形としZ軸を少し考慮してあげればスクリーンショットのような形にすることができるわけです。

アニメーション

アニメーションをスムーズにおこうなうためにsinカーブを用いています。

    var angle:Number = 45;
    var lx:Number = bind width/2 - Math.sin(Math.toRadians(angle)) * width/2;
    var rx:Number = bind width/2 + Math.sin(Math.toRadians(angle)) * width/2;
    var uly:Number = bind 0 - Math.cos(Math.toRadians(angle)) * height / 10;
    var ury:Number = bind 0 + Math.cos(Math.toRadians(angle)) * height / 10;

angle(角度)は45℃の時が左側の状態、90°が中央、135°が右側です。90°の時にlxとlyはちょうどwidthとなり、角度を変化させる事で自然に立体的に変化していきます。この角度変化はTimelineで行うというわけです。