macos 在 OSX 上,如何渐变填充路径笔划?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2737973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 06:55:17  来源:igfitidea点击:

On OSX, how do I gradient fill a path stroke?

macoscocoacore-graphics

提问by Emiel

Using the plethora of drawing functions in Cocoa or Quartz it's rather easy to draw paths, and fill them using a gradient. I can't seem to find an acceptable way however, to 'stroke'-draw a path with a line width of a few pixels and fill this stroke using a gradient. How is this done?

使用 Cocoa 或 Quartz 中的大量绘图函数可以很容易地绘制路径,并使用渐变填充它们。然而,我似乎无法找到一种可接受的方法来“描边”-绘制一条线宽为几个像素的路径并使用渐变填充此描边。这是怎么做的?

Edit: Apparently the question wasn't clear enough. Thanks for the responses so far, but I already figured that out. What I want to do is this:

编辑:显然这个问题还不够清楚。感谢您到目前为止的答复,但我已经想通了。我想做的是这样的:

squares
(source: emle.nl)

正方形
(来源:emle.nl

The left square is NSGradient drawn in a path followed by a path stroke message. The right is what I want to do; I want to fill the stroke using the gradient.

左边的方块是在路径中绘制的 NSGradient,后跟路径笔画消息。正确的是我想做的;我想使用渐变填充笔划。

回答by Rob Keniger

If you convert the NSBezierPathto a CGPath, you can use the CGContextReplacePathWithStrokedPath()method to retrieve a path that is the outline of the stroked path. Graham Cox's excellent GCDrawKithas a -strokedPathcategory method on NSBezierPaththat will do this for you without needing to drop down to Core Graphics.

如果将 转换NSBezierPathCGPath,则可以使用该CGContextReplacePathWithStrokedPath()方法检索作为描边路径轮廓的路径。Graham Cox 出色的GCDrawKit有一个-strokedPath类别方法NSBezierPath,可以为您完成此操作,而无需下拉到 Core Graphics。

Once you have the outlined path, you can fill that path with an NSGradient.

获得轮廓路径后,您可以使用NSGradient.

回答by Peter Hosey

I can't seem to find an acceptable way however, to 'stroke'-draw a path with a line width of a few pixels and fill this stroke using a gradient. How is this done?

然而,我似乎无法找到一种可接受的方法来“描边”-绘制一条线宽为几个像素的路径并使用渐变填充此描边。这是怎么做的?

[Original answer replaced with the following]

[原答案替换为以下内容]

Ah, I see. You want to apply the gradient to the stroke.

啊,我明白了。您想将渐变应用于笔划。

To do that, you use a blend mode. I explained how to do this in an answer on another question.Here's the list of steps, adapted to your goal:

为此,您可以使用混合模式。我在另一个问题的回答中解释了如何做到这一点以下是适合您的目标的步骤列表:

  1. Begin a transparency layer.
  2. Stroke the path with any non-transparent color.
  3. Set the blend modeto source in.
  4. Draw the gradient.
  5. End the transparency layer.
  1. 开始一个透明层
  2. 用任何不透明的颜色描边路径。
  3. 将混合模式设置source in
  4. 绘制渐变。
  5. 结束透明层。

回答by Bartosz Olszanowski

According to Peter Hosey's answer I've managed to do a simple gradient curve, which looks like this:

根据 Peter Hosey 的回答,我设法制作了一个简单的渐变曲线,如下所示:

Gradient Curve Image

渐变曲线图像

I've done this in drawRect(_:) method of UIView class by writing the code below:

我通过编写以下代码在 UIView 类的 drawRect(_:) 方法中完成了此操作:

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()

    CGContextBeginTransparencyLayer (context, nil)
    let path = createCurvePath()
    UIColor.blueColor().setStroke()
    path.stroke()
    CGContextSetBlendMode(context, .SourceIn)

    let colors          = [UIColor.blueColor().CGColor, UIColor.redColor().CGColor]
    let colorSpace      = CGColorSpaceCreateDeviceRGB()
    let colorLocations  :[CGFloat] = [0.0, 1.0]
    let gradient        = CGGradientCreateWithColors(colorSpace, colors, colorLocations)
    let startPoint      = CGPoint(x: 0.0, y: rect.size.height / 2)
    let endPoint        = CGPoint(x: rect.size.width, y: rect.size.height / 2)

    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, CGGradientDrawingOptions.DrawsBeforeStartLocation)
    CGContextEndTransparencyLayer(context)
}

Function createCurvePath() returns an UIBezierPath object. I've also set path.lineWidth to 5 points.

函数 createCurvePath() 返回一个 UIBezierPath 对象。我还将 path.lineWidth 设置为 5 点。