Skip to content

Instantly share code, notes, and snippets.

@pridees
Created December 19, 2020 10:13
Show Gist options
  • Save pridees/c7d4037a424e4acd9324d583fffe1b3b to your computer and use it in GitHub Desktop.
Save pridees/c7d4037a424e4acd9324d583fffe1b3b to your computer and use it in GitHub Desktop.
SwiftUI Color Extension
//
// Color+Extension.swift
// Helpers pack with:
//
// 1 - encode/decode RGBA
// 2 - accessibleFontColor depends on background color
// 3 - isLightColor - color lightness detection
//
// Created by Alexo on 19.12.2020.
//
import SwiftUI
extension Color: Codable {
private struct Components {
let red: Double
let green: Double
let blue: Double
let alpha: Double
}
private enum CodingKeys: String, CodingKey {
case red
case green
case blue
case alpha
}
/// A new random color.
static var random: Color {
let red = Double.random(in: 0...1)
let green = Double.random(in: 0...1)
let blue = Double.random(in: 0...1)
return Color(.sRGB, red: red, green: green, blue: blue, opacity: 1)
}
private var components: Components {
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
UIColor(self).getRed(&red, green: &green, blue: &blue, alpha: &alpha)
return Components(red: Double(red),
green: Double(green),
blue: Double(blue),
alpha: Double(alpha))
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let red = try container.decode(Double.self, forKey: .red)
let green = try container.decode(Double.self, forKey: .green)
let blue = try container.decode(Double.self, forKey: .blue)
let alpha = try container.decode(Double.self, forKey: .alpha)
self.init(Components(red: red, green: green, blue: blue, alpha: alpha))
}
private init(_ components: Components) {
self.init(.sRGB, red: components.red, green: components.green, blue: components.blue, opacity: components.alpha)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
let components = self.components
try container.encode(components.red, forKey: .red)
try container.encode(components.green, forKey: .green)
try container.encode(components.blue, forKey: .blue)
try container.encode(components.alpha, forKey: .alpha)
}
// MARK: - font colors
/// This color is either black or white, whichever is more accessible when viewed against the scrum color.
var accessibleFontColor: Color {
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
UIColor(self).getRed(&red, green: &green, blue: &blue, alpha: nil)
return isLightColor(red: red, green: green, blue: blue) ? .black : .white
}
private func isLightColor(red: CGFloat, green: CGFloat, blue: CGFloat) -> Bool {
let lightRed = red > 0.65
let lightGreen = green > 0.65
let lightBlue = blue > 0.65
let lightness = [lightRed, lightGreen, lightBlue].reduce(0) { $1 ? $0 + 1 : $0 }
return lightness >= 2
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment