在具有圆角边缘的弧形中绘制渐变颜色
Drawing a gradient color in an arc with a rounded edge
我想在 Swift 中复制这个。进一步阅读:How to draw a linear gradient arc with Qt QPainter?
我已经想出如何在矩形视图内绘制渐变:
override func drawRect(rect: CGRect) {
let currentContext = UIGraphicsGetCurrentContext()
CGContextSaveGState(currentContext)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let startColor = MyDisplay.displayColor(myMetric.currentValue)
let startColorComponents = CGColorGetComponents(startColor.CGColor)
let endColor = MyDisplay.gradientEndDisplayColor(myMetric.currentValue)
let endColorComponents = CGColorGetComponents(endColor.CGColor)
var colorComponents
= [startColorComponents[0], startColorComponents[1], startColorComponents[2], startColorComponents[3], endColorComponents[0], endColorComponents[1], endColorComponents[2], endColorComponents[3]]
var locations: [CGFloat] = [0.0, 1.0]
let gradient = CGGradientCreateWithColorComponents(colorSpace, &colorComponents, &locations, 2)
let startPoint = CGPointMake(0, 0)
let endPoint = CGPointMake(1, 8)
CGContextDrawLinearGradient(currentContext, gradient, startPoint, endPoint, CGGradientDrawingOptions.DrawsAfterEndLocation)
CGContextRestoreGState(currentContext)
}
以及如何画圆弧
func drawArc(color: UIColor, x: CGFloat, y: CGFloat, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, lineWidth: CGFloat, clockwise: Int32) {
let context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, lineWidth)
CGContextSetStrokeColorWithColor(context,
color.CGColor)
CGContextAddArc(context, x, y, radius, startAngle, endAngle, clockwise)
CGContextStrokePath(context)
}
随着渐变,它占据了整个视图。我不确定如何将渐变限制到特定区域,所以我制作了 UIView
的子类,修改了框架并使用了渐变代码(第一个片段)。
对于弧线,我使用了第二个片段。我在想我可以画一个圆弧,然后在圆弧的末端画一个圆来平滑圆弧。我该怎么做并在弧形上绘制渐变?
请忽略紫色标记。第一张图片是我指定的渐变弧的开始,第二张是渐变弧的结尾,在开始弧的下方和左侧。
如何使用 Core Graphics 在 Swift 中绘制它?
override func draw(_ rect: CGRect) {
//Add gradient layer
let gl = CAGradientLayer()
gl.frame = rect
gl.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
layer.addSublayer(gl)
//create mask in the shape of arc
let sl = CAShapeLayer()
sl.frame = rect
sl.lineWidth = 15.0
sl.strokeColor = UIColor.red.cgColor
let path = UIBezierPath()
path.addArc(withCenter: .zero, radius: 250.0, startAngle: 10.0.radians, endAngle: 60.0.radians, clockwise: true)
sl.fillColor = UIColor.clear.cgColor
sl.lineCap = kCALineCapRound
sl.path = path.cgPath
//Add mask to gradient layer
gl.mask = sl
}
希望对您有所帮助!!
2019 年的精确代码,具有真正的圆形渐变和完全灵活的结束位置:
这些天基本上你有一个渐变层和该层的蒙版。
所以第一步,你需要一个“面具”。
iOS 中的“面具”到底是什么?
在iOS中,你实际上使用了一个CAShapeLayer来制作遮罩。
这令人困惑。它应该被称为 'CAShapeToUseAsAMaskLayer'
但这就是你的做法,一个 CAShapeLayer。
第二步。在布局中,您必须调整形状层的大小。就是这样。
所以基本上就是这样:
class SweetArc: UIView {
open override func layoutSubviews() {
super.layoutSubviews()
arcLayer.frame = bounds
gradientLayer.frame = bounds
}
private lazy var gradientLayer: CAGradientLayer = {
let l = CAGradientLayer()
...
l.mask = arcLayer
layer.addSublayer(l)
return l
}()
private lazy var arcLayer: CAShapeLayer = {
let l = CAShapeLayer()
...
return l
}()
}
这就是全部。
请注意,渐变层的遮罩确实设置为形状层,我们将其命名为“arcLayer”。
形状图层用作遮罩。
这是两层的确切代码:
private lazy var gradientLayer: CAGradientLayer = {
// recall that .conic is finally available in 12 !
let l = CAGradientLayer()
l.type = .conic
l.colors = [
UIColor.yellow,
UIColor.red
].map{[=11=].cgColor}
l.locations = [0, 1]
l.startPoint = CGPoint(x: 0.5, y: 0.5)
l.endPoint = CGPoint(x: 0.5, y: 0)
l.mask = arcLayer
layer.addSublayer(l)
return l
}()
private lazy var arcLayer: CAShapeLayer = {
let l = CAShapeLayer()
l.path = arcPath
// to use a shape layer as a mask, you mask with white-on-clear:
l.fillColor = UIColor.clear.cgColor
l.strokeColor = UIColor.white.cgColor
l.lineWidth = lineThick
l.lineCap = CAShapeLayerLineCap.round
l.strokeStart = 0.4 // try values 0-1
l.strokeEnd = 0.5 // try values 0-1
return l
}()
同样,请注意 arcLayer 是一个形状层,您正在 用作遮罩 - 您实际上并未将其添加为子视图。
请记住,用作遮罩的形状层 不会! 被添加为子视图。
这可能会造成混淆。它根本不是一个“层”。
最后,注意 arcLayer 使用路径 arcPath
。
完美构建路径,使 strokeStart 和 strokeEnd 正常工作。
您想完美地构建路径。
因此非常容易设置笔划起始值和笔划终止值。
它们完全正确 运行 顺时针,从顶部,从 0 到 1。
这是具体的代码:
private let lineThick: CGFloat = 10.0
private let outerGap: CGFloat = 10.0
private let beginFraction: CGFloat = 0 // 0 means from top; runs clockwise
private lazy var arcPath: CGPath = {
let b = beginFraction * .pi * 2.0
return UIBezierPath(
arcCenter: bounds.centerOfCGRect(),
radius: bounds.width / 2.0 - lineThick / 2.0 - outerGap,
startAngle: .pi * -0.5 + b,
endAngle: .pi * 1.5 + b,
clockwise: true
).cgPath
}()
大功告成!
我想在 Swift 中复制这个。进一步阅读:How to draw a linear gradient arc with Qt QPainter?
我已经想出如何在矩形视图内绘制渐变:
override func drawRect(rect: CGRect) {
let currentContext = UIGraphicsGetCurrentContext()
CGContextSaveGState(currentContext)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let startColor = MyDisplay.displayColor(myMetric.currentValue)
let startColorComponents = CGColorGetComponents(startColor.CGColor)
let endColor = MyDisplay.gradientEndDisplayColor(myMetric.currentValue)
let endColorComponents = CGColorGetComponents(endColor.CGColor)
var colorComponents
= [startColorComponents[0], startColorComponents[1], startColorComponents[2], startColorComponents[3], endColorComponents[0], endColorComponents[1], endColorComponents[2], endColorComponents[3]]
var locations: [CGFloat] = [0.0, 1.0]
let gradient = CGGradientCreateWithColorComponents(colorSpace, &colorComponents, &locations, 2)
let startPoint = CGPointMake(0, 0)
let endPoint = CGPointMake(1, 8)
CGContextDrawLinearGradient(currentContext, gradient, startPoint, endPoint, CGGradientDrawingOptions.DrawsAfterEndLocation)
CGContextRestoreGState(currentContext)
}
以及如何画圆弧
func drawArc(color: UIColor, x: CGFloat, y: CGFloat, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, lineWidth: CGFloat, clockwise: Int32) {
let context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, lineWidth)
CGContextSetStrokeColorWithColor(context,
color.CGColor)
CGContextAddArc(context, x, y, radius, startAngle, endAngle, clockwise)
CGContextStrokePath(context)
}
随着渐变,它占据了整个视图。我不确定如何将渐变限制到特定区域,所以我制作了 UIView
的子类,修改了框架并使用了渐变代码(第一个片段)。
对于弧线,我使用了第二个片段。我在想我可以画一个圆弧,然后在圆弧的末端画一个圆来平滑圆弧。我该怎么做并在弧形上绘制渐变?
请忽略紫色标记。第一张图片是我指定的渐变弧的开始,第二张是渐变弧的结尾,在开始弧的下方和左侧。
如何使用 Core Graphics 在 Swift 中绘制它?
override func draw(_ rect: CGRect) {
//Add gradient layer
let gl = CAGradientLayer()
gl.frame = rect
gl.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
layer.addSublayer(gl)
//create mask in the shape of arc
let sl = CAShapeLayer()
sl.frame = rect
sl.lineWidth = 15.0
sl.strokeColor = UIColor.red.cgColor
let path = UIBezierPath()
path.addArc(withCenter: .zero, radius: 250.0, startAngle: 10.0.radians, endAngle: 60.0.radians, clockwise: true)
sl.fillColor = UIColor.clear.cgColor
sl.lineCap = kCALineCapRound
sl.path = path.cgPath
//Add mask to gradient layer
gl.mask = sl
}
希望对您有所帮助!!
2019 年的精确代码,具有真正的圆形渐变和完全灵活的结束位置:
这些天基本上你有一个渐变层和该层的蒙版。
所以第一步,你需要一个“面具”。
iOS 中的“面具”到底是什么?
在iOS中,你实际上使用了一个CAShapeLayer来制作遮罩。
这令人困惑。它应该被称为 'CAShapeToUseAsAMaskLayer'
但这就是你的做法,一个 CAShapeLayer。
第二步。在布局中,您必须调整形状层的大小。就是这样。
所以基本上就是这样:
class SweetArc: UIView {
open override func layoutSubviews() {
super.layoutSubviews()
arcLayer.frame = bounds
gradientLayer.frame = bounds
}
private lazy var gradientLayer: CAGradientLayer = {
let l = CAGradientLayer()
...
l.mask = arcLayer
layer.addSublayer(l)
return l
}()
private lazy var arcLayer: CAShapeLayer = {
let l = CAShapeLayer()
...
return l
}()
}
这就是全部。
请注意,渐变层的遮罩确实设置为形状层,我们将其命名为“arcLayer”。
形状图层用作遮罩。
这是两层的确切代码:
private lazy var gradientLayer: CAGradientLayer = {
// recall that .conic is finally available in 12 !
let l = CAGradientLayer()
l.type = .conic
l.colors = [
UIColor.yellow,
UIColor.red
].map{[=11=].cgColor}
l.locations = [0, 1]
l.startPoint = CGPoint(x: 0.5, y: 0.5)
l.endPoint = CGPoint(x: 0.5, y: 0)
l.mask = arcLayer
layer.addSublayer(l)
return l
}()
private lazy var arcLayer: CAShapeLayer = {
let l = CAShapeLayer()
l.path = arcPath
// to use a shape layer as a mask, you mask with white-on-clear:
l.fillColor = UIColor.clear.cgColor
l.strokeColor = UIColor.white.cgColor
l.lineWidth = lineThick
l.lineCap = CAShapeLayerLineCap.round
l.strokeStart = 0.4 // try values 0-1
l.strokeEnd = 0.5 // try values 0-1
return l
}()
同样,请注意 arcLayer 是一个形状层,您正在 用作遮罩 - 您实际上并未将其添加为子视图。
请记住,用作遮罩的形状层 不会! 被添加为子视图。
这可能会造成混淆。它根本不是一个“层”。
最后,注意 arcLayer 使用路径 arcPath
。
完美构建路径,使 strokeStart 和 strokeEnd 正常工作。
您想完美地构建路径。
因此非常容易设置笔划起始值和笔划终止值。
它们完全正确 运行 顺时针,从顶部,从 0 到 1。
这是具体的代码:
private let lineThick: CGFloat = 10.0
private let outerGap: CGFloat = 10.0
private let beginFraction: CGFloat = 0 // 0 means from top; runs clockwise
private lazy var arcPath: CGPath = {
let b = beginFraction * .pi * 2.0
return UIBezierPath(
arcCenter: bounds.centerOfCGRect(),
radius: bounds.width / 2.0 - lineThick / 2.0 - outerGap,
startAngle: .pi * -0.5 + b,
endAngle: .pi * 1.5 + b,
clockwise: true
).cgPath
}()
大功告成!