From fd8478df1e9ec9b9ceeb7eed414354792218b02f Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 30 Dec 2024 16:32:25 +0200 Subject: [PATCH] much better getTextColor function --- src/services/color_convert/color_convert.js | 37 +++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js index d92bbbe05..8a0531be6 100644 --- a/src/services/color_convert/color_convert.js +++ b/src/services/color_convert/color_convert.js @@ -1,4 +1,4 @@ -import { invertLightness, contrastRatio } from 'chromatism' +import { invertLightness, contrastRatio, convert } from 'chromatism' // useful for visualizing color when debugging export const consoleColor = (color) => console.log('%c##########', 'background: ' + color + '; color: ' + color) @@ -187,19 +187,36 @@ export const rgba2css = function (rgba) { * @param {Boolean} preserve - try to preserve intended text color's hue/saturation (i.e. no BW) */ export const getTextColor = function (bg, text, preserve) { - const contrast = getContrastRatio(bg, text) - - if (contrast < 4.5) { - const base = typeof text.a !== 'undefined' ? { a: text.a } : {} - const result = Object.assign(base, invertLightness(text).rgb) - if (!preserve && getContrastRatio(bg, result) < 4.5) { + const originalContrast = getContrastRatio(bg, text) + if (!preserve) { + if (originalContrast < 4.5) { // B&W return contrastRatio(bg, text).rgb } - // Inverted color - return result } - return text + + const originalColor = convert(text).hex + const invertedColor = invertLightness(originalColor).hex + const invertedContrast = getContrastRatio(bg, invertedColor) + let workColor + + if (invertedContrast > originalContrast) { + workColor = invertedColor + } else { + workColor = originalColor + } + + let contrast = getContrastRatio(bg, text) + const result = convert(rgb2hex(workColor)).hsl + const delta = result.l > 50 ? 1 : -1 + const multiplier = 10 + while (contrast < 4.5) { + result.l += delta * multiplier + contrast = getContrastRatio(bg, result) + } + + const base = typeof text.a !== 'undefined' ? { a: text.a } : {} + return Object.assign(base, result) } /**