catch mid colors outside of WCAG AA
This commit is contained in:
parent
f72c7a357b
commit
df33164b08
28 changed files with 135 additions and 96 deletions
|
@ -2,6 +2,7 @@ package utils
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
)
|
||||
|
||||
|
@ -11,11 +12,10 @@ const (
|
|||
Pblue float64 = 0.114
|
||||
)
|
||||
|
||||
func IsDarkColor(r, g, b uint8) bool {
|
||||
lum := Luminance(r, g, b)
|
||||
|
||||
return lum <= 130
|
||||
}
|
||||
var (
|
||||
DarkAltFallback = []uint8{0x1c, 0x10, 0x10}
|
||||
LightAltFallback = []uint8{0xf2, 0xef, 0xef}
|
||||
)
|
||||
|
||||
func IntToRgb(color uint32) (uint8, uint8, uint8) {
|
||||
b := color % 256
|
||||
|
@ -30,11 +30,30 @@ func RgbToString(r, g, b uint8) string {
|
|||
}
|
||||
|
||||
func AltColor(r, g, b uint8) (uint8, uint8, uint8) {
|
||||
l1 := Luminance(r, g, b)
|
||||
isDark := l1 <= 0.5098
|
||||
|
||||
brightnessAmount := -0.6
|
||||
if IsDarkColor(r, g, b) {
|
||||
if isDark { // color is dark
|
||||
brightnessAmount = 0.85
|
||||
}
|
||||
return Brighten(r, g, b, brightnessAmount)
|
||||
|
||||
r2, g2, b2 := Brighten(r, g, b, brightnessAmount)
|
||||
|
||||
l2 := Luminance(r2, g2, b2)
|
||||
ratio := WCAGRatio(l1, l2)
|
||||
|
||||
log.Printf("isDark=%v, ratio: %f, l1(%f)=%s, l2(%f)=%s", isDark, ratio, l1, RgbToString(r, g, b), l2, RgbToString(r2, g2, b2))
|
||||
|
||||
if ratio >= 3 {
|
||||
return r2, g2, b2
|
||||
}
|
||||
|
||||
if isDark {
|
||||
return LightAltFallback[0], LightAltFallback[1], LightAltFallback[2]
|
||||
} else {
|
||||
return DarkAltFallback[0], DarkAltFallback[1], DarkAltFallback[3]
|
||||
}
|
||||
}
|
||||
|
||||
func Brighten(r, g, b uint8, amount float64) (uint8, uint8, uint8) {
|
||||
|
@ -53,18 +72,23 @@ func multiply(i uint8, amount float64) uint8 {
|
|||
)
|
||||
}
|
||||
|
||||
func sRGB(c uint8) float64 {
|
||||
cf := float64(c) / 255
|
||||
if cf <= 0.03928 {
|
||||
return cf / 12.92
|
||||
} else {
|
||||
return math.Pow((cf+0.055)/1.055, 2.4)
|
||||
}
|
||||
}
|
||||
|
||||
func Luminance(r, g, b uint8) float64 {
|
||||
rC := Pred * math.Pow(float64(r), 2)
|
||||
gC := Pgreen * math.Pow(float64(g), 2)
|
||||
bC := Pblue * math.Pow(float64(b), 2)
|
||||
rC := Pred * math.Pow(sRGB(r), 2)
|
||||
gC := Pgreen * math.Pow(sRGB(g), 2)
|
||||
bC := Pblue * math.Pow(sRGB(b), 2)
|
||||
|
||||
return math.Sqrt(rC + gC + bC)
|
||||
}
|
||||
|
||||
func WCAGRatio(l1, l2 float64) float64 {
|
||||
if l1 < l2 {
|
||||
return (l1 + 0.05) / (l2 + 0.05)
|
||||
} else {
|
||||
return (l2 + 0.05) / (l1 + 0.05)
|
||||
}
|
||||
return (math.Max(l1, l2) + 0.05) / (math.Min(l1, l2) + 0.05)
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
WCAGAAA float64 = 0.14285714285714285
|
||||
WCAGAA float64 = 0.25
|
||||
WCAGAA float64 = 3
|
||||
)
|
||||
|
||||
func TestIntToRgb(t *testing.T) {
|
||||
|
@ -19,38 +18,20 @@ func TestIntToRgb(t *testing.T) {
|
|||
assert.Equal(t, uint8(0x56), b, "blue")
|
||||
}
|
||||
|
||||
func TestIsDarkColor(t *testing.T) {
|
||||
isDark := utils.IsDarkColor(0, 0, 0)
|
||||
assert.True(t, isDark)
|
||||
|
||||
isLight := utils.IsDarkColor(255, 255, 255)
|
||||
assert.False(t, isLight)
|
||||
|
||||
isQuestionable := utils.IsDarkColor(0x88, 0x88, 0x88)
|
||||
assert.False(t, isQuestionable)
|
||||
|
||||
isReallyQuestionable := utils.IsDarkColor(0x00, 0x88, 0x00)
|
||||
assert.True(t, isReallyQuestionable)
|
||||
}
|
||||
|
||||
func TestBrighten(t *testing.T) {
|
||||
r, g, b := utils.Brighten(0, 0, 0, 0.1)
|
||||
assert.Equal(t, uint8(0x19), r)
|
||||
assert.Equal(t, uint8(0x19), g)
|
||||
assert.Equal(t, uint8(0x19), b)
|
||||
// assert.LessOrEqual(t, WCAGAA, utils.WCAGRatio(
|
||||
// utils.Luminance(0, 0, 0),
|
||||
// utils.Luminance(r, g, b),
|
||||
// ))
|
||||
|
||||
r, g, b = utils.Brighten(0x88, 0x88, 0x88, -0.1)
|
||||
assert.Equal(t, uint8(0x88-0x19-1), r)
|
||||
assert.Equal(t, uint8(0x88-0x19-1), g)
|
||||
assert.Equal(t, uint8(0x88-0x19-1), b)
|
||||
// assert.LessOrEqual(t, WCAGAA, utils.WCAGRatio(
|
||||
// utils.Luminance(0x88, 0x88, 0x88),
|
||||
// utils.Luminance(r, g, b),
|
||||
// ))
|
||||
assert.GreaterOrEqual(t, utils.WCAGRatio(
|
||||
utils.Luminance(0x88, 0x88, 0x88),
|
||||
utils.Luminance(r, g, b),
|
||||
), WCAGAA)
|
||||
}
|
||||
|
||||
func TestRgbToString(t *testing.T) {
|
||||
|
@ -59,12 +40,21 @@ func TestRgbToString(t *testing.T) {
|
|||
|
||||
func TestAltColor(t *testing.T) {
|
||||
r, g, b := utils.AltColor(0xa2, 0xc2, 0x42)
|
||||
assert.Equal(t, uint8(0x09), r, "red")
|
||||
assert.Equal(t, uint8(0x29), g, "green")
|
||||
assert.Equal(t, uint8(0x00), b, "blue")
|
||||
assert.Equal(t, uint8(0xf2), r, "red")
|
||||
assert.Equal(t, uint8(0xef), g, "green")
|
||||
assert.Equal(t, uint8(0xef), b, "blue")
|
||||
assert.GreaterOrEqual(t, utils.WCAGRatio(
|
||||
utils.Luminance(0xa2, 0xc2, 0x42),
|
||||
utils.Luminance(r, g, b),
|
||||
), WCAGAA)
|
||||
|
||||
r, g, b = utils.AltColor(0xa2, 0x15, 0x18)
|
||||
assert.Equal(t, uint8(0xff), r, "red")
|
||||
assert.Equal(t, uint8(0xed), g, "green")
|
||||
assert.Equal(t, uint8(0xf0), b, "blue")
|
||||
assert.Equal(t, uint8(0xff), r, "red2")
|
||||
assert.Equal(t, uint8(0xed), g, "green2")
|
||||
assert.Equal(t, uint8(0xf0), b, "blue2")
|
||||
assert.GreaterOrEqual(t, utils.WCAGRatio(
|
||||
utils.Luminance(0xa2, 0x15, 0x18),
|
||||
utils.Luminance(r, g, b),
|
||||
), WCAGAA)
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue