Skip to content

Instantly share code, notes, and snippets.

@Koshimizu-Takehito
Last active July 19, 2023 23:03
Show Gist options
  • Save Koshimizu-Takehito/69ddb1690b2106fd4d9259cdf3d3ca11 to your computer and use it in GitHub Desktop.
Save Koshimizu-Takehito/69ddb1690b2106fd4d9259cdf3d3ca11 to your computer and use it in GitHub Desktop.
おしゃれなローディングアニメーション
// Thanks to @Ren_yello
// https://twitter.com/ren_yello/status/1681556136682741762?s=61&t=SNv1ZCU_S3Y8TobPv4MBww
import SwiftUI
struct ContentView: View {
var body: some View {
LoadingSquares()
}
}
struct LoadingSquares: View {
@State var point = CGPoint(x: 1, y: 1)
var p1: CGPoint { point }
var p2: CGPoint { p1.applying(.init(rotationAngle: .pi / 2)) }
var p3: CGPoint { p2.applying(.init(rotationAngle: .pi / 2)) }
var p4: CGPoint { p3.applying(.init(rotationAngle: .pi / 2)) }
var points: [CGPoint] { [p1, p2, p3, p4] }
var colors: [Color] { [.green, .blue, .yellow, .red] }
var items: [(CGPoint, Color)] { .init(zip(points, colors)) }
var body: some View {
GeometryReader { geometry in
let l = min(geometry.size.width, geometry.size.height) / 2
ForEach(items, id: \.1) { point, color in
let scale = (point.x * point.y).sign == .plus ? 0.8 : 1.2
Circle()
.frame(width: 50 , height: 50)
.scaleEffect(x: scale, y: scale)
.frame(width: l , height: l)
.offset(x: l / 2, y: l / 2)
.offset(x: l * point.x, y: l * point.y)
.foregroundStyle(color)
}
}
.frame(width: 120, height: 120)
.task {
await performAnimation()
}
}
func performAnimation() async {
withAnimation(Animation.easeInOut(duration: 1)) {
point = point.applying(.init(rotationAngle: .pi / 2))
}
try? await Task.sleep(nanoseconds: 1_000_000_000)
await performAnimation()
}
}
struct ContentView12_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment