はじめに
背景がどんな色でも常に文字を見やすくする方法を紹介します。
こちらの記事の続きです。
作るもの
色のついた背景とその色のカラーコードを表示するアプリを作ります。
タップすると、ランダムに背景色が変わります。
背景色を変更すると背景色に応じて文字色も見やすい色に変更されます。
デモ
やり方
背景色に応じて文字色を変更するには、背景色の相対輝度を求め、その値に応じて文字色を変更します。
相対輝度が0.5未満の場合は白、0.5以上の場合は黒にします。
// 前の記事で紹介した相対輝度です
extension Color {
var relativeLuminance: CGFloat {
// 色の相対輝度を計算する
return 0.2126 * components.red + 0.7152 * components.green + 0.0722 * components.blue
}
private var components: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
// 色の成分を取得する
var redComponent: CGFloat = 0
var greenComponent: CGFloat = 0
var blueComponent: CGFloat = 0
var alphaComponent: CGFloat = 0
UIColor(self).getRed(&redComponent, green: &greenComponent, blue: &blueComponent, alpha: &alphaComponent)
return (redComponent, greenComponent, blueComponent, alphaComponent)
}
}
extension Color {
// isLight
var isLight: Bool {
// 色の相対輝度が0.5以上の場合は明るい色と判定する
return relativeLuminance >= 0.5
}
// random
static var random: Color {
// ランダムな色を生成する
return Color(red: .random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1))
}
// toHex
func toHex() -> String {
// 色を16進数に変換する
let components = self.components
let red = Int(components.red * 255)
let green = Int(components.green * 255)
let blue = Int(components.blue * 255)
return String(format: "#%02X%02X%02X", red, green, blue)
}
}
struct ContentView: View {
@State private var backgroundColor = Color.white
var body: some View {
ZStack {
Rectangle()
.fill(backgroundColor)
.ignoresSafeArea()
Text(backgroundColor.toHex())
.font(.system(size: 56).bold())
.foregroundColor(backgroundColor.isLight ? .black : .white)
}
.onTapGesture {
// 背景色をランダムに変更する
backgroundColor = Color.random
}
.animation(.easeInOut(duration: 0.3), value: backgroundColor)
}
}
ポイント
- 背景色の相対輝度を求める
- 相対輝度が0.5以上の場合は明るい色と判定する
- 背景色が明るい場合は文字色を黒に、暗い場合は白にする
おわりに
背景色に応じて文字色を変更する方法を紹介しました。
色って面白い😆