Skip to content

Instantly share code, notes, and snippets.

@schwa
Created March 20, 2024 19:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schwa/2aa154b7607f2f11b0d558a31ae08494 to your computer and use it in GitHub Desktop.
Save schwa/2aa154b7607f2f11b0d558a31ae08494 to your computer and use it in GitHub Desktop.
Silly Swift Screen Saver Sample Source
import SwiftUI
struct Point {
var position: CGPoint
var velocity: CGPoint
}
struct ContentView: View {
@State
var lines: [[Point]] = []
var body: some View {
GeometryReader { geometry in
TimelineView(.animation(paused: false)) { timeline in
Canvas(rendersAsynchronously: true) { context, size in
for (index, line) in lines.enumerated() {
let path = Path { path in
path.move(to: line.first!.position)
for i in 1..<line.count {
let cp2 = line[i].position
let cp1 = line[(i + 1) % line.count].position
let end = line[(i + 2) % line.count].position
path.addCurve(to: end, control1: cp1, control2: cp2)
}
}
let color = Color(hue: 1 - Double(index) / Double(lines.count), saturation: 0.8, brightness: 0.8, opacity: 1 - Double(index) / Double(lines.count))
context.stroke(path, with: .color(color))
}
}
.onAppear {
let lineVelocity = CGPoint(x: .random(in: -1 ... 1), y: .random(in: -1 ... 1))
return lines = [
(0...10).map { _ in
let position = CGPoint(x: .random(in: 0..<geometry.size.width), y: .random(in: 0..<geometry.size.height))
let velocity = CGPoint(x: lineVelocity.x + .random(in: -0.5 ... 0.5), y: lineVelocity.y + .random(in: -0.5 ... 0.5))
return .init(position: position, velocity: velocity)
}
]
}
.onChange(of: timeline.date) {
let old = lines
lines = lines.map { line in
line.map { point in
var point = point
point.position.x += point.velocity.x
point.position.y += point.velocity.y
if point.position.x < 0 {
point.position.x = 0 - point.position.x
point.velocity.x *= -1
}
else if point.position.x > geometry.size.width {
point.position.x = geometry.size.width - (geometry.size.width - geometry.size.width)
point.velocity.x *= -1
}
if point.position.y < 0 {
point.position.y = 0 - point.position.y
point.velocity.y *= -1
}
else if point.position.y > geometry.size.height {
point.position.y = geometry.size.height - (geometry.size.height - geometry.size.height)
point.velocity.y *= -1
}
return point
}
}
if lines.count < 50, let last = old.last {
lines.append(last)
}
}
}
}
.background(.black)
}
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment