0

I would like to do some effect like this using Quartz:

enter image description here

I would like to have a layer on top of the imageView, but some of the area is no covered, how can I implement it? Any ideas? Thanks.

Community
  • 1
  • 1
DNB5brims
  • 29,344
  • 50
  • 131
  • 195

1 Answers1

1

It's not clear whether you're talking about iOS or MacOS, but the principal is the same. The easiest way I can think of is to fill the overlay view with the semi-transparent gray color and then punch out with an offset shadow... Here's a trivial example:

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSaveGState(ctx);

    // Replace with your location, spot radius, and blur radius
    CGPoint spotLoc = CGPointMake(200,200);
    CGFloat spotRadius = 100;
    CGFloat blurRadius = 5;

    // Draw 50% black overlay over the entire view
    CGContextSetFillColorWithColor(ctx, [[UIColor colorWithRed: 0 green:0 blue:0 alpha:0.5] CGColor]);
    CGContextFillRect(ctx, CGContextGetClipBoundingBox(ctx));

    // Then punch out spot using an offset shadow
    CGRect spotRect = CGRectMake(spotLoc.x - spotRadius, spotLoc.y - spotRadius, 2 * spotRadius, 2 * spotRadius);
    CGFloat xOffset = CGRectGetMaxX(spotRect) - CGRectGetMinX(self.bounds);
    CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut);
    CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] CGColor]);
    CGContextSetShadowWithColor(ctx, CGSizeMake(xOffset, 0), blurRadius, [[UIColor blackColor] CGColor]);
    CGContextTranslateCTM(ctx, -xOffset, 0);
    CGContextFillEllipseInRect(ctx, spotRect);

    CGContextRestoreGState(ctx);
}

If you want hard edges, don't even bother with the offset and the shadow, just use CGContextFillEllipseInRect with an opaque fill after setting the blend mode to kCGBlendModeDestinationOut.

EDIT: It occurs to me that you could also do something similar with a radial gradient effect, but looking at the effect you gave as an example, I'm guessing the edges are more blurred and not a uniform gradient, but it's hard to say. Anyway Quartz gives you the blur for free with its shadowing mechanism, so why not use it, right?

ipmcc
  • 29,581
  • 5
  • 84
  • 147