Last active
October 26, 2024 11:57
-
-
Save mattyoung/52947aff8524ed3c86d6ebd695dcfc86 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// !!! SwiftUI 3: use .foregroundStyle()! Much simplified | |
// | |
import SwiftUI | |
import os | |
let logger = Logger(subsystem: "net.hddigitalworks.TextColorAnimate", category: "color") | |
// all five (so far) ways to animate Text foreground color | |
struct TextColorAnimate: View { | |
@State private var flag = false | |
var body: some View { | |
VStack { | |
// 1) the best! Thanks @SwiftUILab !! | |
Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle) | |
.foregroundColor(.white) | |
.colorMultiply(flag ? .green : .red) | |
// 2) | |
if flag { | |
Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle) | |
.foregroundColor(.green) | |
} else { | |
Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle) | |
.foregroundColor(.red) | |
} | |
// 3) | |
ZStack { | |
Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle) | |
.foregroundColor(.green) | |
.opacity(flag ? 0 : 1) | |
Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle) | |
.foregroundColor(.red) | |
.opacity(flag ? 1 : 0) | |
} | |
// 4 | |
Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle) | |
.modifier(ColorAnimation(flag, from: .green, to: .red)) | |
// 5) | |
Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle) | |
.foregroundColor(.clear) | |
.overlay( | |
Rectangle() | |
.foregroundColor(flag ? .green : .red) | |
.mask(Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle)) | |
) | |
Text("So that redacted is animated!") | |
Text("Lorem Ipsum deldor \(Image(systemName: "externaldrive.fill.badge.plus"))").font(.largeTitle) | |
.foregroundColor(.white) | |
.colorMultiply(flag ? .green : .red) | |
.redacted(reason: .placeholder) | |
} | |
.onAppear { | |
withAnimation(Animation.linear(duration: 2).repeatForever()) { | |
flag.toggle() | |
} | |
} | |
} | |
} | |
// copied (mostly) from https://swiftui-lab.com/swiftui-animations-part3/ | |
struct ColorAnimation: AnimatableModifier { | |
var animatableData: Double | |
let rgbaPair: [(Double, Double)] | |
static private let garbage = [(0.0, 1.0), (0.0, 1.0), (0.0, 1.0), (0.0, 1.0)] | |
init(_ flag: Bool, from: Color, to: Color) { | |
animatableData = flag ? 0 : 1 | |
guard let cc1 = UIColor(from).cgColor.components else { | |
rgbaPair = Self.garbage | |
logger.error("ColorAnimation: UIColor(from).cgColor.components return nil!!") | |
return | |
} | |
guard let cc2 = UIColor(to).cgColor.components else { | |
rgbaPair = Self.garbage | |
logger.error("ColorAnimation: UIColor(to).cgColor.components return nil!!") | |
return | |
} | |
rgbaPair = Array(zip(cc1.map(Double.init), cc2.map(Double.init))) | |
} | |
func body(content: Content) -> some View { | |
content | |
.foregroundColor(mixedColor) | |
} | |
// This is a very basic implementation of a color interpolation | |
// between two values. | |
var mixedColor: Color { | |
let rgba = rgbaPair.map { $0.0 + ($0.1 - $0.0) * animatableData } | |
return Color(red: rgba[0], green: rgba[1], blue: rgba[2], opacity: rgba[3]) | |
} | |
} | |
struct TextColorAnimate_Previews: PreviewProvider { | |
static var previews: some View { | |
TextColorAnimate() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment