it-swarm.com.de

Wie kann ich die Gegenfarbe entsprechend der aktuellen Farbe erzeugen?

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?

35
stack

UPDATE: Produktionsbereit code auf GitHub .


So würde ich es machen: 

  1. Konvertieren Sie HEX in RGB
  2. Invertieren Sie die Komponenten R, G und B
  3. Wandeln Sie jede Komponente zurück in HEX
  4. Füllen Sie jede Komponente mit Nullen und Ausgaben auf.
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: 

 enter image description here

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:

 enter image description here

99

Einfacher Weg dies mit CSS zu erreichen:

mix-blend-mode: difference;
color:white;
6
raphadko

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

4
dn Fer

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")

  • Drehen Sie den Farbton um 180º, um den (möglicherweise unbrauchbaren) maximalen Farbkontrast zu erhalten
  • Berechnen Sie den Helligkeitsunterschied.
  • (Berechne den Farbunterschied ... unnötig, es ist maximal oder fast)
  • Berechnen Sie das Kontrastverhältnis.
  • Wenn die resultierende Farbe den Anforderungen entspricht, endet die Anforderungsberechnung, andernfalls Schleife:
    • Wenn der Helligkeitsunterschied nicht groß genug ist, erhöhen oder verringern Sie die berechnete Farbhelligkeit (L) um einen bestimmten Betrag oder ein bestimmtes Verhältnis (nach oben oder nach unten).
    • Prüfen Sie, ob es Ihren Anforderungen entspricht, ob die Berechnung beendet ist.
    • wenn die Leuchtkraft mehr erhöht (oder verringert) werden kann, gibt es keine gültige Farbe, um die Anforderungen zu erfüllen. Versuchen Sie es einfach mit Schwarz und Weiß, nehmen Sie "die beste" von diesen (wahrscheinlich die mit größerem Kontrastverhältnis) und beenden Sie.
4
miguel-svq

Einfach und elegant.

function invertHex(hex {
  return (Number(`0x1${hex}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase()
}

invertHex('00FF00'); // FF00FF
1
Gerard Lamusse

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. 

1
jason_zhuyx

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;
}());
0
Derek Ziemba