mirror of
https://github.com/home-assistant/iOS.git
synced 2026-02-04 11:42:39 -06:00
87 lines
2.6 KiB
Swift
87 lines
2.6 KiB
Swift
import SwiftUI
|
|
|
|
final class HAProgressViewModel: ObservableObject {
|
|
@Published var isAnimating = false
|
|
@Published var trimEnd: CGFloat = 0.1
|
|
}
|
|
|
|
public struct HAProgressView: View {
|
|
public enum Style {
|
|
case small
|
|
case medium
|
|
case large
|
|
case extraLarge
|
|
|
|
var size: CGSize {
|
|
switch self {
|
|
case .small:
|
|
return CGSize(width: 24, height: 24)
|
|
case .medium:
|
|
return CGSize(width: 28, height: 28)
|
|
case .large:
|
|
return CGSize(width: 48, height: 48)
|
|
case .extraLarge:
|
|
return CGSize(width: 68, height: 68)
|
|
}
|
|
}
|
|
|
|
var lineWidth: CGFloat {
|
|
4
|
|
}
|
|
}
|
|
|
|
public enum ColorType {
|
|
/// When display in light background
|
|
case `default`
|
|
/// When displayed on accented background such as haPrimary
|
|
case light
|
|
}
|
|
|
|
@StateObject private var viewModel = HAProgressViewModel()
|
|
let style: Style
|
|
let colorType: ColorType
|
|
|
|
public init(style: Style = .medium, colorType: ColorType = .default) {
|
|
self.style = style
|
|
self.colorType = colorType
|
|
}
|
|
|
|
public var body: some View {
|
|
ZStack {
|
|
Circle()
|
|
.stroke(
|
|
colorType == .default ? Color.track : Color.white,
|
|
style: StrokeStyle(lineWidth: style.lineWidth)
|
|
)
|
|
.frame(width: style.size.width, height: style.size.height)
|
|
Circle()
|
|
.trim(from: 0, to: viewModel.trimEnd)
|
|
.stroke(
|
|
Color.haPrimary.opacity(colorType == .default ? 1 : 0.5),
|
|
style: StrokeStyle(lineWidth: style.lineWidth, lineCap: .round)
|
|
)
|
|
.frame(width: style.size.width, height: style.size.height)
|
|
.rotationEffect(Angle(degrees: viewModel.isAnimating ? 360 : 0))
|
|
.animation(
|
|
Animation.linear(duration: 1).repeatForever(autoreverses: false),
|
|
value: viewModel.isAnimating
|
|
)
|
|
.onAppear {
|
|
viewModel.isAnimating = true
|
|
withAnimation(.easeInOut(duration: 1.75).repeatForever(autoreverses: true)) {
|
|
viewModel.trimEnd = 0.7
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
HStack(spacing: DesignSystem.Spaces.two) {
|
|
HAProgressView(style: .small)
|
|
HAProgressView(style: .medium)
|
|
HAProgressView(style: .large)
|
|
HAProgressView(style: .extraLarge)
|
|
}
|
|
}
|