Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is not a simple one. I can get you a good bit of the way there. It's the animating that is tricky. Here's the output of some code I threw together:</p> <p><img src="https://i.stack.imgur.com/CMnRP.png" alt="Inverted Mask Layer"></p> <p>The code is like this:</p> <pre><code>- (void)viewDidLoad { [super viewDidLoad]; // Create a containing layer and set it contents with an image CALayer *containerLayer = [CALayer layer]; [containerLayer setBounds:CGRectMake(0.0f, 0.0f, 500.0f, 320.0f)]; [containerLayer setPosition:[[self view] center]]; UIImage *image = [UIImage imageNamed:@"cool"]; [containerLayer setContents:(id)[image CGImage]]; // Create your translucent black layer and set its opacity CALayer *translucentBlackLayer = [CALayer layer]; [translucentBlackLayer setBounds:[containerLayer bounds]]; [translucentBlackLayer setPosition: CGPointMake([containerLayer bounds].size.width/2.0f, [containerLayer bounds].size.height/2.0f)]; [translucentBlackLayer setBackgroundColor:[[UIColor blackColor] CGColor]]; [translucentBlackLayer setOpacity:0.45]; [containerLayer addSublayer:translucentBlackLayer]; // Create a mask layer with a shape layer that has a circle path CAShapeLayer *maskLayer = [CAShapeLayer layer]; [maskLayer setBorderColor:[[UIColor purpleColor] CGColor]]; [maskLayer setBorderWidth:5.0f]; [maskLayer setBounds:[containerLayer bounds]]; // When you create a path, remember that origin is in upper left hand // corner, so you have to treat it as if it has an anchor point of 0.0, // 0.0 UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake([translucentBlackLayer bounds].size.width/2.0f - 100.0f, [translucentBlackLayer bounds].size.height/2.0f - 100.0f, 200.0f, 200.0f)]; // Append a rectangular path around the mask layer so that // we can use the even/odd fill rule to invert the mask [path appendPath:[UIBezierPath bezierPathWithRect:[maskLayer bounds]]]; // Set the path's fill color since layer masks depend on alpha [maskLayer setFillColor:[[UIColor blackColor] CGColor]]; [maskLayer setPath:[path CGPath]]; // Center the mask layer in the translucent black layer [maskLayer setPosition: CGPointMake([translucentBlackLayer bounds].size.width/2.0f, [translucentBlackLayer bounds].size.height/2.0f)]; // Set the fill rule to even odd [maskLayer setFillRule:kCAFillRuleEvenOdd]; // Set the translucent black layer's mask property [translucentBlackLayer setMask:maskLayer]; // Add the container layer to the view so we can see it [[[self view] layer] addSublayer:containerLayer]; } </code></pre> <p>You would have to animate the mask layer which you could build up based on user input, but it will be a bit challenging. Notice the lines where I append a rectangular path to the circle path and then set the fill rule a few lines later on the shape layer. These are what make the inverted mask possible. If you leave those out you will instead show the translucent black in the center of the circle and then nothing on the outer part (if that makes sense).</p> <p>Maybe try to play with this code a bit and see if you can get it animating. I'll play with it some more as I have time, but this is a pretty interesting problem. Would love to see a complete solution.</p> <hr> <p><strong>UPDATE:</strong> So here's another stab at it. The trouble here is that this one makes the translucent mask look white instead of black, but the upside is that circle can be animated pretty easily.</p> <p>This one builds up a composite layer with the translucent layer and the circle layer being siblings inside of a parent layer that gets used as the mask.</p> <p><img src="https://i.stack.imgur.com/F8z4n.png" alt="Composite Mask"></p> <p>I added a basic animation to this one so we could see the circle layer animate.</p> <pre><code>- (void)viewDidLoad { [super viewDidLoad]; CGRect baseRect = CGRectMake(0.0f, 0.0f, 500.0f, 320.0f); CALayer *containerLayer = [CALayer layer]; [containerLayer setBounds:baseRect]; [containerLayer setPosition:[[self view] center]]; UIImage *image = [UIImage imageNamed:@"cool"]; [containerLayer setContents:(id)[image CGImage]]; CALayer *compositeMaskLayer = [CALayer layer]; [compositeMaskLayer setBounds:baseRect]; [compositeMaskLayer setPosition:CGPointMake([containerLayer bounds].size.width/2.0f, [containerLayer bounds].size.height/2.0f)]; CALayer *translucentLayer = [CALayer layer]; [translucentLayer setBounds:baseRect]; [translucentLayer setBackgroundColor:[[UIColor blackColor] CGColor]]; [translucentLayer setPosition:CGPointMake([containerLayer bounds].size.width/2.0f, [containerLayer bounds].size.height/2.0f)]; [translucentLayer setOpacity:0.35]; [compositeMaskLayer addSublayer:translucentLayer]; CAShapeLayer *circleLayer = [CAShapeLayer layer]; UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0.0f, 0.0f, 200.0f, 200.0f)]; [circleLayer setBounds:CGRectMake(0.0f, 0.0f, 200.0f, 200.0f)]; [circleLayer setPosition:CGPointMake([containerLayer bounds].size.width/2.0f, [containerLayer bounds].size.height/2.0f)]; [circleLayer setPath:[circlePath CGPath]]; [circleLayer setFillColor:[[UIColor blackColor] CGColor]]; [compositeMaskLayer addSublayer:circleLayer]; [containerLayer setMask:compositeMaskLayer]; [[[self view] layer] addSublayer:containerLayer]; CABasicAnimation *posAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; [posAnimation setFromValue:[NSValue valueWithCGPoint:[circleLayer position]]]; [posAnimation setToValue:[NSValue valueWithCGPoint:CGPointMake([circleLayer position].x + 100.0f, [circleLayer position].y + 100)]]; [posAnimation setDuration:1.0f]; [posAnimation setRepeatCount:INFINITY]; [posAnimation setAutoreverses:YES]; [circleLayer addAnimation:posAnimation forKey:@"position"]; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload