3D回転いわゆる Flip アニメーションを CoreAnimation で実装しようと思い調べてみた。
- (void)animationTransform:(UIView *)view :(float)duration :(float)delay {
CABasicAnimation* animation;
animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.duration = duration;
//animation.beginTime = delay;
//animation.autoreverses = YES;
animation.repeatCount = 0;
CATransform3D transform;
transform = CATransform3DIdentity;
animation.fromValue = [NSValue valueWithCATransform3D:transform];
transform = CATransform3DMakeRotation(M_PI, 0, 1.0f, 0);
animation.toValue = [NSValue valueWithCATransform3D:transform];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[view.layer addAnimation:animation forKey:@"transformAnimation"];
}
プロパティベースのアニメーション のドキュメントを参考にしました。
(1) CABasicAnimation animationWithKeyPath: でアニメーションを作成 単純なアニメーションは CABasicAnimation 、複数実行させたい場合は CAAnimation を利用するようです。 引数は String型のプロパティで、CALayer Class Reference によると種類は以下のものがあるようです
frame property bounds property position property zPosition property anchorPointZ property anchorPoint property contentsScale property affineTransform setAffineTransform: transform property sublayerTransform property
(2) fromValue で始点 (3) 変換関数などでアニメーション座標を作成
CATransform3DMakeTranslation '(tx, ty, tz)'の平行移動を行う変換を返します CATransform3DTranslate 't'を'(tx, ty, tz)'だけ平行移動して、その結果を返します CATransform3DMakeScale `(sx, sy, sz)'の拡大縮小を行う変換を返します CATransform3DScale 't'を'(sx, sy, sz)'だけ拡大縮小し、その結果を返します CATransform3DMakeRotation ベクトル'(x, y, z)'を中心にしてラジアン'angle'分の回転をする変換を返します。ベクトルの長さがゼロの場合は同一変換が返されます。 CATransform3DRotate ベクトル'(x, y, z)'を中心にして't'をラジアン'angle'だけ回転し、その結果を返します
(4) toValue で作成したアニメーション座標で終点を設定 (5) duration で長さ指定 (6) layer addAnimation: でアニメーション追加
(1) transform で CABasicAnimation を作成し、CATransform3DIdentity で 3D座標を fromValue に設定 (2) CATransform3DMakeRotation() で 回転座標を作成し、toValue に設定 ※第1引数は回転(π で半回転)、第2,3,4 引数は中心点 (x, y, z) になります
アニメーションの easing のような時間調整は、CAMediaTimingFunction で設定します。 タイミング、時空間、CAAnimation のドキュメントを見てみると、あらかじめ定数で用意されています。
kCAMediaTimingFunctionLinear kCAMediaTimingFunctionEaseIn kCAMediaTimingFunctionEaseOut kCAMediaTimingFunctionEaseInEaseOut
カスタムで指定する事もでき、ベジェ曲線の原理で設定するみたいです。
CAMediaTimingFunction *customTimingFunction;
customTimingFunction=[CAMediaTimingFunction functionWithControlPoints:0.25f :0.1f :0.25f :1.0f];