diff --git a/Sources/GaugeKit/GaugeBackView.swift b/Sources/GaugeKit/GaugeBackView.swift index c3334c2..d67366d 100644 --- a/Sources/GaugeKit/GaugeBackView.swift +++ b/Sources/GaugeKit/GaugeBackView.swift @@ -39,13 +39,16 @@ struct GaugeBackView: View { @Binding var flipped: Bool let additionalInfo: GaugeAdditionalInfo + private var flipAngle: Angle { + Angle(degrees: flipped ? -180 : 0) + } + var body: some View { - let flipAngle = Angle(degrees: flipped ? -180 : 0) - GeometryReader { geometry in VStack { if let preTitle = additionalInfo.strap { Text(preTitle) + .font(.system(size: geometry.size.width / 20, weight: .regular)) } if let title = additionalInfo.title { Text(title) @@ -54,6 +57,7 @@ struct GaugeBackView: View { } if let body = additionalInfo.body { Text(body) + .font(.system(size: geometry.size.width / 20, weight: .regular)) } } .foregroundColor(color) diff --git a/Sources/GaugeKit/GaugeLabelStack.swift b/Sources/GaugeKit/GaugeLabelStack.swift index 500e500..8144508 100644 --- a/Sources/GaugeKit/GaugeLabelStack.swift +++ b/Sources/GaugeKit/GaugeLabelStack.swift @@ -22,23 +22,30 @@ struct GaugeLabelStack: View { var value: Int? var title: String? + private func smallestDimension(for geometry: GeometryProxy) -> Double { + let isTaller = geometry.size.width < geometry.size.height + let smallestDimension = isTaller ? geometry.size.width : geometry.size.height + return smallestDimension + } + var body: some View { GeometryReader { geometry in - let isTaller = geometry.size.width < geometry.size.height - let smallestDimension = isTaller ? geometry.size.width : geometry.size.height - VStack { if let unwrappedValue = value { Text("\(unwrappedValue)") .fontWeight(.bold) - .font(.system(size: smallestDimension / 4)) + .font(.system(size: smallestDimension(for: geometry) / 4)) .foregroundColor(valueColor) + .lineLimit(1) + .frame(maxWidth: geometry.size.width * 0.8) } if let unwrappedTitle = title { Text(unwrappedTitle) .fontWeight(.light) - .font(.system(size: smallestDimension / 20)) + .font(.system(size: smallestDimension(for: geometry) / 12)) .foregroundColor(titleColor) + .multilineTextAlignment(.center) + .frame(maxWidth: geometry.size.width / 2) } } .position(x: geometry.size.width / 2, y: geometry.size.height / 2) @@ -46,3 +53,8 @@ struct GaugeLabelStack: View { .aspectRatio(1, contentMode: .fit) } } + +#Preview { + let colors: [Color] = [.red, .orange, .yellow, .green] + return GaugeView(title: "Speed", value: 88, maxValue: 100, colors: colors) +} diff --git a/Sources/GaugeKit/GaugeMeter.swift b/Sources/GaugeKit/GaugeMeter.swift index 6a9e3be..a692c87 100644 --- a/Sources/GaugeKit/GaugeMeter.swift +++ b/Sources/GaugeKit/GaugeMeter.swift @@ -21,8 +21,8 @@ struct GaugeMeter : View { let colors: [Color] let maxValue: Int? - let trimStart = 0.1 - let trimEnd = 0.9 + private let trimStart = 0.1 + private let trimEnd = 0.9 init(value: Int? = nil, maxValue: Int? = nil, colors: [Color]) { self.colors = colors @@ -31,15 +31,39 @@ struct GaugeMeter : View { self.maxValue = defaultMaxValue ? 100 : maxValue } + private var startAngle: Double { + 360 * trimStart + } + + private var endAngle: Double { + 360 * trimEnd + } + + private var gradient: Gradient { + Gradient(colors: colors) + } + + private var indicatorAngle: Angle? { + if let value, let maxValue { + let oneUnit = (Double(360) * 0.8) / Double(maxValue) + let degrees = (Double(value) * oneUnit) + return Angle(degrees: degrees > (360 * 0.8) ? 360 * 0.8 : degrees) + } else if let value { + let oneUnit = (Double(360) * 0.8) / Double(100) + let degrees = (Double(value) * oneUnit) + return Angle(degrees: degrees > (360 * 0.8) ? 360 * 0.8 : degrees) + } else { + return nil + } + } + + private func meterThickness(for geometry: GeometryProxy) -> Double { + (geometry.size.width / 10) + } + var body: some View { - let startAngle = 360 * trimStart - let endAngle = 360 * trimEnd - ZStack { GeometryReader { geometry in - let gradient = Gradient(colors: colors) - let meterThickness = geometry.size.width / 10 - AngularGradient( gradient: gradient, center: .center, @@ -50,20 +74,14 @@ struct GaugeMeter : View { GaugeMask( trimStart: trimStart, trimEnd: trimEnd, - meterThickness: meterThickness + meterThickness: meterThickness(for: geometry) ) ) .rotationEffect(Angle(degrees: 90)) .shadow(color: .black.opacity(0.2), radius: 10, x: 0, y: 0) - if let unwrappedValue = value, let unwrappedMax = maxValue { - let oneUnit = (Double(360) * 0.8) / Double(unwrappedMax) - let degrees = (Double(unwrappedValue) * oneUnit) - GaugeIndicator(angle: Angle(degrees: degrees), size: geometry.size) - } else if let unwrappedValue = value { - let oneUnit = (Double(360) * 0.8) / Double(100) - let degrees = (Double(unwrappedValue) * oneUnit) - GaugeIndicator(angle: Angle(degrees: degrees), size: geometry.size) + if let indicatorAngle { + GaugeIndicator(angle: indicatorAngle, size: geometry.size) } } } @@ -94,9 +112,7 @@ private struct GaugeMask: View { } } -struct GaugeComponents_Previews: PreviewProvider { - static var previews: some View { - let colors: [Color] = [.red, .orange, .yellow, .green] - GaugeView(title: "Speed", value: 88, colors: colors) - } +#Preview { + let colors: [Color] = [.red, .orange, .yellow, .green] + return GaugeView(title: "Speed", value: 88, maxValue: 100, colors: colors) } diff --git a/Sources/GaugeKit/GaugeView.swift b/Sources/GaugeKit/GaugeView.swift index 65ae62f..0840847 100644 --- a/Sources/GaugeKit/GaugeView.swift +++ b/Sources/GaugeKit/GaugeView.swift @@ -42,9 +42,11 @@ public struct GaugeView : View { self.additionalInfo = additionalInfo } + private var flipAngle: Angle { + Angle(degrees: flipped ? 180 : 0) + } + public var body: some View { - let flipAngle = Angle(degrees: flipped ? 180 : 0) - GeometryReader { geometry in ZStack { ZStack { @@ -52,7 +54,7 @@ public struct GaugeView : View { GaugeLabelStack(value: value, title: title) } .rotation3DEffect(flipAngle, axis: (x: 0, y: 1, z: 0)) - .opacity(flipped ? 0.1 : 1) + .opacity(flipped ? 0.05 : 1) if let info = additionalInfo { GaugeBackView(flipped: $flipped, additionalInfo: info) @@ -71,9 +73,15 @@ public struct GaugeView : View { } } -struct Gauge_Previews: PreviewProvider { - static var previews: some View { - GaugeView(title: "Hej", value: 50, colors: [.red, .orange, .yellow, .green], additionalInfo: .init(strap: "This is the top title", title: "Title", body: "Hejsan svejsan")) - .padding() - } +#Preview { + GaugeView( + title: "Speed", + value: 100, + colors: [.red, .orange, .yellow, .green], + additionalInfo: .init( + strap: "This is the top title", + title: "Title", + body: "Hejsan svejsan") + ) + .padding() }