Skip to content

Instantly share code, notes, and snippets.

@Koshimizu-Takehito
Created August 4, 2024 01:20
Show Gist options
  • Save Koshimizu-Takehito/62f5f17614e5431e7cf8d8614109ef72 to your computer and use it in GitHub Desktop.
Save Koshimizu-Takehito/62f5f17614e5431e7cf8d8614109ef72 to your computer and use it in GitHub Desktop.
Color animation
import SwiftUI
extension Color {
static var random: Self {
Color(
hue: .random(in: 0..<1),
saturation: .random(in: (0.9)..<1),
brightness: .random(in: (0.9)..<1)
)
}
}
struct ContentView: View {
@State var color: Color = .random
@State var timer: Timer?
var body: some View {
FooView(color: color)
.ignoresSafeArea()
.onAppear {
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
withAnimation {
color = .random
}
}
}
.onDisappear {
timer?.invalidate()
}
}
}
struct FooView: View, Animatable {
@Environment(\.self) var environment
var color: Color
var animatableData: Color.Resolved.AnimatableData {
get {
color.resolve(in: environment).animatableData
}
set(value) {
var resolved = color.resolve(in: environment)
resolved.animatableData = value
color = Color(resolved)
}
}
var body: some View {
ZStack {
color
.clipShape(.circle)
.padding()
.padding()
Text(description)
.font(.largeTitle)
.bold()
.monospaced()
.contentTransition(.numericText(countsDown: true))
.animation(.default, value: color)
.foregroundStyle(textColor)
.foregroundStyle(.black)
}
}
var description: String {
func value(_ v: Color.Resolved, _ k: KeyPath<Color.Resolved, Float>) -> String {
let value = min(max(Int(v[keyPath: k] * Float(UInt8.max)), 0), 255)
return String(format: "%02x", value).uppercased()
}
let resolved = color.resolve(in: environment)
let red = value(resolved, \.red)
let green = value(resolved, \.green)
let blue = value(resolved, \.blue)
return "#\(red)\(green)\(blue)"
}
var textColor: some ShapeStyle {
let color = color.resolve(in: environment)
let luminance = 0.299 * color.red + 0.587 * color.green + 0.114 * color.blue
return luminance > 0.5 ? .black : .white
}
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment