How to make CALayers use the center of the screen as a vanishing point for 3D transformations?

I have a 2D grid of views (I will name them tiles) on the screen. Each tile has a subspecies that I rotate around the Y axis in the animation block. I set the Transform sublayer on each tile correctly. All the subzones that I rotate exhibit a three-dimensional perspective. The problem is that the drop point for each of them is the center of the tile instead of the center of the screen, violating the illusion of 3D. When I set the sublayerTransform to the parent of all the fragments, the rotating views have no perspective. I believe this is because sublayerTransform applies only to child layers, not grandchildren. How to make all rotating views use the same point of convergence? I included a poorly drawn image to help illustrate the point. enter image description here

+4
source share
4 answers

Here's the solution: you need to add the broadcast to the superlayer, and then make up for it by adjusting the position of the sublevel. I successfully used the following code snippet, just creating an empty โ€œSingle View Applicationโ€ Xcode project and running it on the iPad simulator:

- (void)viewDidLoad { [super viewDidLoad]; for (int i = 0; i < 6; i++) { CALayer *parent = [CALayer layer]; parent.frame = CGRectMake(0, 0, 100, 100); parent.position = CGPointMake(70 + 120*i, 70); parent.backgroundColor = [[UIColor greenColor] CGColor]; [self.view.layer addSublayer:parent]; float width = self.view.frame.size.width/2.0; float offset = (width - parent.position.x); CALayer *layer = [CALayer layer]; layer.frame = CGRectMake(0, 0, 40, 40); layer.position = CGPointMake(-offset + 50, 60); layer.backgroundColor = [[UIColor redColor] CGColor]; layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0); CATransform3D tr = CATransform3DMakeTranslation(offset, 0, 0); CATransform3D t = CATransform3DIdentity ; t.m34 = -4.0f/2000.0f ; parent.sublayerTransform = CATransform3DConcat(t, tr); [parent addSublayer:layer]; } } 
+1
source

This is a rather difficult problem. I suggest you look and see how others have decided this. Take a look at Nick Lockwood's iCarousel . This is a carousel implementation that may give you some idea.

0
source

Have you tried setting sublayerTransform to the parent element of the tile, but using CATransformLayer for the fragments? This should spread the sublayerTransform further down the hierarchy. Please note that CATransformLayer only makes its own sublayers, not any content / background colors of its own, so everything you did in the tile itself might need to be moved to a separate sublayer.

0
source

Try turning the tiles themselves, not their subzones. In your view of your tile views, set the perspective transform:

 CATransform3D t = kCATransform3DIdentity ; t.m34 = -1.0f/2000.0f ; parentLayer.sublayerTransform = t ; 

Will this work? Although I assume that you obviously do not want to rotate the tiles themselves?

0
source

All Articles