IOS / Core-Animation: 12 overlapping cards in a circle

I am trying to arrange 12 objects in a circle so that each overlays its neighbor counterclockwise.

Something like that:

enter image description here

The problem is that if I just rely on the drawing order, one of them will always be completely on top, in this case red at 12 o’clock.

I tried using

{ GlowButton* G = glowButton[ 0 ]; float theta = 0.3; G.layer.transform = CATransform3DMakeRotation( theta, 0, 1, 0 ); } 

When trying to rotate around a vertical axis, thereby securing one side to a neighbor, but this does not work.

I was told that this is because the main animation does not support depth testing.

Is there a way to do this without breaking into GL?

+6
source share
2 answers

I can think of two ways to avoid the problem:

  • Divide each object in half. First draw those halves that are behind adjacent objects, then draw these halves on top of the neighbors.

  • Use the clipping area and draw a circle in two steps. The first clipping region restricts drawing to the left half of the image. The second clipping region is limited to the right half. Every time you draw all the objects. But you must start at either the bottom or the top element.

I'm not quite sure what you are doing with Core Animation, so one approach may be better suited or needs some adaptation.

+6
source

Now it works fine for me. I am very glad I should not have gone to GL.

enter image description here

I basically draw the first (red - at 12 o’clock) gem with a mask, allowing me to see only the right half.

Then I draw the remaining 11.

Then I draw the first again, this time setting the mask only to display the left half.

  for( int i = 0; i <= 12; i++ ) { for ( int dullGlow = 0; dullGlow <= 1; dullGlow++ ) { BOOL isDull = ( dullGlow == 0 ) ? YES : NO; CALayer* L = [CALayer layer]; CGImageRef dullImage = [ButtonImages dullImage: i % 12]; CGImageRef glowImage = [ButtonImages glowImage: i % 12]; L.contents = (id) ( isDull ? dullImage : glowImage ); L.bounds = CGRectMake( 0, 0, buttonSize, buttonSize ); L.opacity = ( isDull ? 1.0 : 0.0 ); if( i == 0 || i == 12 ) { CGFloat halfSize = buttonSize / 2.0; CGRect keepLeftHalf = CGRectMake( 0, 0, halfSize, buttonSize ); CGRect keepRightHalf = CGRectMake( halfSize, 0, halfSize, buttonSize ); CALayer* maskLayer = [CALayer layer]; maskLayer.frame = ( i == 0 ) ? keepRightHalf : keepLeftHalf; maskLayer.backgroundColor = [UIColor greenColor].CGColor; maskLayer.edgeAntialiasingMask = 0x0; [L setMask: maskLayer]; } [self.layer addSublayer: L]; layers[ dullGlow ] [ i ] = L; } // dullGlow } // i 

Setting edgeAntialiasingMask of the 4 least significant bits to 0 smoothing members on all 4 edges - without this line I would get a seam.

I would be very grateful if someone could explain the mechanics of the masking process - although I got the right result, I did it with trial and error.

Note that the mask is set to (opaque) green, and this is the visible masking area - that is, for the first pass, the green rectangle covers the right half of the image, and it is this love that gets displayed.

I assume that for each pixel it multiplies the layer-level RGBA by the alpha value on the mask-pixel

+4
source

Source: https://habr.com/ru/post/896206/


All Articles