J'essaie de créer une couleur opposée à la couleur actuelle. Je veux dire si la couleur actuelle est black, alors je dois générer white.
En fait, j'ai un texte (la couleur de ce texte est dynamique, sa couleur peut être faite au hasard). Ce texte est dans un div
et je dois définir la couleur opposée de ce texte pour le background-color
de div
. Je voudrais que le texte soit clair dans div
(perspective colorimétrique).
La couleur opposée signifie: Dark/Bright
J'ai la couleur actuelle du texte et je peux le transmettre à cette fonction:
var TextColor = #F0F0F0; // for example (it is a bright color)
function create_opp_color(current color) {
// create opposite color according to current color
}
create_opp_color(TextColor); // this should be something like "#202020" (or a dark color)
Y a-t-il une idée pour créer la fonction create_opp_color()
?
UPDATE: code prêt à la production sur GitHub .
Voici comment je le ferais:
function invertColor(hex) {
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
// invert color components
var r = (255 - parseInt(hex.slice(0, 2), 16)).toString(16),
g = (255 - parseInt(hex.slice(2, 4), 16)).toString(16),
b = (255 - parseInt(hex.slice(4, 6), 16)).toString(16);
// pad each with zeros and return
return '#' + padZero(r) + padZero(g) + padZero(b);
}
function padZero(str, len) {
len = len || 2;
var zeros = new Array(len).join('0');
return (zeros + str).slice(-len);
}
Exemple de sortie:
Version avancée:
Ceci a une option bw
qui décidera s'il faut inverser en noir ou blanc; vous obtiendrez ainsi plus de contraste, ce qui est généralement meilleur pour l'œil humain.
function invertColor(hex, bw) {
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
var r = parseInt(hex.slice(0, 2), 16),
g = parseInt(hex.slice(2, 4), 16),
b = parseInt(hex.slice(4, 6), 16);
if (bw) {
// http://stackoverflow.com/a/3943023/112731
return (r * 0.299 + g * 0.587 + b * 0.114) > 186
? '#000000'
: '#FFFFFF';
}
// invert color components
r = (255 - r).toString(16);
g = (255 - g).toString(16);
b = (255 - b).toString(16);
// pad each with zeros and return
return "#" + padZero(r) + padZero(g) + padZero(b);
}
Exemple de sortie:
Un moyen simple d'y parvenir avec CSS:
mix-blend-mode: difference;
color:white;
Dans ma compréhension de votre question, par couleur opposée, vous voulez dire une couleur inversée.
InvertedColorComponent = 0xFF - ColorComponent
Donc, pour la couleur rouge (# FF0000), cela signifie: R = 0xFF ou 255 G = 0x00 ou 0 B = 0x00 ou 0
la couleur inversée rouge (# 00FFFF) est:
R = 0xFF - 0xFF = 0x00 or 255 - 255 = 0
G = 0xFF - 0x00 = 0xFF or 255 - 0 = 255
B = 0xFF - 0x00 = 0xFF or 255 - 0 = 255
Un autre exemple:
Noir (# 000000) devient blanc (#FFFFFF).
Orange (# FFA500) devient # 005AFF
Attention à l'accessibilité (AA/AAA). Le contraste de couleur en soi est inutile. Des couleurs vraiment différentes ne peuvent pas avoir de contraste du tout pour les daltoniens . À mon humble avis, un calcul pour une telle couleur pourrait se présenter comme suit:
(Utilisez "HLS" pour plus de simplicité)
Simple et élégant.
function invertHex(hex {
return (Number(`0x1${hex}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase()
}
invertHex('00FF00'); // FF00FF
Basculer simplement la couleur d'arrière-plan en couleur de texte ne fonctionnera pas avec certaines valeurs moyennes, par exemple. 0x808080
. J'avais essayé de décaler les valeurs de couleur - (v + 0x80) % 0x100
. Voir une démo ici .
Je suis d’accord avec le commentaire de miguel-svq - bien que nous attendions de voir des algorithmes plus détaillés pour chaque étape de calcul.
Fonction pour inverser la couleur de l'élément. Obtient la luminosité de chacun et s'ils sont proches, inverse la couleur du texte.
function adjustColor(element) {
var style = window.getComputedStyle(element);
var background = new Color(style['background-color']);
var text = new Color(style['color']);
if (Math.abs(background.luma - text.luma) < 100) {
element.style.color = text.inverted.toString();
}
}
La couleur "Classe" ci-dessous. Accepte les valeurs hex, rgb, rgba (même avec des pourcentages) et peut également être reproduit. Explorer aura besoin de polyfills pour String.padStart et String.startsWith et la chaîne interpolée dans la méthode toString () devra être modifiée à l'aide de concat.
const Color = (function () {
function toHex(num, padding) { return num.toString(16).padStart(padding || 2); }
function parsePart(value) {
var perc = value.lastIndexOf('%');
return perc < 0 ? value : value.substr(0, perc);
}
function Color(data) {
if (arguments.length > 1) {
this[0] = arguments[0];
this[1] = arguments[1];
this[2] = arguments[2];
if (arguments.length > 3) { this[3] = arguments[3]; }
} else if (data instanceof Color || Array.isArray(data)) {
this[0] = data[0];
this[1] = data[1];
this[2] = data[2];
this[3] = data[3];
} else if (typeof data === 'string') {
data = data.trim();
if (data[0] === "#") {
switch (data.length) {
case 4:
this[0] = parseInt(data[1], 16); this[0] = (this[0] << 4) | this[0];
this[1] = parseInt(data[2], 16); this[1] = (this[1] << 4) | this[1];
this[2] = parseInt(data[3], 16); this[2] = (this[2] << 4) | this[2];
break;
case 9:
this[3] = parseInt(data.substr(7, 2), 16);
//Fall Through
case 7:
this[0] = parseInt(data.substr(1, 2), 16);
this[1] = parseInt(data.substr(3, 2), 16);
this[2] = parseInt(data.substr(5, 2), 16);
break;
}
} else if (data.startsWith("rgb")) {
var parts = data.substr(data[3] === "a" ? 5 : 4, data.length - (data[3] === "a" ? 6 : 5)).split(',');
this.r = parsePart(parts[0]);
this.g = parsePart(parts[1]);
this.b = parsePart(parts[2]);
if (parts.length > 3) { this.a = parsePart(parts[3]); }
}
}
}
Color.prototype = {
constructor: Color,
0: 255,
1: 255,
2: 255,
3: 255,
get r() { return this[0]; },
set r(value) { this[0] = value == null ? 0 : Math.max(Math.min(parseInt(value), 255), 0); },
get g() { return this[1]; },
set g(value) { this[1] = value == null ? 0 : Math.max(Math.min(parseInt(value), 255), 0); },
get b() { return this[2]; },
set b(value) { this[2] = value == null ? 0 : Math.max(Math.min(parseInt(value), 255), 0); },
get a() { return this[3] / 255; },
set a(value) { this[3] = value == null ? 255 : Math.max(Math.min(value > 1 ? value : parseFloat(value) * 255, 255), 0); },
get luma() { return .299 * this.r + .587 * this.g + .114 * this.b; },
get inverted() { return new Color(255 - this[0], 255 - this[1], 255 - this[2], this[3]); },
toString: function (option) {
if (option === 16) {
return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b) + (this[3] === 255 ? '' : toHex(this[3]));
} else if (option === '%') {
if (this.a !== 1) {
return `rgba(${this.r / 255 * 100}%, ${this.b / 255 * 100}%, ${this.g / 255 * 100}%, ${this.a / 255})`;
} else {
return `rgb(${this.r / 255 * 100}%, ${this.b / 255 * 100}%, ${this.g / 255 * 100})%`;
}
} else {
if (this.a !== 1) {
return `rgba(${this.r}, ${this.b}, ${this.g}, ${this.a})`;
} else {
return `rgb(${this.r}, ${this.b}, ${this.g})`;
}
}
}
};
return Color;
}());