Skip to content

Instantly share code, notes, and snippets.

@durul
Created January 1, 2025 16:49
Show Gist options
  • Save durul/3e9034f5a75c4209b19e9b5554fdeedd to your computer and use it in GitHub Desktop.
Save durul/3e9034f5a75c4209b19e9b5554fdeedd to your computer and use it in GitHub Desktop.
Dynamic Sphere Animation in SwiftUI with TimelineView and Canvas
import SwiftUI
struct SphereView: View {
@State var start = Date()
func createPoint(at angle: Double, radius: Double, time: Double, center: CGPoint, pointSize: Double) -> (path: Path, color: Color) {
let wobble = sin(time * 2 + radius / 10) * 10
let distanceModifier = 1 + sin(angle * 3 + time) * 0.1
let adjustedRadius = (radius + wobble) * distanceModifier
let x = cos(angle) * adjustedRadius
let y = sin(angle) * adjustedRadius
let point = CGPoint(x: center.x + x, y: center.y + y)
let path = Circle().path(in: CGRect(origin: point, size: CGSize(width: pointSize * 2, height: pointSize * 2)))
// Increase color diversity and vibrancy
let hue = ((radius / 360 + time / 5).truncatingRemainder(dividingBy: 1.0)) * 1.5 // Faster hue cycling
let saturation = 1.0 // Max saturation for vibrant colors
let brightness = 0.7 + sin(time * 3 + angle) * 0.3 // Increase brightness range
let color = Color(hue: hue.truncatingRemainder(dividingBy: 1.0), saturation: saturation, brightness: brightness)
return (path, color)
}
var body: some View {
TimelineView(.animation) { context in
let time = context.date.timeIntervalSince(start)
let rotation = sin(time) * 2
Canvas { context, size in
let pointSize = min(size.width, size.height) * 0.001
let center = CGPoint(x: size.width / 2, y: size.height / 2)
for ring in 0..<40 {
let ringRadius = Double(ring) * 12
let points = min(Int(ringRadius * 1.5), 100)
for point in 0..<points {
let angle = (Double(point) / Double(points)) * 2 * .pi + rotation
let (path, color) = createPoint(at: angle, radius: ringRadius, time: time, center: center, pointSize: pointSize)
context.fill(path, with: .color(color.opacity(1.5)))
}
}
}
}
.background(.black)
.onTapGesture { start = .now }
.ignoresSafeArea()
}
}
#Preview {
SphereView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment