-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathGear.swift
54 lines (42 loc) · 1.59 KB
/
Gear.swift
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
//
// Gear.swift
// Morphi
//
// Created by phimage on 18/07/2019.
// Copyright © 2019 phimage. All rights reserved.
//
import SwiftUI
/// An ring centered on the frame of the view containing it.
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public struct Gear: Shape {
/// The radius of the gear ring.
public var radius: CGFloat
/// Number of cogs. Must be more than 2.
public var cogs: Int
public init(radius: CGFloat, cogs: Int) {
self.radius = radius
self.cogs = cogs
}
/// Describes this shape as a path within a rectangular frame of reference.
///
/// - Parameter rect: The frame of reference for describing this shape.
/// - Returns: A path that describes this shape.
public func path(in rect: CGRect) -> Path {
var path = Path()
let center = rect.center
let (innerRadius, outerRadius) = rect.radii(for: radius)
guard cogs > 2 else {
return path
}
let angle: Angle = .pi / Double(cogs)
var radius = (outerRadius, innerRadius)
path.addArc(center: .zero, radius: innerRadius / 2, startAngle: .zero, endAngle: .pi * 2, clockwise: true)
path.move(to: CGPoint(x: radius.0, y: 0))
for _ in 0..<cogs * 2 {
path.addArc(center: .zero, radius: radius.0, startAngle: .zero, endAngle: -angle, clockwise: true)
path = path.applying(CGAffineTransform(rotationAngle: CGFloat(angle.radians)))
swap(&radius.0, &radius.1)
}
return path.applying(CGAffineTransform(translationX: center.x, y: center.y))
}
}