Improve vibrant color contrast in light mode

Modified setVibrantColor in ui.js to darken bright colors when in light mode and lighten dark colors in dark mode, ensuring text and button readability.
This commit is contained in:
Julien Maille 2025-12-26 12:28:05 +01:00
parent 8ccd81b058
commit 45a31075a5

View file

@ -268,24 +268,60 @@ export class UIRenderer {
if (!color) return; if (!color) return;
const root = document.documentElement; const root = document.documentElement;
const theme = root.getAttribute('data-theme');
const isLightMode = theme === 'light';
// Calculate contrast text color let hex = color.replace('#', '');
const hex = color.replace('#', ''); // Handle shorthand hex
const r = parseInt(hex.substr(0, 2), 16); if (hex.length === 3) {
const g = parseInt(hex.substr(2, 2), 16); hex = hex.split('').map(char => char + char).join('');
const b = parseInt(hex.substr(4, 2), 16); }
const brightness = ((r * 299) + (g * 587) + (b * 114)) / 1000;
let r = parseInt(hex.substr(0, 2), 16);
let g = parseInt(hex.substr(2, 2), 16);
let b = parseInt(hex.substr(4, 2), 16);
// Calculate perceived brightness
let brightness = ((r * 299) + (g * 587) + (b * 114)) / 1000;
if (isLightMode) {
// In light mode, the background is white.
// We need the color (used for text/highlights) to be dark enough.
// If brightness is too high (> 150), darken it.
while (brightness > 150) {
r = Math.floor(r * 0.9);
g = Math.floor(g * 0.9);
b = Math.floor(b * 0.9);
brightness = ((r * 299) + (g * 587) + (b * 114)) / 1000;
}
} else {
// In dark mode, the background is dark.
// We need the color to be light enough.
// If brightness is too low (< 80), lighten it.
while (brightness < 80) {
r = Math.min(255, Math.floor(r * 1.15));
g = Math.min(255, Math.floor(g * 1.15));
b = Math.min(255, Math.floor(b * 1.15));
brightness = ((r * 299) + (g * 587) + (b * 114)) / 1000;
// Break if we hit white or can't get brighter to avoid infinite loop
if (r >= 255 && g >= 255 && b >= 255) break;
}
}
const adjustedColor = `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
// Calculate contrast text color for buttons (text on top of the vibrant color)
const foreground = brightness > 128 ? '#000000' : '#ffffff'; const foreground = brightness > 128 ? '#000000' : '#ffffff';
// Set global CSS variables // Set global CSS variables
root.style.setProperty('--primary', color); root.style.setProperty('--primary', adjustedColor);
root.style.setProperty('--primary-foreground', foreground); root.style.setProperty('--primary-foreground', foreground);
root.style.setProperty('--highlight', color); root.style.setProperty('--highlight', adjustedColor);
root.style.setProperty('--highlight-rgb', `${r}, ${g}, ${b}`); root.style.setProperty('--highlight-rgb', `${r}, ${g}, ${b}`);
root.style.setProperty('--active-highlight', color); root.style.setProperty('--active-highlight', adjustedColor);
root.style.setProperty('--ring', color); root.style.setProperty('--ring', adjustedColor);
// Calculate a safe hover color (darken if too light) // Calculate a safe hover color
let hoverColor; let hoverColor;
if (brightness > 200) { if (brightness > 200) {
const dr = Math.floor(r * 0.85); const dr = Math.floor(r * 0.85);