Skip to content

Commit f168144

Browse files
authored
Merge pull request #9 from SwiftUIExtensions/lines
Path quad curves
2 parents dcf4522 + 99875c9 commit f168144

File tree

5 files changed

+81
-57
lines changed

5 files changed

+81
-57
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import SwiftUI
2+
3+
public extension CGPoint {
4+
init(unitPoint: UnitPoint, in rect: CGRect) {
5+
self.init(
6+
x: rect.width * unitPoint.x,
7+
y: rect.height - (rect.height * unitPoint.y)
8+
)
9+
}
10+
}
11+
12+
public extension CGPoint {
13+
func halfway(to point: CGPoint) -> CGPoint {
14+
CGPoint(x: (self.x + point.x) * 0.5, y: (self.y + point.y) * 0.5)
15+
}
16+
17+
func quadCurveControlPoint(with point: CGPoint) -> CGPoint {
18+
let halfwayPoint = self.halfway(to: point)
19+
let absoluteDistance = abs(point.y - halfwayPoint.y)
20+
21+
if self.y < point.y {
22+
return CGPoint(x: halfwayPoint.x, y: halfwayPoint.y + absoluteDistance)
23+
} else if self.y > point.y {
24+
return CGPoint(x: halfwayPoint.x, y: halfwayPoint.y - absoluteDistance)
25+
} else {
26+
return halfwayPoint
27+
}
28+
}
29+
}
30+
31+
public extension Collection where Element == UnitPoint {
32+
func points(in rect: CGRect) -> [CGPoint] {
33+
self.map { CGPoint(unitPoint: $0, in: rect) }
34+
}
35+
}

Sources/Shapes/CGPoint+UnitPoint.swift

Lines changed: 0 additions & 29 deletions
This file was deleted.

Sources/Shapes/Lines/Line.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import SwiftUI
22

33
public struct Line: Shape {
4-
var unitPoints: [UnitPoint]
4+
private let unitPoints: [UnitPoint]
55

66
public func path(in rect: CGRect) -> Path {
77
Path { path in
8-
guard self.unitPoints.count > 0 else { return }
9-
path.move(to: .init(unitPoint: self.unitPoints[0], in: rect))
10-
11-
(1..<self.unitPoints.count).forEach { index in
12-
path.addLine(to: .init(unitPoint: self.unitPoints[index], in: rect))
13-
}
8+
path.addLines(self.unitPoints.points(in: rect))
149
}
1510
}
1611

Sources/Shapes/Lines/QuadCurve.swift

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,7 @@ public struct QuadCurve: Shape {
55

66
public func path(in rect: CGRect) -> Path {
77
Path { path in
8-
guard self.unitPoints.count > 0 else { return }
9-
var lastUnitPoint = self.unitPoints[0]
10-
path.move(to: CGPoint(unitPoint: lastUnitPoint, in: rect))
11-
12-
(1..<self.unitPoints.count).forEach { index in
13-
let nextUnitPoint = self.unitPoints[index]
14-
let nextPoint = CGPoint(unitPoint: nextUnitPoint, in: rect)
15-
16-
let halfwayUnitPoint = lastUnitPoint.halfway(to: nextUnitPoint)
17-
let halfwayPoint = CGPoint(unitPoint: halfwayUnitPoint, in: rect)
18-
19-
let firstControlUnitPoint = halfwayUnitPoint.quadCurveControlUnitPoint(with: lastUnitPoint)
20-
let firstControlPoint = CGPoint(unitPoint: firstControlUnitPoint, in: rect)
21-
path.addQuadCurve(to: halfwayPoint, control: firstControlPoint)
22-
23-
let secondControlUnitPoint = halfwayUnitPoint.quadCurveControlUnitPoint(with: nextUnitPoint)
24-
let secondControlPoint = CGPoint(unitPoint: secondControlUnitPoint, in: rect)
25-
path.addQuadCurve(to: nextPoint, control: secondControlPoint)
26-
27-
lastUnitPoint = nextUnitPoint
28-
}
8+
path.addQuadCurves(self.unitPoints.points(in: rect))
299
}
3010
}
3111

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import SwiftUI
2+
3+
4+
public extension Path {
5+
mutating func addQuadCurves(_ points: [CGPoint]) {
6+
guard points.count > 0 else { return }
7+
8+
if let currentPoint = self.currentPoint {
9+
var lastPoint = currentPoint
10+
11+
(0..<points.count).forEach { index in
12+
let nextPoint = points[index]
13+
14+
let halfwayPoint = lastPoint.halfway(to: nextPoint)
15+
16+
let firstControlPoint = halfwayPoint.quadCurveControlPoint(with: lastPoint)
17+
self.addQuadCurve(to: halfwayPoint, control: firstControlPoint)
18+
19+
let secondControlPoint = halfwayPoint.quadCurveControlPoint(with: nextPoint)
20+
self.addQuadCurve(to: nextPoint, control: secondControlPoint)
21+
22+
lastPoint = nextPoint
23+
}
24+
} else {
25+
var lastPoint = points[0]
26+
self.move(to: lastPoint)
27+
28+
(1..<points.count).forEach { index in
29+
let nextPoint = points[index]
30+
31+
let halfwayPoint = lastPoint.halfway(to: nextPoint)
32+
33+
let firstControlPoint = halfwayPoint.quadCurveControlPoint(with: lastPoint)
34+
self.addQuadCurve(to: halfwayPoint, control: firstControlPoint)
35+
36+
let secondControlPoint = halfwayPoint.quadCurveControlPoint(with: nextPoint)
37+
self.addQuadCurve(to: nextPoint, control: secondControlPoint)
38+
39+
lastPoint = nextPoint
40+
}
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)