美文网首页
iOS - Color Picker

iOS - Color Picker

作者: ienos | 来源:发表于2022-07-24 14:31 被阅读0次

绘制色盘


效果图.png

通过一个一个扇形叠加而成


扇形.png
func draw(context: CGContext, size: CGSize) {
    let center = CGPoint.init(x: size.width * 0.5, y: size.height * 0.5)
    let radius = size.width * 0.5
    context.saveGState()
    context.addEllipse(in: CGRect.init(origin: .zero, size: size))
    context.clip()
    let count = 3600
    let _ = Array(0..<count).map({ self.drawSector(context, index: $0, radius: radius, count: count, center: center) })
    context.restoreGState()
}

func drawSector(_ context: CGContext, index: Int, radius: CGFloat, count: Int, center: CGPoint) {
    let color = UIColor.init(hue: 1-CGFloat(index)/CGFloat(count), saturation: 1, brightness: 1, alpha: 1)
    context.setStrokeColor(color.cgColor)
    context.saveGState()
    context.addPath(sectorPath(center: center,
                                   radius: radius,
                                   angle: CGFloat(index) * self.partAngle(count),
                                   sectorAngle: self.partAngle(count)))
    context.clip()
    
    guard let gradient = CGGradient.init(colorsSpace: CGColorSpaceCreateDeviceRGB(),
                                         colors: [UIColor.init(white: 1, alpha: 1).cgColor, color.cgColor] as CFArray,
                                         locations: nil) else { context.restoreGState() ; return }
    context.drawLinearGradient(gradient,
                               start: center,
                               end: radiusEdge(center: center,
                                               radius: radius,
                                               angle: CGFloat(index) * self.partAngle(count)),
                               options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
    context.restoreGState()
}

func partAngle(_ number: Int) -> Double {
    return 2 * Double.pi / CGFloat(number)
}

func radiusEdge(center: CGPoint, radius: CGFloat, angle: CGFloat) -> CGPoint {
    return CGPoint.init(x: center.x + radius * cos(angle),
                        y: center.y + radius * sin(angle))
}

func sectorPath(center: CGPoint, radius: CGFloat, angle: CGFloat, sectorAngle: CGFloat) -> CGPath {
    let path = CGMutablePath.init()
    path.move(to: center)
    let end1 = CGPoint.init(x: center.x + radius * cos(angle - sectorAngle * 0.5),
                            y: center.y + radius * sin(angle - sectorAngle * 0.5))
    let end2 = CGPoint.init(x: center.x + radius * cos(angle + sectorAngle * 0.5),
                            y: center.y + radius * sin(angle + sectorAngle * 0.5))
    path.addLine(to: end1)
    path.addLine(to: end2)
    return path
}

相关文章