I'm trying to create a simple iPhone application that displays an image with a reflection at the bottom, and I want to rotate the image around the X axis using Core Animation.
I started by creating a new iPhone application using the App-Based View template. I added the image file "Picture.jpg" and then added it to the view controller:
- (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"]; }
It almost works. The problem is that the rotation of the main picture and reflection are not perfectly synchronized. It is very close to perfection, but the edges of the lower part of the image and the peaks of reflection are at a distance of several pixels from each other. It seems that they differ by several degrees.
On the left side of the screen, the reflection appears โin frontโ of the image, and on the right side it is reflected behind the picture. In other words, it seems that the lower corners of the upper image are pushed toward the screen, and the upper corners of the reflection are pulled towards the viewer. This is true both when viewed from the front and the back of the images as they rotate.
If I increase zDistance , the effect will be less noticeable. If I completely exclude perspective transformations, leaving transform.m34 equal to zero for both layers, then the image and reflection look perfectly synchronized. Therefore, I do not think that the problem is related to time synchronization problems.
I suspect that my prospective transformations are missing something, but I'm not sure how to determine what is wrong. I think I'm basically doing the same transformation described in in this related question .
Can anyone help?