diff options
author | silverwind <me@silverwind.io> | 2024-04-07 18:19:25 +0200 |
---|---|---|
committer | Gusted <postmaster@gusted.xyz> | 2024-04-15 16:11:34 +0200 |
commit | f6c0c39f1aef167bb14375a009cf463c6bf031fb (patch) | |
tree | 6785b479f0f47fbe360311391af0e8ab53dc8bc5 /modules/util | |
parent | Merge pull request '[CHORE] Exclude git repository testdate from watching' (#... (diff) | |
download | forgejo-f6c0c39f1aef167bb14375a009cf463c6bf031fb.tar.xz forgejo-f6c0c39f1aef167bb14375a009cf463c6bf031fb.zip |
[PORT] gitea##30237: Fix and rewrite contrast color calculation, fix project-related bugs
1. The previous color contrast calculation function was incorrect at
least for the `#84b6eb` where it output low-contrast white instead of
black. I've rewritten these functions now to accept hex colors and to
match GitHub's calculation and to output pure white/black for maximum
contrast. Before and after:
<img width="94" alt="Screenshot 2024-04-02 at 01 53 46"
src="https://github.com/go-gitea/gitea/assets/115237/00b39e15-a377-4458-95cf-ceec74b78228"><img
width="90" alt="Screenshot 2024-04-02 at 01 51 30"
src="https://github.com/go-gitea/gitea/assets/115237/1677067a-8d8f-47eb-82c0-76330deeb775">
2. Fix project-related issues:
- Expose the new `ContrastColor` function as template helper and use it
for project cards, replacing the previous JS solution which eliminates a
flash of wrong color on page load.
- Fix a bug where if editing a project title, the counter would get
lost.
- Move `rgbToHex` function to color utils.
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: Giteabot <teabot@gitea.io>
---
Conflict resolution: Trivial.
(cherry picked from commit 36887ed3921d03f1864360c95bd2ecf853bfbe72)
Diffstat (limited to 'modules/util')
-rw-r--r-- | modules/util/color.go | 42 | ||||
-rw-r--r-- | modules/util/color_test.go | 46 |
2 files changed, 39 insertions, 49 deletions
diff --git a/modules/util/color.go b/modules/util/color.go index 240b045c28..9c520dce78 100644 --- a/modules/util/color.go +++ b/modules/util/color.go @@ -4,22 +4,10 @@ package util import ( "fmt" - "math" "strconv" "strings" ) -// Check similar implementation in web_src/js/utils/color.js and keep synchronization - -// Return R, G, B values defined in reletive luminance -func getLuminanceRGB(channel float64) float64 { - sRGB := channel / 255 - if sRGB <= 0.03928 { - return sRGB / 12.92 - } - return math.Pow((sRGB+0.055)/1.055, 2.4) -} - // Get color as RGB values in 0..255 range from the hex color string (with or without #) func HexToRBGColor(colorString string) (float64, float64, float64) { hexString := colorString @@ -47,19 +35,23 @@ func HexToRBGColor(colorString string) (float64, float64, float64) { return r, g, b } -// return luminance given RGB channels -// Reference from: https://www.w3.org/WAI/GL/wiki/Relative_luminance -func GetLuminance(r, g, b float64) float64 { - R := getLuminanceRGB(r) - G := getLuminanceRGB(g) - B := getLuminanceRGB(b) - luminance := 0.2126*R + 0.7152*G + 0.0722*B - return luminance +// Returns relative luminance for a SRGB color - https://en.wikipedia.org/wiki/Relative_luminance +// Keep this in sync with web_src/js/utils/color.js +func GetRelativeLuminance(color string) float64 { + r, g, b := HexToRBGColor(color) + return (0.2126729*r + 0.7151522*g + 0.0721750*b) / 255 } -// Reference from: https://firsching.ch/github_labels.html -// In the future WCAG 3 APCA may be a better solution. -// Check if text should use light color based on RGB of background -func UseLightTextOnBackground(r, g, b float64) bool { - return GetLuminance(r, g, b) < 0.453 +func UseLightText(backgroundColor string) bool { + return GetRelativeLuminance(backgroundColor) < 0.453 +} + +// Given a background color, returns a black or white foreground color that the highest +// contrast ratio. In the future, the APCA contrast function, or CSS `contrast-color` will be better. +// https://github.com/color-js/color.js/blob/eb7b53f7a13bb716ec8b28c7a56f052cd599acd9/src/contrast/APCA.js#L42 +func ContrastColor(backgroundColor string) string { + if UseLightText(backgroundColor) { + return "#fff" + } + return "#000" } diff --git a/modules/util/color_test.go b/modules/util/color_test.go index d96ac36730..be6e6b122a 100644 --- a/modules/util/color_test.go +++ b/modules/util/color_test.go @@ -33,33 +33,31 @@ func Test_HexToRBGColor(t *testing.T) { } } -func Test_UseLightTextOnBackground(t *testing.T) { +func Test_UseLightText(t *testing.T) { cases := []struct { - r float64 - g float64 - b float64 - expected bool + color string + expected string }{ - {215, 58, 74, true}, - {0, 117, 202, true}, - {207, 211, 215, false}, - {162, 238, 239, false}, - {112, 87, 255, true}, - {0, 134, 114, true}, - {228, 230, 105, false}, - {216, 118, 227, true}, - {255, 255, 255, false}, - {43, 134, 133, true}, - {43, 135, 134, true}, - {44, 135, 134, true}, - {59, 182, 179, true}, - {124, 114, 104, true}, - {126, 113, 108, true}, - {129, 112, 109, true}, - {128, 112, 112, true}, + {"#d73a4a", "#fff"}, + {"#0075ca", "#fff"}, + {"#cfd3d7", "#000"}, + {"#a2eeef", "#000"}, + {"#7057ff", "#fff"}, + {"#008672", "#fff"}, + {"#e4e669", "#000"}, + {"#d876e3", "#000"}, + {"#ffffff", "#000"}, + {"#2b8684", "#fff"}, + {"#2b8786", "#fff"}, + {"#2c8786", "#000"}, + {"#3bb6b3", "#000"}, + {"#7c7268", "#fff"}, + {"#7e716c", "#fff"}, + {"#81706d", "#fff"}, + {"#807070", "#fff"}, + {"#84b6eb", "#000"}, } for n, c := range cases { - result := UseLightTextOnBackground(c.r, c.g, c.b) - assert.Equal(t, c.expected, result, "case %d: error should match", n) + assert.Equal(t, c.expected, ContrastColor(c.color), "case %d: error should match", n) } } |