Core Animationの中で視点変換を使用するために失敗しました
-
20-09-2019 - |
質問
私は下に反射して画像を表示するシンプルなiPhoneアプリを作成しようとしている、と私はCore Animationのを使用して、X軸を中心に画像を回転します。
私は、「ビューベースのアプリケーション」テンプレートを使用して新しいiPhoneアプリを作成することで始めました。 I「がPicture.jpg」画像ファイルを追加し、その後、私は、ビューコントローラにこれを追加します:
- (void)awakeFromNib {
CGFloat zDistance = 1500.0f;
// Create perspective transformation
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0f / -zDistance;
// Create perspective transform for reflected layer
CATransform3D reflectedTransform = CATransform3DMakeRotation(M_PI, 1.0f, 0.0f, 0.0f);
reflectedTransform.m34 = 1.0f / -zDistance;
// Create spinning picture
CALayer *spinningLayer = [CALayer layer];
spinningLayer.frame = CGRectMake(60.0f, 60.0f, 200.0f, 300.0f);
spinningLayer.contents = (id)[UIImage imageNamed:@"Picture.jpg"].CGImage;
spinningLayer.transform = transform;
// Create reflection of spinning picture
CALayer *reflectionLayer = [CALayer layer];
reflectionLayer.frame = CGRectMake(60.0f, 360.0f, 200.0f, 300.0f);
reflectionLayer.contents = (id)[UIImage imageNamed:@"Picture.jpg"].CGImage;
reflectionLayer.opacity = 0.4f;
reflectionLayer.transform = reflectedTransform;
// Add layers to the root layer
[self.view.layer addSublayer:spinningLayer];
[self.view.layer insertSublayer:reflectionLayer below:spinningLayer];
// Spin the layers
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
anim.fromValue = [NSNumber numberWithFloat:0.0f];
anim.toValue = [NSNumber numberWithFloat:(2 * M_PI)];
anim.duration = 3.0f;
anim.repeatCount = 1e100f;
[spinningLayer addAnimation:anim forKey:@"anim"];
[reflectionLayer addAnimation:anim forKey:@"anim"];
}
こののほとんどの作品。問題は、メイン画面の反射の回転が完全に同期されていないということです。これは完璧に非常に近いですが、画像の下の反射の上部の縁は、離れて数ピクセルです。彼らは数度によって異なるように見えます。
画面の左側には、反射は、画像の「先」であるように思われ、右側には、反射は絵の背後にあります。上部画像の底角がスクリーンに向かって押されるように反射の頂角が視聴者に向かって引っ張られながら、言い換えれば、それは、見えます。彼らはスピンとして前面にし、画像の裏を見ているとき、これは本当です両方ます。
私はzDistance
を増やす場合は、、効果はあまり顕著です。私は両方の層のためにゼロに等しいtransform.m34
を残して完全に透視変換を排除する場合は、画像及び反射外観は完全に同期されます。だから私はこの問題は、時刻同期の問題に関連しているとは思いません。
私は私の透視変換は何かが欠けている疑いがあるが、私は間違っているかを決定するかどうかはわかりません。私は基本的にこの関連スタックオーバーフローの質問をhref="https://stackoverflow.com/questions/347721/uiview-perspective-transform">
誰かが助けることはできますか?
解決
私は、私は私の質問への答えを見つけたかもしれないと思います。私の元のコードでは、Iピクチャの下に置き、そしてフリップ及び視点を適用することにより、反射を作成しました。それを行うための正しい方法は、画像と同じ位置での反射を置いて平行移動と回転が適切な場所にそれを得るために変換適用し、透視変換を適用することのようです。
スピンをアニメートする場合、それは画像のアニメーションの反対方向に反射を回転させる必要がある。
だから、ここ動作するコードです。
- (void)awakeFromNib {
CGFloat zDistance = 1500.0f;
// Create perspective transformation
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0f / -zDistance;
// Create perspective transform for reflected layer
CATransform3D reflectedTransform = CATransform3DMakeTranslation(0.0f, 300.0f, 0.0f);
reflectedTransform = CATransform3DRotate(reflectedTransform, M_PI, 1.0f, 0.0f, 0.0f);
reflectedTransform.m34 = 1.0f / -zDistance;
// Create spinning picture
CALayer *spinningLayer = [CALayer layer];
spinningLayer.frame = CGRectMake(60.0f, 60.0f, 200.0f, 300.0f);
spinningLayer.contents = (id)[UIImage imageNamed:@"Picture.jpg"].CGImage;
spinningLayer.transform = transform;
// Create reflection of spinning picture
CALayer *reflectionLayer = [CALayer layer];
reflectionLayer.frame = CGRectMake(60.0f, 60.0f, 200.0f, 300.0f);
reflectionLayer.contents = (id)[UIImage imageNamed:@"Picture.jpg"].CGImage;
reflectionLayer.opacity = 0.4f;
reflectionLayer.transform = reflectedTransform;
// Add layers to the root layer
[self.view.layer addSublayer:spinningLayer];
[self.view.layer insertSublayer:reflectionLayer below:spinningLayer];
// Spin the layers
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
anim.fromValue = [NSNumber numberWithFloat:0.0f];
anim.toValue = [NSNumber numberWithFloat:(2 * M_PI)];
anim.duration = 3.0f;
anim.repeatCount = 1e100f;
[spinningLayer addAnimation:anim forKey:@"anim"];
CABasicAnimation *reflectAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
reflectAnim.fromValue = [NSNumber numberWithFloat:0.0f];
reflectAnim.toValue = [NSNumber numberWithFloat:(-2 * M_PI)];
reflectAnim.duration = 3.0f;
reflectAnim.repeatCount = 1e100f;
[reflectionLayer addAnimation:reflectAnim forKey:@"reflectAnim"];
}
私はこの作品正確な理由はわかりません。それは何とかそれを変換すると、同じ「変換空間」に2枚の画像を置き、誰かがこの背後に数学を説明することができれば、私はそれを感謝し、元と同じ位置での反射を置くように私には直感的に理にかなっています。
フルプロジェクトはGitHubのに利用可能である: https://github.com/kristopherjohnson/perspectivetestする
他のヒント
あなたは<のhref = "http://developer.apple.com/mac/library/documentation/GraphicsImaging/Reference/CAAnimationGroup_class/Introduction/Introduction.html#//apple_ref/occ/cl/CAAnimationGroup" を使用することができますrelが=「nofollowをnoreferrer」> CAAnimationGroup
は、同じ時間間隔で2つのアニメーションを実行するために、オブジェクト。これは、任意の同期の問題の世話をする必要があります。
の の編集:のの愚かなコードを削除
。