iOS 核心图形:仅绘制 CGPath 的阴影
我正在 iOS 5 中使用 Core Graphics 绘制一条简单的路径:
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint( path, NULL, center.x , topMargin );
CGPathAddLineToPoint(path, NULL, center.x+20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x , topMargin+40);
CGPathAddLineToPoint(path, NULL, center.x-20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x , topMargin );
现在我想以叠加模式填充它,如下所示:
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.4] setFill];
CGContextAddPath(context, path);
CGContextSetBlendMode (context, kCGBlendModeOverlay);
CGContextFillPath(context);
这给了我完全预期的结果。但接下来,我想创建浮雕效果。我想到使用白色和黑色阴影来实现这种效果,如下所示:
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(1, 1), 1.0, highlightColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 1.0, shadowColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);
问题是,当 alpha 设置为 0 时,不会绘制阴影。
现在的问题是:有没有一种方法可以仅绘制没有填充颜色但完整 Alpha 的阴影?我可以以某种方式阻止我的路径内部被绘制吗?或者是否有一种更简单的方法为一条路径绘制两个阴影?
I am drawing a simple path in iOS 5 with Core Graphics:
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint( path, NULL, center.x , topMargin );
CGPathAddLineToPoint(path, NULL, center.x+20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x , topMargin+40);
CGPathAddLineToPoint(path, NULL, center.x-20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x , topMargin );
Now i want to fill it in Overlay mode like so:
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.4] setFill];
CGContextAddPath(context, path);
CGContextSetBlendMode (context, kCGBlendModeOverlay);
CGContextFillPath(context);
Which gives me exactly the expected result. But next, i want to create an embossed effect. I thought of using a white and a black drop shadow in order to achieve this effect like so:
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(1, 1), 1.0, highlightColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);
[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 1.0, shadowColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);
The problem is, the shadows are not drawn when alpha is set to 0.
Now the question: Is there a way to draw only the shadows without the fill color but in full alpha? Can I somehow prevent the inside of my path from being drawn? Or is there perhaps a simpler way of drawing two shadows for one path?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议您将上下文的剪切路径设置为形状路径的逆向,配置阴影,并以完全不透明度正常填充形状。剪切路径将遮盖填充颜色,仅保留阴影。
诀窍是使用 CGContextEOClip 和一个附加的矩形子路径将剪切区域设置为原始路径未覆盖的区域。这适用于任何不自相交的路径。
I suggest you set the context's clipping path to the inverse of the shape's path, configure the shadow, and fill the shape normally, with full opacity. The clipping path will mask out the fill color, and only the shadow would remain.
The trick is using
CGContextEOClip
and an additional rectangle subpath to set the clipping area to whatever is not covered by the original path. This will work for any path that is not self-intersecting.是的,阴影依赖于形状的 alpha 值来渲染。
您可以仅绘制阴影而不渲染主要形状。想法是:
对于仅阴影图层,您可能需要使用
beginTransparencyLayer(auxiliaryInfo:)
和saveGState()
将绘图推送到单独的上下文中。这是一个比较:
对于代码片段,您可以在此处查看我对另一个问题的回答:https://stackoverflow.com/a/74844890/3164091
Yes, the shadow relies on the shape's alpha value to render.
You can draw the shadow only without rendering the main shape. The idea is:
For the shadow only layer, you probably want to use
beginTransparencyLayer(auxiliaryInfo:)
andsaveGState()
to push the drawing into a separated context.Here is a comparison:
For code snippet, you can check my answer for another question here: https://stackoverflow.com/a/74844890/3164091