使用 NSBezierPath、CAShapeLayer 和 CAGradientLayer 绘制渐变线
Draw a line with a gradient using NSBezierPath, CAShapeLayer, and CAGradientLayer
我有一个 macOS 应用程序,我可以在其中绘制线条和其他图形。
我使用 NSBezierPath 来形成线条或图形,然后将其添加到 CAShapeLayer 的路径中,最后,将 CAShapeLayer 添加到视图中。
这一切都很好,我有一个单一的笔触颜色。但是,我希望 lines/figures 而不是 是单一颜色,而是多种颜色(渐变)。我知道这可以通过 CAGradientLayer 完成,并尝试了其他 SO 问题中的一些示例,显示 iOS 变体,但它们对我不起作用。
下面是应用程序的代码片段:
startPoint = point
currentPath = NSBezierPath()
currentShape = CAShapeLayer()
currentShape?.lineWidth = lineWeight
currentShape?.strokeColor = strokeColor.cgColor
currentShape?.fillColor = fillColor.cgColor
currentShape?.lineJoin = CAShapeLayerLineJoin.round
currentShape?.lineCap = CAShapeLayerLineCap.round
currentPath?.move(to: point)
currentPath?.line(to: point)
currentShape?.path = currentPath?.cgPath
view.layer?.addSublayer(currentShape!)
currentGradient = CAGradientLayer()
currentGradient?.mask = currentShape
currentGradient?.frame = currentShape!.frame
currentGradient?.colors = [NSColor.red.cgColor, NSColor.black.cgColor]
view.layer?.addSublayer(currentGradient!)
// some more code here that I omitted (to draw shapes with NSBezierPath)
if let shape = currentShape {
shape.path = currentPath?.cgPath
currentGradient?.mask = shape
currentGradient?.frame = shape.frame
}
如果我删除涉及 currentGradient
的代码,那么我会看到 lines/figures(一种纯色),但是当我添加渐变部分时,我什么也看不到。我在上面的代码中做错了什么?
非常感谢任何帮助或提示。
搜索过,就知道答案了。您不能描边带有渐变的形状。相反,你 mask 渐变;形状层成为遮罩,从而显示渐变层。示例(v
是 window 中的视图):
let grad = CAGradientLayer()
grad.frame = v.bounds
v.layer?.addSublayer(grad)
grad.colors = [NSColor.red.cgColor, NSColor.blue.cgColor]
let shape = CAShapeLayer()
shape.frame = v.bounds
shape.lineWidth = 3
shape.fillColor = NSColor.clear.cgColor
shape.strokeColor = NSColor.black.cgColor
let path = CGPath(ellipseIn: v.bounds.insetBy(dx: 4, dy: 4), transform: nil)
shape.path = path
grad.mask = shape
我有一个 macOS 应用程序,我可以在其中绘制线条和其他图形。
我使用 NSBezierPath 来形成线条或图形,然后将其添加到 CAShapeLayer 的路径中,最后,将 CAShapeLayer 添加到视图中。
这一切都很好,我有一个单一的笔触颜色。但是,我希望 lines/figures 而不是 是单一颜色,而是多种颜色(渐变)。我知道这可以通过 CAGradientLayer 完成,并尝试了其他 SO 问题中的一些示例,显示 iOS 变体,但它们对我不起作用。
下面是应用程序的代码片段:
startPoint = point
currentPath = NSBezierPath()
currentShape = CAShapeLayer()
currentShape?.lineWidth = lineWeight
currentShape?.strokeColor = strokeColor.cgColor
currentShape?.fillColor = fillColor.cgColor
currentShape?.lineJoin = CAShapeLayerLineJoin.round
currentShape?.lineCap = CAShapeLayerLineCap.round
currentPath?.move(to: point)
currentPath?.line(to: point)
currentShape?.path = currentPath?.cgPath
view.layer?.addSublayer(currentShape!)
currentGradient = CAGradientLayer()
currentGradient?.mask = currentShape
currentGradient?.frame = currentShape!.frame
currentGradient?.colors = [NSColor.red.cgColor, NSColor.black.cgColor]
view.layer?.addSublayer(currentGradient!)
// some more code here that I omitted (to draw shapes with NSBezierPath)
if let shape = currentShape {
shape.path = currentPath?.cgPath
currentGradient?.mask = shape
currentGradient?.frame = shape.frame
}
如果我删除涉及 currentGradient
的代码,那么我会看到 lines/figures(一种纯色),但是当我添加渐变部分时,我什么也看不到。我在上面的代码中做错了什么?
非常感谢任何帮助或提示。
搜索过,就知道答案了。您不能描边带有渐变的形状。相反,你 mask 渐变;形状层成为遮罩,从而显示渐变层。示例(v
是 window 中的视图):
let grad = CAGradientLayer()
grad.frame = v.bounds
v.layer?.addSublayer(grad)
grad.colors = [NSColor.red.cgColor, NSColor.blue.cgColor]
let shape = CAShapeLayer()
shape.frame = v.bounds
shape.lineWidth = 3
shape.fillColor = NSColor.clear.cgColor
shape.strokeColor = NSColor.black.cgColor
let path = CGPath(ellipseIn: v.bounds.insetBy(dx: 4, dy: 4), transform: nil)
shape.path = path
grad.mask = shape