Skip to content

Instantly share code, notes, and snippets.

@Koshimizu-Takehito
Created July 29, 2024 09:35
Show Gist options
  • Save Koshimizu-Takehito/0dcd2c79248673b84ad6b56c7fc1460d to your computer and use it in GitHub Desktop.
Save Koshimizu-Takehito/0dcd2c79248673b84ad6b56c7fc1460d to your computer and use it in GitHub Desktop.
RingAnimation
import SwiftUI
struct ContentView: View {
@State var progress = 0.0
var body: some View {
ZStack {
Ring(value: progress, speed: 4)
.foregroundStyle(gradation(.yellow, .orange))
.frame(width: 120)
Ring(value: progress, speed: 3)
.foregroundStyle(gradation(.mint, .green))
.frame(width: 150)
Ring(value: progress, speed: 2)
.foregroundStyle(gradation(.cyan, .blue))
.frame(width: 180)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(Rectangle())
.ignoresSafeArea()
.onTapGesture(perform: start)
}
func gradation(_ colors: Color...) -> LinearGradient {
LinearGradient(colors: colors, startPoint: .top, endPoint: .bottom)
}
func start() {
progress = 0
withAnimation(.linear(duration: 4).repeatForever(autoreverses: false)) {
progress = 1
}
}
}
struct Ring: View, Animatable {
var value = 0.0
var speed = 1.0
var animatableData: Double {
get { max(min(value, 1), 0) }
set { value = max(min(newValue, 1), 0) }
}
var body: some View {
let fraction = fraction
ZStack {
Circle()
.stroke(lineWidth: 8)
.foregroundStyle(.gray.opacity(0.3))
Circle()
.trim(from: fraction.from, to: fraction.to)
.stroke(style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))
.rotationEffect(.degrees(-90.0 + (360.0 * speed * value)))
}
}
var fraction: (from: Double, to: Double) {
if value <= 0.5 {
return (0, value * 2)
} else {
return (((value - 0.5) * 2), 1)
}
}
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment