|
|
@@ -2,18 +2,48 @@ import SwiftUI
|
|
|
|
|
|
struct Triangle: Shape {
|
|
|
/// Flag to be able to adjust size based on Apple Watch size
|
|
|
- let isSmallDevice: Bool
|
|
|
+ let deviceType: WatchSize
|
|
|
+
|
|
|
+ private var triangleTipFactor: CGFloat {
|
|
|
+ switch deviceType {
|
|
|
+ case .watch40mm,
|
|
|
+ .watch41mm,
|
|
|
+ .watch42mm:
|
|
|
+ return 7.5
|
|
|
+ case .unknown,
|
|
|
+ .watch44mm,
|
|
|
+ .watch45mm:
|
|
|
+ return 9
|
|
|
+ case .watch49mm:
|
|
|
+ return 9
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private var triangleBezierFactor: CGFloat {
|
|
|
+ switch deviceType {
|
|
|
+ case .watch40mm,
|
|
|
+ .watch41mm,
|
|
|
+ .watch42mm:
|
|
|
+ return 5
|
|
|
+ case .unknown,
|
|
|
+ .watch44mm,
|
|
|
+ .watch45mm:
|
|
|
+ return 7
|
|
|
+ case .watch49mm:
|
|
|
+ return 7
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/// Creates a triangle shape pointing to the right
|
|
|
func path(in rect: CGRect) -> Path {
|
|
|
var path = Path()
|
|
|
|
|
|
// Draw the triangle pointing to the right
|
|
|
- path.move(to: CGPoint(x: rect.maxX - (isSmallDevice ? 7.5 : 9), y: rect.midY))
|
|
|
+ path.move(to: CGPoint(x: rect.maxX - triangleTipFactor, y: rect.midY))
|
|
|
path.addLine(to: CGPoint(x: rect.minX, y: rect.minY))
|
|
|
path.addQuadCurve(
|
|
|
to: CGPoint(x: rect.minX, y: rect.maxY),
|
|
|
- control: CGPoint(x: rect.midX - (isSmallDevice ? 5 : 7), y: rect.midY)
|
|
|
+ control: CGPoint(x: rect.midX - triangleBezierFactor, y: rect.midY)
|
|
|
)
|
|
|
path.closeSubpath()
|
|
|
|
|
|
@@ -26,7 +56,7 @@ struct TrendShape: View {
|
|
|
/// Rotation angle in degrees for the trend direction
|
|
|
let rotationDegrees: Double
|
|
|
/// Flag to be able to adjust size based on Apple Watch size
|
|
|
- let isSmallDevice: Bool
|
|
|
+ let deviceType: WatchSize
|
|
|
|
|
|
// Angular gradient for the outer circle, transitioning through various blues and purples
|
|
|
private let angularGradient = AngularGradient(
|
|
|
@@ -46,12 +76,68 @@ struct TrendShape: View {
|
|
|
// Color for the direction indicator triangle
|
|
|
private let triangleColor = Color(red: 0.262745098, green: 0.7333333333, blue: 0.9137254902) // #43BBE9
|
|
|
|
|
|
- var body: some View {
|
|
|
- let strokeWidth: CGFloat = isSmallDevice ? 4 : 5
|
|
|
- let circleSize: CGFloat = isSmallDevice ? 74 : 92
|
|
|
- let triangleSize: CGFloat = isSmallDevice ? 16 : 20
|
|
|
- let offset: CGFloat = isSmallDevice ? 47.5 : 59
|
|
|
+ private var strokeWidth: CGFloat {
|
|
|
+ switch deviceType {
|
|
|
+ case .watch40mm,
|
|
|
+ .watch41mm,
|
|
|
+ .watch42mm:
|
|
|
+ return 4
|
|
|
+
|
|
|
+ case .unknown,
|
|
|
+ .watch44mm,
|
|
|
+ .watch45mm:
|
|
|
+ return 5
|
|
|
+ case .watch49mm:
|
|
|
+ return 5
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private var circleSize: CGFloat {
|
|
|
+ switch deviceType {
|
|
|
+ case .watch40mm,
|
|
|
+ .watch41mm,
|
|
|
+ .watch42mm:
|
|
|
+ return 74
|
|
|
+ case .unknown,
|
|
|
+ .watch44mm,
|
|
|
+ .watch45mm:
|
|
|
+ return 92
|
|
|
+ case .watch49mm:
|
|
|
+ return 92
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private var triangleSize: CGFloat {
|
|
|
+ switch deviceType {
|
|
|
+ case .watch40mm,
|
|
|
+ .watch41mm,
|
|
|
+ .watch42mm:
|
|
|
+ return 16
|
|
|
+ case .unknown,
|
|
|
+ .watch44mm,
|
|
|
+ .watch45mm:
|
|
|
+ return 20
|
|
|
+ case .watch49mm:
|
|
|
+ return 20
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private var triangleOffset: CGFloat {
|
|
|
+ switch deviceType {
|
|
|
+ case .watch40mm,
|
|
|
+ .watch41mm,
|
|
|
+ .watch42mm:
|
|
|
+ return 47.5
|
|
|
+ case .unknown,
|
|
|
+ .watch44mm,
|
|
|
+ .watch45mm:
|
|
|
+ return 59
|
|
|
+ case .watch49mm:
|
|
|
+ return 59
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ var body: some View {
|
|
|
ZStack {
|
|
|
// Outer circle with gradient
|
|
|
Circle()
|
|
|
@@ -60,12 +146,79 @@ struct TrendShape: View {
|
|
|
.background(Circle().fill(Color.black))
|
|
|
|
|
|
// Triangle with the color of the last gradient color
|
|
|
- Triangle(isSmallDevice: isSmallDevice)
|
|
|
+ Triangle(deviceType: deviceType)
|
|
|
.fill(triangleColor)
|
|
|
.frame(width: triangleSize, height: triangleSize)
|
|
|
- .offset(x: offset)
|
|
|
+ .offset(x: triangleOffset)
|
|
|
}
|
|
|
.rotationEffect(.degrees(rotationDegrees))
|
|
|
.shadow(color: Color.black.opacity(0.33), radius: 3)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+// MARK: - TREND SHAPE PREVIEWS
|
|
|
+struct TrendShape_Previews: PreviewProvider {
|
|
|
+ static var previews: some View {
|
|
|
+ Group {
|
|
|
+ TrendShape(rotationDegrees: 0, deviceType: .watch40mm)
|
|
|
+ .previewDisplayName("TrendShape • 40mm")
|
|
|
+
|
|
|
+ TrendShape(rotationDegrees: 0, deviceType: .watch41mm)
|
|
|
+ .previewDisplayName("TrendShape • 41mm")
|
|
|
+
|
|
|
+ TrendShape(rotationDegrees: 0, deviceType: .watch42mm)
|
|
|
+ .previewDisplayName("TrendShape • 42mm")
|
|
|
+
|
|
|
+ TrendShape(rotationDegrees: 0, deviceType: .watch44mm)
|
|
|
+ .previewDisplayName("TrendShape • 44mm")
|
|
|
+
|
|
|
+ TrendShape(rotationDegrees: 0, deviceType: .watch45mm)
|
|
|
+ .previewDisplayName("TrendShape • 45mm")
|
|
|
+
|
|
|
+ TrendShape(rotationDegrees: 0, deviceType: .watch49mm)
|
|
|
+ .previewDisplayName("TrendShape • 49mm")
|
|
|
+ }
|
|
|
+ .padding()
|
|
|
+ // Optional: to let each preview "shrink to fit" rather than fill the entire simulator screen:
|
|
|
+ // .previewLayout(.sizeThatFits)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// MARK: - TRIANGLE PREVIEWS
|
|
|
+struct Triangle_Previews: PreviewProvider {
|
|
|
+ static var previews: some View {
|
|
|
+ Group {
|
|
|
+ Triangle(deviceType: .watch40mm)
|
|
|
+ .fill(Color.blue)
|
|
|
+ .frame(width: 50, height: 50)
|
|
|
+ .previewDisplayName("Triangle • 40mm")
|
|
|
+
|
|
|
+ Triangle(deviceType: .watch41mm)
|
|
|
+ .fill(Color.green)
|
|
|
+ .frame(width: 50, height: 50)
|
|
|
+ .previewDisplayName("Triangle • 41mm")
|
|
|
+
|
|
|
+ Triangle(deviceType: .watch42mm)
|
|
|
+ .fill(Color.purple)
|
|
|
+ .frame(width: 50, height: 50)
|
|
|
+ .previewDisplayName("Triangle • 42mm")
|
|
|
+
|
|
|
+ Triangle(deviceType: .watch44mm)
|
|
|
+ .fill(Color.red)
|
|
|
+ .frame(width: 50, height: 50)
|
|
|
+ .previewDisplayName("Triangle • 44mm")
|
|
|
+
|
|
|
+ Triangle(deviceType: .watch45mm)
|
|
|
+ .fill(Color.orange)
|
|
|
+ .frame(width: 50, height: 50)
|
|
|
+ .previewDisplayName("Triangle • 45mm")
|
|
|
+
|
|
|
+ Triangle(deviceType: .watch49mm)
|
|
|
+ .fill(Color.pink)
|
|
|
+ .frame(width: 50, height: 50)
|
|
|
+ .previewDisplayName("Triangle • 49mm")
|
|
|
+ }
|
|
|
+ .padding()
|
|
|
+ // .previewLayout(.sizeThatFits)
|
|
|
+ }
|
|
|
+}
|