画像を回転させる

では、transformプロパティを使って、画像の回転をやってみよう。

アニメーションには、CABasicAnimationを使おう。先ほど説明したように、fromValueとtoValueを設定することになる。

まず、fromValueを考えよう。transformプロパティは行列なので、開始の値は単位行列にする。単位行列は、CATransform3DIdentityという定数があるので、これを使おう。

toValueには、y軸に反転させたものを指定してみよう。CATransform3Dを回転させるために、CATransform3DMakeRotation()という関数が用意されている。これで、toValueも作ることが出来る。

最後に、これらの値をObjective-Cオブジェクトにする必要があるのだが、そのためにNSValueが拡張されている。valueWithCATransform3D:メソッドを使うことが出来る。

これらを使えば、y軸で画像を回転させるアニメーションは、次のようになる。

// アニメーションを作成する
CABasicAnimation*   animation;
animation = [CABasicAnimation animationWithKeyPath:@"transform"];

// アニメーションのプロパティを設定する
animation.duration = 0.5f;
animation.autoreverses = YES;
animation.repeatCount = 4;

CATransform3D   transform;
transform = CATransform3DIdentity;
animation.fromValue = [NSValue valueWithCATransform3D:transform];

transform = CATransform3DMakeRotation(M_PI, 0, 1.0f, 0);
animation.toValue = [NSValue valueWithCATransform3D:transform];

// レイヤーにアニメーションを追加する
[layer addAnimation:animation forKey:@"transformAnimation"];

実行結果は、次のようになる。地球がクルクルと回る様が分かるだろう。

なお、ここまでのプロジェクトはこちらからダウンロードできる。

3次元らしく回転させる

先ほどの回転だが、実はうまく見せかけるために、ちょっとしたトリックがある。

まず、背景のレイヤーが黒で、地球の画像の背後も黒である。そして、回転する画像が円である。これらの条件があるから、違和感のない回転が出来ている。

では、普通の四角い画像だったらどうだろう。試してみたのが、次の結果である。

なるほど。確かに回転している。だが、何か変だ。自然な回転というには、違和感があるだろう。

これは、回転したときに透視図法になっていないからだ。奥行きが感じられないため、妙な回転になっている。

そこで、少し味付けをしてみよう。ソースコードのtoValueの値を、次のように修正してみる。

transform = CATransform3DMakeRotation(M_PI, 0, 1.0f, 0);
transform.m34 = 1.0f / -420.0f;
animation.toValue = [NSValue valueWithCATransform3D:transform];

transformプロパティは4x4の行列であるCATransform3D型なのだが、そのm34要素に値を設定してやる。これにより、3次元的な奥行きの表現が出来るようになる。

なお、ここまでのプロジェクトはこちらからダウンロードできる。

これで、だいぶ「らしく」なってきた。Dashboardでのウィジェットの裏面表示や、iPhoneでのアルバム画像の裏面表示に近づいてきた。