Я пытаюсь создать простое приложение для iPhone, которое отображает изображение с отражением внизу, и я хочу повернуть изображение вокруг оси X, используя Core Animation.
Я начал с создания нового приложения для iPhone с использованием шаблона «Просмотреть приложение». Я добавил файл изображения «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
равным нулю для обоих слоев, тогда картинка и отражение выглядят идеально синхронизированными. Поэтому я не думаю, что проблема связана с проблемами синхронизации времени.
Я подозреваю, что в моих перспективных трансформациях чего-то не хватает, но я не уверен, как определить, что не так. Я думаю, что в основном я делаю то же преобразование, описанное в этом связанном вопросе переполнения стека .
Может кто-нибудь помочь?