-
Notifications
You must be signed in to change notification settings - Fork 462
Expand file tree
/
Copy pathGradientDrawingLayer.swift
More file actions
81 lines (61 loc) · 2.95 KB
/
GradientDrawingLayer.swift
File metadata and controls
81 lines (61 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import UIKit
internal class GradientDrawingLayer : ScrollableGraphViewDrawingLayer {
private var startColor: UIColor!
private var endColor: UIColor!
private var gradientType: ScrollableGraphViewGradientType!
// Gradient fills are only used with lineplots and we need
// to know what the line looks like.
private var lineDrawingLayer: LineDrawingLayer!
lazy private var gradientMask: CAShapeLayer = ({
let mask = CAShapeLayer()
mask.frame = CGRect(x: 0, y: 0, width: self.viewportWidth, height: self.viewportHeight)
mask.fillRule = CAShapeLayerFillRule.evenOdd
mask.lineJoin = self.lineJoin
return mask
})()
override init(layer: Any) {
super.init(layer: layer)
}
init(frame: CGRect, startColor: UIColor, endColor: UIColor, gradientType: ScrollableGraphViewGradientType, lineJoin: String = convertFromCAShapeLayerLineJoin(CAShapeLayerLineJoin.round), lineDrawingLayer: LineDrawingLayer) {
self.startColor = startColor
self.endColor = endColor
self.gradientType = gradientType
//self.lineJoin = lineJoin
self.lineDrawingLayer = lineDrawingLayer
super.init(viewportWidth: frame.size.width, viewportHeight: frame.size.height)
addMaskLayer()
self.setNeedsDisplay()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func addMaskLayer() {
self.mask = gradientMask
}
override func updatePath() {
gradientMask.path = lineDrawingLayer.createLinePath().cgPath
}
override func draw(in ctx: CGContext) {
let colors = [startColor.cgColor, endColor.cgColor]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let locations: [CGFloat] = [0.0, 1.0]
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: locations)
let displacement = ((viewportWidth / viewportHeight) / 2.5) * self.bounds.height
let topCentre = CGPoint(x: offset + self.bounds.width / 2, y: -displacement)
let bottomCentre = CGPoint(x: offset + self.bounds.width / 2, y: self.bounds.height)
let startRadius: CGFloat = 0
let endRadius: CGFloat = self.bounds.width
switch(gradientType) {
case .linear?:
ctx.drawLinearGradient(gradient!, start: topCentre, end: bottomCentre, options: .drawsAfterEndLocation)
case .radial?:
ctx.drawRadialGradient(gradient!, startCenter: topCentre, startRadius: startRadius, endCenter: topCentre, endRadius: endRadius, options: .drawsAfterEndLocation)
default:
fatalError("Unknown type of gradient.")
}
}
}
// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromCAShapeLayerLineJoin(_ input: CAShapeLayerLineJoin) -> String {
return input.rawValue
}