Ich versuche, eine Farbe gegenüber der aktuellen Farbe zu erstellen. Ich meine, wenn die aktuelle Farbe black ist, muss ich white generieren.
Eigentlich habe ich einen Text (die Farbe dieses Textes ist dynamisch, seine Farbe kann zufällig gemacht werden). Dieser Text ist in eine div
eingeteilt, und ich muss die entgegengesetzte Farbe des Texts für den background-color
von div
einstellen. Ich möchte, dass der Text klar in der div
(Farbperspektive) ist.
Die entgegengesetzte Farbe bedeutet: Dunkel/Hell
Ich habe die aktuelle Textfarbe und kann sie an diese Funktion übergeben:
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)
Gibt es eine Idee zur Erstellung einer create_opp_color()
-Funktion?
UPDATE: Produktionsbereit code auf GitHub .
So würde ich es machen:
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);
}
Beispielausgabe:
Fortgeschrittene Version:
Dies hat eine bw
-Option, die entscheidet, ob in Schwarz oder Weiß invertiert werden soll. So erhalten Sie mehr Kontrast, der für das menschliche Auge im Allgemeinen besser ist.
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);
}
Beispielausgabe:
Einfacher Weg dies mit CSS zu erreichen:
mix-blend-mode: difference;
color:white;
In meinem Verständnis Ihrer Frage meinen Sie mit umgekehrter Farbe umgekehrte Farbe.
InvertedColorComponent = 0xFF - ColorComponent
Für die Farbe Rot (# FF0000) bedeutet dies: R = 0xFF oder 255 G = 0x00 oder 0 B = 0x00 oder 0
invertierte Farbe Rot (# 00FFFF) ist:
R = 0xFF - 0xFF = 0x00 or 255 - 255 = 0
G = 0xFF - 0x00 = 0xFF or 255 - 0 = 255
B = 0xFF - 0x00 = 0xFF or 255 - 0 = 255
Weitere Beispiele:
Schwarz (# 000000) wird Weiß (#FFFFFF).
Orange (# FFA500) wird zu # 005AFF
Achten Sie auf die Zugänglichkeit (AA/AAA). Farbkontrast an sich ist nutzlos. Wirklich unterschiedliche Farben können für farbblinde Menschen überhaupt keinen Kontrast haben. IMHO eine Berechnung für eine solche Farbe könnte folgendermaßen aussehen:
(Verwenden Sie zur Vereinfachung "HLS")
Einfach und elegant.
function invertHex(hex {
return (Number(`0x1${hex}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase()
}
invertHex('00FF00'); // FF00FF
Das einfache Umkehren der Hintergrundfarbe in eine Textfarbe funktioniert nicht bei einigen Werten des mittleren Bereichs, z. 0x808080
. Ich hatte versucht, stattdessen die Farbwerte zu verschieben - (v + 0x80) % 0x100
. Sehen Sie eine Demo hier .
Zustimmung zu dem Kommentar aus miguel-svq - obwohl erwartet wird, dass für jeden Berechnungsschritt detailliertere Algorithmen angezeigt werden.
Funktion zum Umkehren der Elementfarbe. Ruft die Helligkeit von jedem ab und invertiert die Textfarbe, wenn sie nahe ist.
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();
}
}
Die Farbe "Klasse" unten. Akzeptiert hex, rgb, rgba (auch bei Prozenten) und kann auch an beide ausgegeben werden. Der Explorer benötigt Polyfills für String.padStart und String.startsWith und der interpolierte String in der toString () - Methode muss stattdessen mit concat geändert werden.
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;
}());