Skip to content

Instantly share code, notes, and snippets.

@Koshimizu-Takehito
Created November 29, 2024 07:43
Show Gist options
  • Save Koshimizu-Takehito/42d0450cec7ec5995fa3d61d9a81cd9e to your computer and use it in GitHub Desktop.
Save Koshimizu-Takehito/42d0450cec7ec5995fa3d61d9a81cd9e to your computer and use it in GitHub Desktop.
アニメーション素振り
import SwiftUI
// MARK: - Model
@MainActor
@Observable
final class Model {
var rotations: [[Int]]
init(row: Int, column: Int) {
rotations = (0..<row).map { _ in
(0..<column).map { _ in
Int.random(in: 0..<4)
}
}
}
func rotate() async {
rotations.lazy
.enumerated()
.flatMap { xx in
xx.element.lazy.enumerated().map { x in
(i: xx.offset, j: x.offset)
}
}
.shuffled()
.prefix(2 * rotations.count)
.forEach { i, j in
rotations[i][j] += i.isMultiple(of: 2) ? 1 : -1
}
try? await Task.sleep(nanoseconds: 1_000_000_000)
await rotate()
}
}
// MARK: - View
struct ContentView: View {
@State private var model = Model(row: 12, column: 8)
var body: some View {
Grid(horizontalSpacing: .zero, verticalSpacing: .zero) {
let rotations = model.rotations
ForEach(0..<rotations.count, id: \.self) { i in
GridRow {
ForEach(0..<rotations[i].count, id: \.self) { j in
Tile(radians: Double(rotations[i][j]) * .pi/2)
}
}
}
}
.scaledToFit()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.foregroundStyle(.white)
.background(.black, in: .rect)
.ignoresSafeArea()
.animation(.spring(duration: 0.8), value: model.rotations)
.task {
await model.rotate()
}
}
}
private struct Tile: View {
let radians: Double
var body: some View {
ZStack {
QuarterArc()
.stroke(lineWidth: 16)
.rotationEffect(.radians(radians))
QuarterArc()
.stroke(lineWidth: 16)
.rotationEffect(.radians(.pi + radians))
}
}
}
private struct QuarterArc: Shape {
func path(in rect: CGRect) -> Path {
Path { path in
path.addArc(
center: CGPoint(x: rect.maxX, y: rect.minY),
radius: min(rect.midX, rect.midY),
startAngle: .degrees(180),
endAngle: .degrees(90),
clockwise: true
)
}
}
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment