diff options
Diffstat (limited to 'Map/Presentation/Base Components/MapRender/MapVertices.swift')
| -rw-r--r-- | Map/Presentation/Base Components/MapRender/MapVertices.swift | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/Map/Presentation/Base Components/MapRender/MapVertices.swift b/Map/Presentation/Base Components/MapRender/MapVertices.swift new file mode 100644 index 0000000..74cac6d --- /dev/null +++ b/Map/Presentation/Base Components/MapRender/MapVertices.swift @@ -0,0 +1,92 @@ +import SwiftUI + +struct MapVertices: View { + + let mapSize: CGSize + let vertexSize: CGSize + let vertices: [Vertex] + let padding = CGFloat(5.0) + + var body: some View { + ZStack(alignment: .topLeading) { + ForEach(vertices, id: \.id) { vertex in + getVertexShape(vertex).fill(Color.map.vertexColor) + Text(vertex.label.replacingOccurrences(of: "\\n", with: "\n")).font(.theme.vertexLabel) + .foregroundColor(.map.labelColor) + .shadow(color: .white, radius: 0, x: -0.5, y: -0.5) + .shadow(color: .white, radius: 0, x: 0.5, y: 0.5) + .offset( + CGSize( + width: w(vertex.position.x) + vertexSize.width + padding, + height: h(vertex.position.y) + 7.0)) + } + } + } + + func h(_ dimension: CGFloat) -> CGFloat { + max(0.0, min(mapSize.height, dimension * mapSize.height / 100.0)) + } + + func w(_ dimension: CGFloat) -> CGFloat { + max(0.0, min(mapSize.width, dimension * mapSize.width / 100.0)) + } + + func getVertexShape(_ vertex: Vertex) -> Path { + switch vertex.shape { + case .circle: + return Path { path in + path.addEllipse( + in: CGRect( + origin: CGPoint(x: w(vertex.position.x), y: h(vertex.position.y)), size: vertexSize + )) + } + case .square: + return Path { path in + path.addRect( + CGRect( + x: w(vertex.position.x), y: h(vertex.position.y), width: vertexSize.width, + height: vertexSize.height + )) + } + case .triangle: + return Path { path in + path.move(to: CGPoint(x: w(vertex.position.x), y: h(vertex.position.y) + vertexSize.height)) + path.addLine( + to: CGPoint( + x: w(vertex.position.x) + vertexSize.width, y: h(vertex.position.y) + vertexSize.height) + ) + path.addLine( + to: CGPoint(x: w(vertex.position.x) + vertexSize.width / 2.0, y: h(vertex.position.y))) + path.addLine( + to: CGPoint(x: w(vertex.position.x), y: h(vertex.position.y) + vertexSize.height)) + path.closeSubpath() + } + case .x: + return Path { path in + path.move(to: CGPoint(x: w(vertex.position.x), y: h(vertex.position.y))) + path.addLine( + to: CGPoint( + x: w(vertex.position.x) + vertexSize.width, y: h(vertex.position.y) + vertexSize.height) + ) + path.closeSubpath() + path.move(to: CGPoint(x: w(vertex.position.x) + vertexSize.width, y: h(vertex.position.y))) + path.addLine( + to: CGPoint(x: w(vertex.position.x), y: h(vertex.position.y) + vertexSize.height)) + path.closeSubpath() + }.strokedPath(StrokeStyle(lineWidth: 2.0, lineCap: .butt)) + } + } +} + +struct MapVertices_Previews: PreviewProvider { + static var previews: some View { + MapVertices( + mapSize: CGSize(width: 400.0, height: 400.0), vertexSize: CGSize(width: 25.0, height: 25.0), + vertices: [ + Vertex(id: 0, label: "A Circle", position: CGPoint(x: 50.0, y: 50.0)), + Vertex(id: 1, label: "A Square", position: CGPoint(x: 10.0, y: 20.0), shape: .square), + Vertex(id: 2, label: "A triangle", position: CGPoint(x: 25, y: 32.0), shape: .triangle), + Vertex(id: 3, label: "An X", position: CGPoint(x: 70.0, y: 70.0), shape: .x), + ]) + } +} |