Skip to content

Instantly share code, notes, and snippets.

@renyello
Last active July 19, 2023 13:37
Show Gist options
  • Save renyello/8107478347a6f7b77455d453e41b770b to your computer and use it in GitHub Desktop.
Save renyello/8107478347a6f7b77455d453e41b770b to your computer and use it in GitHub Desktop.
HuggingFaceのLoading画面に表示されるアニメーションを再現しました。カラーは青:#3498DB 黄色:#F1C40F 赤:#E74C3C を使用してます。
import SwiftUI
struct HugginFaceProgressCircle: View {
@State private var rotationDegrees: [Double] = [0, 0, 0]
@State private var startTrim: [CGFloat] = [0, 0, 0]
@State private var trimTo: CGFloat = 120.0 / 360.0
@State private var shouldRotate = true
@State private var opacity = 1.0
let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
@State private var percentage: Int = 0
let timer2 = Timer.publish(every: 0.3, on: .main, in: .common).autoconnect()
@State private var expandGreenCircle = false
var body: some View {
ZStack {
Text("\(percentage)%")
.font(.system(size: 30)) // smaller font size
.opacity(opacity)
.onReceive(timer2) { _ in
if percentage < 100 {
percentage += Int.random(in: 1...5)
if percentage >= 100 {
percentage = 100
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
withAnimation(.linear(duration: 1.0)) {
trimTo = 1.0 // Trim all the way when it reaches 100%
shouldRotate = false // Stop rotation when it reaches 100%
expandGreenCircle = true
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
withAnimation(.linear(duration: 0.4)) {
self.opacity = 0
}
}
}
}
}
}
ForEach(0..<3) { index in
Circle()
.trim(from: 0, to: trimTo)
.stroke(lineWidth: 3)
.frame(width: CGFloat(100 + 30 * index), height: CGFloat(100 + 30 * index))
.foregroundColor(Color(["Blue","Yellow", "Red"][index]))
.rotationEffect(Angle.degrees(CGFloat(index*50)+rotationDegrees[index]))
.animation(shouldRotate ? Animation.linear(duration: 1).repeatForever(autoreverses: false) : .default)
.opacity(opacity)
}
}
.onAppear() {
startTrim = startTrim.map { _ in CGFloat.random(in: 0...1) }
}
.onReceive(timer) { _ in
if shouldRotate {
withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
rotationDegrees = rotationDegrees.enumerated().map { index, degree in
degree + (50.0 * Double(1 - Double(index) * 0.2))
}
}
}
}
}
}
struct HugginFaceProgressCircle_Previews: PreviewProvider {
static var previews: some View {
HugginFaceProgressCircle()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment