97 lines
2.8 KiB
Swift
97 lines
2.8 KiB
Swift
import SwiftUI
|
|
|
|
struct MacroRing: View {
|
|
let current: Double
|
|
let goal: Double
|
|
let color: Color
|
|
let label: String
|
|
let unit: String
|
|
var size: CGFloat = 72
|
|
var lineWidth: CGFloat = 7
|
|
|
|
private var progress: Double {
|
|
guard goal > 0 else { return 0 }
|
|
return min(current / goal, 1.0)
|
|
}
|
|
|
|
private var remaining: Double {
|
|
max(goal - current, 0)
|
|
}
|
|
|
|
var body: some View {
|
|
VStack(spacing: 4) {
|
|
ZStack {
|
|
Circle()
|
|
.stroke(color.opacity(0.12), lineWidth: lineWidth)
|
|
|
|
Circle()
|
|
.trim(from: 0, to: progress)
|
|
.stroke(
|
|
color,
|
|
style: StrokeStyle(lineWidth: lineWidth, lineCap: .round)
|
|
)
|
|
.rotationEffect(.degrees(-90))
|
|
.animation(.easeOut(duration: 0.5), value: progress)
|
|
|
|
VStack(spacing: 0) {
|
|
Text("\(Int(remaining))")
|
|
.font(.system(size: size * 0.22, weight: .bold, design: .rounded))
|
|
.foregroundStyle(Color.text1)
|
|
Text("left")
|
|
.font(.system(size: size * 0.13, weight: .medium))
|
|
.foregroundStyle(Color.text4)
|
|
}
|
|
}
|
|
.frame(width: size, height: size)
|
|
|
|
Text(label)
|
|
.font(.caption2)
|
|
.fontWeight(.medium)
|
|
.foregroundStyle(Color.text3)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct MacroRingLarge: View {
|
|
let current: Double
|
|
let goal: Double
|
|
let color: Color
|
|
var size: CGFloat = 120
|
|
var lineWidth: CGFloat = 10
|
|
|
|
private var progress: Double {
|
|
guard goal > 0 else { return 0 }
|
|
return min(current / goal, 1.0)
|
|
}
|
|
|
|
private var remaining: Double {
|
|
max(goal - current, 0)
|
|
}
|
|
|
|
var body: some View {
|
|
ZStack {
|
|
Circle()
|
|
.stroke(color.opacity(0.12), lineWidth: lineWidth)
|
|
|
|
Circle()
|
|
.trim(from: 0, to: progress)
|
|
.stroke(
|
|
color,
|
|
style: StrokeStyle(lineWidth: lineWidth, lineCap: .round)
|
|
)
|
|
.rotationEffect(.degrees(-90))
|
|
.animation(.easeOut(duration: 0.5), value: progress)
|
|
|
|
VStack(spacing: 2) {
|
|
Text("\(Int(remaining))")
|
|
.font(.system(size: size * 0.26, weight: .bold, design: .rounded))
|
|
.foregroundStyle(Color.text1)
|
|
Text("remaining")
|
|
.font(.system(size: size * 0.11, weight: .medium))
|
|
.foregroundStyle(Color.text4)
|
|
}
|
|
}
|
|
.frame(width: size, height: size)
|
|
}
|
|
}
|