绘制内嵌的NSShadow和内嵌描边

13

我有一个NSBezierPath,我想在路径内部绘制插入阴影(类似于Photoshop)。

有没有办法实现这个效果?另外,我知道可以用-stroke对路径进行描边,但是能不能在路径内部绘制描边呢(类似于Photoshop中的Stroke Inside)?

更新3

static NSImage * graydient = nil;

if (!graydient) {
    graydient = [[NSImage alloc] initWithSize: NSMakeSize(22, 22)];
    [graydient lockFocus];

    NSGradient * gradient = [[NSGradient alloc] initWithColorsAndLocations: clr(@"#262729"), 0.0f, clr(@"#37383a"), 0.43f, clr(@"#37383a"), 1.0f, nil];
    [gradient drawInRect: NSMakeRect(0, 4.179, 22, 13.578) angle: 90.0f];
    [gradient release];

    [graydient unlockFocus];
}

NSColor * gcolor = [NSColor colorWithPatternImage: graydient];

[gcolor set];

NSShadow * shadow = [NSShadow new];
[shadow setShadowColor: [NSColor colorWithDeviceWhite: 1.0f alpha: 1.0f]];
[shadow setShadowBlurRadius: 0.0f];
[shadow setShadowOffset: NSMakeSize(0, 1)];
[shadow set];

[path fill];

[NSGraphicsContext saveGraphicsState];

[[path pathFromIntersectionWithPath: [NSBezierPath bezierPathWithRect: NSInsetRect([path bounds], 0.6, 0)]] setClip];

[gcolor set];

[shadow setShadowOffset: NSMakeSize(0, 1)];
[shadow setShadowColor: [NSColor blackColor]];
[shadow set];

[outer stroke];

[NSGraphicsContext restoreGraphicsState];

[NSGraphicsContext saveGraphicsState];

[[NSGraphicsContext currentContext] setCompositingOperation: NSCompositeSourceOut];

[shadow set];
[[NSColor whiteColor] set];
[inner fill];

[shadow set];
[inner fill];

[NSGraphicsContext restoreGraphicsState];

最终结果这是我的最终结果。看起来相当不错。我不得不将阴影更改为白色@ 1.0透明度才能使其起作用。即使菜单栏项目的阴影透明度规范为0.5,它看起来也不错。

非常感谢Joshua Nozzi


只是顺便提一下 - 这正是像PaintCode这样的工具可以节省您时间的地方。是的,如果你第一次看它的价格点有点高,但我想这是一个很好的例子,说明它如何可以节省您宝贵的时间 - 因此也节省了金钱..(而且,我没有任何关联。只是相信工具和自动化可以节省我们的时间) - Jay
1个回答

26

我认为你可以通过在Bezier路径上设置剪切来将其用作掩码,然后描出阴影并添加普通描边(如果需要)来实现此操作。

基于更新的代码进行更新:

这里是更新后的代码。今晚我感觉拖延了。:-)

// Describe an inset rect (adjust for pixel border)
NSRect whiteRect = NSInsetRect([self bounds], 20, 20);
whiteRect.origin.x += 0.5;
whiteRect.origin.y += 0.5;

// Create and fill the shown path
NSBezierPath * path = [NSBezierPath bezierPathWithRect:whiteRect];
[[NSColor whiteColor] set];
[path fill];

// Save the graphics state for shadow
[NSGraphicsContext saveGraphicsState];

// Set the shown path as the clip
[path setClip];

// Create and stroke the shadow
NSShadow * shadow = [[[NSShadow alloc] init] autorelease];
[shadow setShadowColor:[NSColor redColor]];
[shadow setShadowBlurRadius:10.0];
[shadow set];
[path stroke];

// Restore the graphics state
[NSGraphicsContext restoreGraphicsState];

// Add a nice stroke for a border
[path setLineWidth:1.0];
[[NSColor grayColor] set];
[path stroke];

你能更具体一些吗?可以提供方法建议吗?引用文档页面? - Alexsander Akers
请查看NSBezierPath API参考文档。快速搜索“clip”会显示-addClip和-setClip方法。一定要阅读这些方法的描述并理解它们所引用的内容(如路径规则等)。您需要保存图形状态(NSGraphicsState),进行剪切和阴影绘制,然后恢复先前的状态,然后继续正常绘制。我所说的“描边阴影”是指,在剪切后,设置阴影(在NSShadow API参考文档中描述),描绘路径,恢复图形状态,然后设置您的正常描边颜色并再次描绘路径。 - Joshua Nozzi
我该如何在中间绘制我的渐变并使用[NSColor clearColor],以便不会出现白色背景? - Alexsander Akers
我不确定你在这里问什么。你看到了什么,想要看到什么?你能提供一些插图吗? - Joshua Nozzi
我在加号下面得到了一个奇怪的“V”形状。有什么想法吗? - Alexsander Akers
我在你发布的图片中没有看到你所描述的内容。也许当它被放大到发布的图片大小时,不希望的视觉效果就消失了? - Joshua Nozzi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接