如何在可可中繪製模糊的形狀?想象一下帶有填充路徑的blurRadius
的陰影,但沒有尖銳的前景路徑形狀。如何繪製模糊的形狀?
我試過的是使用帶陰影的填充路徑,並將填充顏色設置爲透明(alpha 0.0)。但是這也使得這個影子不可見,因爲它顯然會將影子「對象」的影子考慮在內。
如何在可可中繪製模糊的形狀?想象一下帶有填充路徑的blurRadius
的陰影,但沒有尖銳的前景路徑形狀。如何繪製模糊的形狀?
我試過的是使用帶陰影的填充路徑,並將填充顏色設置爲透明(alpha 0.0)。但是這也使得這個影子不可見,因爲它顯然會將影子「對象」的影子考慮在內。
這實際上是非常棘手的。我這個掙扎了一段時間,直到我用這一類的NSShadow
上來:
@implementation NSShadow (Extras)
//draw a shadow using a bezier path but do not draw the bezier path
- (void)drawUsingBezierPath:(NSBezierPath*) path alpha:(CGFloat) alpha
{
[NSGraphicsContext saveGraphicsState];
//get the bounds of the path
NSRect bounds = [path bounds];
//create a rectangle that outsets the size of the path bounds by the blur radius amount
CGFloat blurRadius = [self shadowBlurRadius];
NSRect shadowBounds = NSInsetRect(bounds, -blurRadius, -blurRadius);
//create an image to hold the shadow
NSImage* shadowImage = [[NSImage alloc] initWithSize:shadowBounds.size];
//make a copy of the shadow and set its offset so that when the path is drawn, the shadow is drawn in the middle of the image
NSShadow* aShadow = [self copy];
[aShadow setShadowOffset:NSMakeSize(0, -NSHeight(shadowBounds))];
//lock focus on the image
[shadowImage lockFocus];
//we want to draw the path directly above the shadow image and offset the shadow so it is drawn in the image rect
//to do this we must translate the drawing into the correct location
NSAffineTransform* transform=[NSAffineTransform transform];
//first get it to the zero point
[transform translateXBy:-shadowBounds.origin.x yBy:-shadowBounds.origin.y];
//now translate it by the height of the image so that it draws outside the image bounds
[transform translateXBy:0.0 yBy:NSHeight(shadowBounds)];
NSBezierPath* translatedPath = [transform transformBezierPath:path];
//apply the shadow
[aShadow set];
//fill the path with an arbitrary black color
[[NSColor blackColor] set];
[translatedPath fill];
[aShadow release];
[shadowImage unlockFocus];
//draw the image at the correct location relative to the original path
NSPoint imageOrigin = bounds.origin;
imageOrigin.x = (imageOrigin.x - blurRadius) + [self shadowOffset].width;
imageOrigin.y = (imageOrigin.y - blurRadius) - [self shadowOffset].height;
[shadowImage drawAtPoint:imageOrigin fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:alpha];
[shadowImage release];
[NSGraphicsContext restoreGraphicsState];
}
@end
我找到了一個實現這不正是我在網上的意思。作者:肖恩帕特里克奧布萊恩。這是NSBezierPath一類,像這樣:
@interface NSBezierPath (MCAdditions)
- (void)drawBlurWithColor:(NSColor *)color radius:(CGFloat)radius;
@end
@implementation NSBezierPath (MCAdditions)
- (void)drawBlurWithColor:(NSColor *)color radius:(CGFloat)radius
{
NSRect bounds = NSInsetRect(self.bounds, -radius, -radius);
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowOffset = NSMakeSize(0, bounds.size.height);
shadow.shadowBlurRadius = radius;
shadow.shadowColor = color;
NSBezierPath *path = [self copy];
NSAffineTransform *transform = [NSAffineTransform transform];
if ([[NSGraphicsContext currentContext] isFlipped])
[transform translateXBy:0 yBy:bounds.size.height];
else
[transform translateXBy:0 yBy:-bounds.size.height];
[path transformUsingAffineTransform:transform];
[NSGraphicsContext saveGraphicsState];
[shadow set];
[[NSColor blackColor] set];
NSRectClip(bounds);
[path fill];
[NSGraphicsContext restoreGraphicsState];
[path release];
[shadow release];
}
@end
這段代碼是從這個blog post下載。我沒有在網上任何地方單獨找到代碼。