forked from forgejo/forgejo
[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="00b39e15
-a377-4458-95cf-ceec74b78228"><img width="90" alt="Screenshot 2024-04-02 at 01 51 30" src="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)
This commit is contained in:
parent
6f4827b3e0
commit
f6c0c39f1a
14 changed files with 136 additions and 195 deletions
|
@ -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"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue