En es6, le contraste d'une chaîne de couleurs à 6 caractères HEX (#123456) peut être calculé avec cette seule ligne :
const contrastColor = c=>["black","white"][~~([1,3,5].map(p=>parseInt(c.substr(p,2),16)).reduce((r,v,i)=>[.299,.587,.114][i]*v+r,0)<128)];
Voici la version décomposée et lisible :
const contrastColor = color =>
{
const lum = [1,3,5].map(pos => //get RGB colors array from the string at positions 1, 3 and 5 (0 = # character)
{
// return converted hex value into decimal for each R, G, and B
return parseInt(color.substr(pos, 2), 16);
}).reduce((result, value, index) =>
{
// with reduce() we can convert an array of numbers into a single number
// result = previous result returned by this function
// value = Red, Green or Blue value of the color
// index = current position index in the array
// y = https://www.w3.org/TR/AERT/#color-contrast
const y = [.299 /*red*/,.587 /*green*/,.114 /*blue*/][index];
return result + y * value // return sum of previous results
}
, 0 /* result = 0 */);
const isDark = lum < 128;
const index = ~~isDark; // convert boolean into 0 or 1
return ["black", "white"][index];
}
function setColors()
{
for(let i = 0; i < 70; i++)
{
const bg = "#" + (~~(Math.random() * 16777216)).toString(16).padStart(6, 0),
color = contrastColor(bg);
node = test.children[i] || document.createElement("span");
node.style.backgroundColor = bg;
node.style.color = color;
node.textContent = bg;
if (!node.parentNode)
test.appendChild(node);
}
}
setColors();
#test
{
display: flex;
flex-wrap: wrap;
font-family: monospace;
}
#test > *
{
padding: 0.3em;
}
<button id="click" onclick="setColors()">change</button>
<div id="test"></div>
1 votes
Juste une pensée plutôt qu'une réponse. Il y a peut-être un moyen de définir vos couleurs en utilisant HSL puis en regardant la valeur de luminosité. Si cette valeur est supérieure à une certaine valeur, appliquez une règle css.
1 votes
On pourrait concevoir d'analyser la couleur d'arrière-plan d'un élément en valeurs R, G, B (et alpha facultatif), en remontant l'arbre DOM si le canal alpha est défini sur zéro. Cependant, essayer de déterminer la couleur d'une image d'arrière-plan est une toute autre affaire.
0 votes
Déjà répondu ici stackoverflow.com/questions/5650924/javascript-color-contraster
0 votes
@Pascal Assez similaire, et bonne contribution mais ce n'est pas la réponse exacte à ma question.