如何使用Quartz来做聚光效果?

时间:2013-07-17 12:14:26

标签: objective-c animation quartz-graphics

我想使用Quartz做这样的效果:

enter image description here

我想在imageView上面有一个图层,但是有些区域没有被覆盖,我该如何实现呢?有任何想法吗?谢谢。

1 个答案:

答案 0 :(得分:1)

目前尚不清楚您是在谈论iOS还是MacOS,但主要内容是相同的。我能想到的最简单的方法是用半透明的灰色填充叠加视图,然后用偏移阴影打出......这是一个简单的例子:

- (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);
}

如果你想要硬边缘,甚至不需要考虑偏移和阴影,只需在将混合模式设置为CGContextFillEllipseInRect后使用带有不透明填充的kCGBlendModeDestinationOut

编辑:我发现你也可以用径向渐变效果做类似的事情,但是看看你给出的效果作为一个例子,我猜测边缘更模糊,而不是一个统一的渐变,但它是很难说。无论如何,Quartz通过其阴影机制为您提供免费模糊,所以为什么不使用它,对吧?