Programmgesteuert eine Hex-Farbe aufhellen oder abdunkeln (oder RGB und Farben mischen)


504

Hier ist eine Funktion, an der ich gearbeitet habe, um eine Hex-Farbe programmgesteuert um einen bestimmten Betrag aufzuhellen oder abzudunkeln. Geben Sie einfach eine Zeichenfolge wie "3F6D2A"für die Farbe ( col) und eine Base10-Ganzzahl ( amt) ein, damit der Betrag aufgehellt oder abgedunkelt wird. Geben Sie zum Abdunkeln eine negative Zahl ein (dh -20).

Der Grund für mich, dies zu tun, war, dass all die Lösungen, die ich bisher gefunden habe, das Problem zu komplizieren schienen. Und ich hatte das Gefühl, dass dies mit nur ein paar Codezeilen möglich ist. Bitte lassen Sie mich wissen, wenn Sie Probleme finden oder Anpassungen vornehmen müssen, die dies beschleunigen würden.

function LightenDarkenColor(col, amt) {
  col = parseInt(col, 16);
  return (((col & 0x0000FF) + amt) | ((((col >> 8) & 0x00FF) + amt) << 8) | (((col >> 16) + amt) << 16)).toString(16);
}


// TEST
console.log( LightenDarkenColor("3F6D2A",40) );

Für die Entwicklung ist hier eine leichter zu lesende Version:

function LightenDarkenColor(col, amt) {
  var num = parseInt(col, 16);
  var r = (num >> 16) + amt;
  var b = ((num >> 8) & 0x00FF) + amt;
  var g = (num & 0x0000FF) + amt;
  var newColor = g | (b << 8) | (r << 16);
  return newColor.toString(16);
}


// TEST
console.log(LightenDarkenColor("3F6D2A", -40));

Und schließlich eine Version für Farben, die am Anfang möglicherweise das "#" haben (oder auch nicht). Plus Anpassung für falsche Farbwerte:

function LightenDarkenColor(col,amt) {
    var usePound = false;
    if ( col[0] == "#" ) {
        col = col.slice(1);
        usePound = true;
    }

    var num = parseInt(col,16);

    var r = (num >> 16) + amt;

    if ( r > 255 ) r = 255;
    else if  (r < 0) r = 0;

    var b = ((num >> 8) & 0x00FF) + amt;

    if ( b > 255 ) b = 255;
    else if  (b < 0) b = 0;

    var g = (num & 0x0000FF) + amt;

    if ( g > 255 ) g = 255;
    else if  ( g < 0 ) g = 0;

    return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
}

OK, jetzt sind es nicht nur ein paar Zeilen, sondern es scheint viel einfacher zu sein. Wenn Sie das "#" nicht verwenden und nicht nach Farben außerhalb des Bereichs suchen müssen, sind es nur ein paar Zeilen.

Wenn Sie das "#" nicht verwenden, können Sie es einfach in folgenden Code einfügen:

var myColor = "3F6D2A";
myColor = LightenDarkenColor(myColor,10);
thePlaceTheColorIsUsed = ("#" + myColor);

Ich denke meine Hauptfrage ist, bin ich hier richtig? Umfasst dies nicht einige (normale) Situationen?


1
Wenn Sie beim Ändern von Farben keine erwarteten Ergebnisse erhalten, empfehle ich einen Blick in den LAB-Farbraum, der näher am menschlichen Sehen liegt. Viele Sprachen haben Bibliotheken zur Konvertierung. Nach meiner Erfahrung können besonders Orangetöne beim Abdunkeln oder Aufhellen problematisch sein.
Henrik

Sehr guter Punkt. Der Hauptzweck dieser Frage war es jedoch, erstens die schnellste Laufzeit- und kleinste Größenformel zu finden ... und zweitens ihre Genauigkeit. Deshalb habe ich mich nicht mit der Umstellung auf HSL oder was auch immer befasst. Hier sind Geschwindigkeit und Größe wichtiger. Aber wie Sie mit meiner Version 2 der Formel sehen können. Die Verwendung von LERP zum Schattieren führt zu angenehmen Orangen im gesamten Farbbereich. Schauen Sie sich die Farbkarte unten an und lassen Sie mich wissen, ob dieser Farbbereich nicht annähernd genau ist.
Pimp Trizkit

Ich war ein bisschen verwirrt mit der Struktur hier, aber Sie haben Recht, die Orangenwerte für shadowColor1 scheinen sehr gut zu sein.
Henrik

Lol, du meinst shadowColor2. Ich denke, die Struktur, über die Sie sprechen, ist das Gesamtlayout der Antwort selbst? Irgendwelche Hinweise, um klarer zu machen?
Pimp Trizkit

3
Es gibt nur ein Problem in der Funktion mit # oben, dass die führenden Nullen nicht erstellt werden, wenn der endgültige Hex-Code mit Nullen beginnt. Wenn der Hex-Code beispielsweise # 00a6b7 lautet, wird er als # a6b7 ausgegeben, was bei Verwendung als CSS nicht funktioniert. Sie können dies korrigieren, indem Sie die Rückgabezeile durch folgende ersetzen: var string = "000000" + (g | (b << 8) | (r << 16)). ToString (16); return (usePound? "#": "") + string.substr (string.length-6);
Rafael Levy

Antworten:


877

Nun, diese Antwort ist zu einem eigenen Tier geworden. Viele neue Versionen, es wurde lange dumm. Vielen Dank an alle, die zu dieser Antwort beigetragen haben. Aber um es für die Massen einfach zu halten. Ich habe alle Versionen / den Verlauf der Entwicklung dieser Antwort in meinem Github archiviert . Und hier auf StackOverflow mit der neuesten Version von vorne angefangen. Ein besonderer Dank geht an Mike 'Pomax' Kamermans für diese Version. Er gab mir die neue Mathematik.


Diese Funktion ( pSBC) nimmt eine HEX- oder RGB-Webfarbe an. pSBCkann es dunkler oder heller schattieren oder mit einer zweiten Farbe mischen und es auch direkt durchlaufen lassen, aber von Hex zu RGB (Hex2RGB) oder RGB zu Hex (RGB2Hex) konvertieren. Alles ohne dass Sie wissen, welches Farbformat Sie verwenden.

Dies läuft sehr schnell, wahrscheinlich am schnellsten, insbesondere angesichts der vielen Funktionen. Es war eine lange Zeit in der Herstellung. Sehen Sie die ganze Geschichte auf meinem Github . Wenn Sie den absolut kleinsten und schnellsten Weg zum Schattieren oder Mischen suchen, lesen Sie die unten stehenden Mikrofunktionen und verwenden Sie einen der 2-Liner-Geschwindigkeitsdämonen. Sie eignen sich hervorragend für intensive Animationen, aber diese Version hier ist für die meisten Animationen schnell genug.

Diese Funktion verwendet Log Blending oder Linear Blending. Es wird jedoch NICHT in HSL konvertiert, um eine Farbe richtig aufzuhellen oder abzudunkeln. Daher unterscheiden sich die Ergebnisse dieser Funktion von den viel größeren und viel langsameren Funktionen, die HSL verwenden.

jsFiddle mit pSBC

github> pSBC Wiki

Eigenschaften:

  • Erkennt und akzeptiert Standard-Hex-Farben in Form von Zeichenfolgen automatisch. Zum Beispiel: "#AA6622"oder "#bb551144".
  • Erkennt und akzeptiert Standard-RGB-Farben in Form von Zeichenfolgen automatisch. Zum Beispiel: "rgb(123,45,76)"oder "rgba(45,15,74,0.45)".
  • Schattiert die Farben prozentual in Weiß oder Schwarz.
  • Mischt Farben prozentual zusammen.
  • Konvertiert Hex2RGB und RGB2Hex gleichzeitig oder solo.
  • Akzeptiert 3-stellige (oder 4-stellige mit Alpha) HEX-Farbcodes in der Form #RGB (oder #RGBA). Es wird sie erweitern. Zum Beispiel: "#C41"wird "#CC4411".
  • Akzeptiert und mischt Alphakanäle (linear). Wenn entweder die c0(von) Farbe oder die c1(bis) Farbe einen Alpha-Kanal hat, hat die zurückgegebene Farbe einen Alpha-Kanal. Wenn beide Farben einen Alphakanal haben, ist die zurückgegebene Farbe eine lineare Mischung der beiden Alphakanäle unter Verwendung des angegebenen Prozentsatzes (als wäre es ein normaler Farbkanal). Wenn nur eine der beiden Farben einen Alphakanal hat, wird dieses Alpha nur an die zurückgegebene Farbe weitergeleitet. Dies ermöglicht das Mischen / Schattieren einer transparenten Farbe unter Beibehaltung des Transparenzniveaus. Wenn die Transparenzstufen ebenfalls gemischt werden sollen, stellen Sie sicher, dass beide Farben Alphas enthalten. Beim Schattieren wird der Alphakanal gerade durchlaufen. Wenn Sie eine grundlegende Schattierung wünschen, die auch den Alphakanal schattiert, verwenden Sie rgb(0,0,0,1)oder rgb(255,255,255,1)als Ihrec1(zu) Farbe (oder deren Hex-Äquivalente). Bei RGB-Farben wird der Alphakanal der zurückgegebenen Farbe auf 3 Dezimalstellen gerundet.
  • RGB2Hex- und Hex2RGB-Konvertierungen sind bei der Verwendung von Blending implizit. Unabhängig von der c0(von) Farbe; Die zurückgegebene Farbe hat immer das Farbformat der c1(zu) Farbe, falls vorhanden. Wenn es keine c1(zu) Farbe gibt, geben Sie sie 'c'als c1Farbe ein und sie schattiert und konvertiert die c0Farbe. Wenn nur eine Konvertierung gewünscht wird, geben Sie diese auch 0als Prozentsatz ( p) ein. Wenn die c1Farbe weggelassen oder ein Nicht übergeben stringwird, wird sie nicht konvertiert.
  • Eine sekundäre Funktion wird ebenfalls zur globalen hinzugefügt. pSBCrkann eine Hex- oder RGB-Farbe übergeben werden und es wird ein Objekt zurückgegeben, das diese Farbinformationen enthält. Es hat die Form: {r: XXX, g: XXX, b: XXX, a: X.XXX}. Wo .r, .gund .bhat Bereich von 0 bis 255. Und wenn es keine Alpha ist: .a-1. Ansonsten: .ahat einen Bereich von 0,000 bis 1.000.
  • Für RGB - Ausgang, gibt er rgba()über , rgb()wenn eine Farbe mit einem Alphakanal zu übergeben wurde c0(von) und / oder c1(to).
  • Kleinere Fehlerprüfung wurde hinzugefügt. Es ist nicht perfekt. Es kann immer noch abstürzen oder Quatsch verursachen. Aber es wird ein paar Sachen fangen. Grundsätzlich wird zurückgegeben, wenn die Struktur in irgendeiner Weise falsch ist oder wenn der Prozentsatz keine Zahl ist oder außerhalb des Gültigkeitsbereichs liegt null. Ein Beispiel: pSBC(0.5,"salt") == nullWo, wie es denkt, #salteine gültige Farbe ist. Löschen Sie die vier Zeilen, die mit enden return null;, um diese Funktion zu entfernen und sie schneller und kleiner zu machen.
  • Verwendet Log Blending. Übergeben Sie truefür l(den 4. Parameter), um die lineare Überblendung zu verwenden.

Code:

// Version 4.0
const pSBC=(p,c0,c1,l)=>{
    let r,g,b,P,f,t,h,i=parseInt,m=Math.round,a=typeof(c1)=="string";
    if(typeof(p)!="number"||p<-1||p>1||typeof(c0)!="string"||(c0[0]!='r'&&c0[0]!='#')||(c1&&!a))return null;
    if(!this.pSBCr)this.pSBCr=(d)=>{
        let n=d.length,x={};
        if(n>9){
            [r,g,b,a]=d=d.split(","),n=d.length;
            if(n<3||n>4)return null;
            x.r=i(r[3]=="a"?r.slice(5):r.slice(4)),x.g=i(g),x.b=i(b),x.a=a?parseFloat(a):-1
        }else{
            if(n==8||n==6||n<4)return null;
            if(n<6)d="#"+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]+(n>4?d[4]+d[4]:"");
            d=i(d.slice(1),16);
            if(n==9||n==5)x.r=d>>24&255,x.g=d>>16&255,x.b=d>>8&255,x.a=m((d&255)/0.255)/1000;
            else x.r=d>>16,x.g=d>>8&255,x.b=d&255,x.a=-1
        }return x};
    h=c0.length>9,h=a?c1.length>9?true:c1=="c"?!h:false:h,f=this.pSBCr(c0),P=p<0,t=c1&&c1!="c"?this.pSBCr(c1):P?{r:0,g:0,b:0,a:-1}:{r:255,g:255,b:255,a:-1},p=P?p*-1:p,P=1-p;
    if(!f||!t)return null;
    if(l)r=m(P*f.r+p*t.r),g=m(P*f.g+p*t.g),b=m(P*f.b+p*t.b);
    else r=m((P*f.r**2+p*t.r**2)**0.5),g=m((P*f.g**2+p*t.g**2)**0.5),b=m((P*f.b**2+p*t.b**2)**0.5);
    a=f.a,t=t.a,f=a>=0||t>=0,a=f?a<0?t:t<0?a:a*P+t*p:0;
    if(h)return"rgb"+(f?"a(":"(")+r+","+g+","+b+(f?","+m(a*1000)/1000:"")+")";
    else return"#"+(4294967296+r*16777216+g*65536+b*256+(f?m(a*255):0)).toString(16).slice(1,f?undefined:-2)
}

Verwendungszweck:

// Setup:

let color1 = "rgb(20,60,200)";
let color2 = "rgba(20,60,200,0.67423)";
let color3 = "#67DAF0";
let color4 = "#5567DAF0";
let color5 = "#F3A";
let color6 = "#F3A9";
let color7 = "rgb(200,60,20)";
let color8 = "rgba(200,60,20,0.98631)";

// Tests:

/*** Log Blending ***/
// Shade (Lighten or Darken)
pSBC ( 0.42, color1 ); // rgb(20,60,200) + [42% Lighter] => rgb(166,171,225)
pSBC ( -0.4, color5 ); // #F3A + [40% Darker] => #c62884
pSBC ( 0.42, color8 ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(225,171,166,0.98631)

// Shade with Conversion (use "c" as your "to" color)
pSBC ( 0.42, color2, "c" ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #a6abe1ac

// RGB2Hex & Hex2RGB Conversion Only (set percentage to zero)
pSBC ( 0, color6, "c" ); // #F3A9 + [Convert] => rgba(255,51,170,0.6)

// Blending
pSBC ( -0.5, color2, color8 ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(142,60,142,0.83)
pSBC ( 0.7, color2, color7 ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(168,60,111,0.67423)
pSBC ( 0.25, color3, color7 ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(134,191,208)
pSBC ( 0.75, color7, color3 ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #86bfd0

/*** Linear Blending ***/
// Shade (Lighten or Darken)
pSBC ( 0.42, color1, false, true ); // rgb(20,60,200) + [42% Lighter] => rgb(119,142,223)
pSBC ( -0.4, color5, false, true ); // #F3A + [40% Darker] => #991f66
pSBC ( 0.42, color8, false, true ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(223,142,119,0.98631)

// Shade with Conversion (use "c" as your "to" color)
pSBC ( 0.42, color2, "c", true ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #778edfac

// RGB2Hex & Hex2RGB Conversion Only (set percentage to zero)
pSBC ( 0, color6, "c", true ); // #F3A9 + [Convert] => rgba(255,51,170,0.6)

// Blending
pSBC ( -0.5, color2, color8, true ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(110,60,110,0.83)
pSBC ( 0.7, color2, color7, true ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(146,60,74,0.67423)
pSBC ( 0.25, color3, color7, true ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(127,179,185)
pSBC ( 0.75, color7, color3, true ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #7fb3b9

/*** Other Stuff ***/
// Error Checking
pSBC ( 0.42, "#FFBAA" ); // #FFBAA + [42% Lighter] => null  (Invalid Input Color)
pSBC ( 42, color1, color5 ); // rgb(20,60,200) + #F3A + [4200% Blend] => null  (Invalid Percentage Range)
pSBC ( 0.42, {} ); // [object Object] + [42% Lighter] => null  (Strings Only for Color)
pSBC ( "42", color1 ); // rgb(20,60,200) + ["42"] => null  (Numbers Only for Percentage)
pSBC ( 0.42, "salt" ); // salt + [42% Lighter] => null  (A Little Salt is No Good...)

// Error Check Fails (Some Errors are not Caught)
pSBC ( 0.42, "#salt" ); // #salt + [42% Lighter] => #a5a5a500  (...and a Pound of Salt is Jibberish)

// Ripping
pSBCr ( color4 ); // #5567DAF0 + [Rip] => [object Object] => {'r':85,'g':103,'b':218,'a':0.941}

Das folgende Bild zeigt den Unterschied zwischen den beiden Mischmethoden:


Mikrofunktionen

Wenn Sie wirklich Geschwindigkeit und Größe wollen, müssen Sie RGB und nicht HEX verwenden. RGB ist unkomplizierter und einfacher, HEX schreibt zu langsam und ist in zu vielen Varianten für einen einfachen Zweiliner erhältlich (dh es kann sich um einen 3-, 4-, 6- oder 8-stelligen HEX-Code handeln). Sie müssen auch einige Funktionen opfern, keine Fehlerprüfung, kein HEX2RGB oder RGB2HEX. Außerdem müssen Sie eine bestimmte Funktion (basierend auf dem Funktionsnamen unten) für die Farbüberblendungsmathematik auswählen und wenn Sie Schattierungen oder Überblendungen wünschen. Diese Funktionen unterstützen Alphakanäle. Und wenn beide Eingabefarben Alphas haben, werden sie linear gemischt. Wenn nur eine der beiden Farben ein Alpha hat, wird es direkt an die resultierende Farbe weitergegeben. Im Folgenden sind zwei Liner-Funktionen aufgeführt, die unglaublich schnell und klein sind:

const RGB_Linear_Blend=(p,c0,c1)=>{
    var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,j=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")";
    return"rgb"+(x?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+i(e[3]=="a"?e.slice(5):e.slice(4))*p)+","+r(i(b)*P+i(f)*p)+","+r(i(c)*P+i(g)*p)+j;
}

const RGB_Linear_Shade=(p,c)=>{
    var i=parseInt,r=Math.round,[a,b,c,d]=c.split(","),P=p<0,t=P?0:255*p,P=P?1+p:1-p;
    return"rgb"+(d?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+t)+","+r(i(b)*P+t)+","+r(i(c)*P+t)+(d?","+d:")");
}

const RGB_Log_Blend=(p,c0,c1)=>{
    var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,j=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")";
    return"rgb"+(x?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+p*i(e[3]=="a"?e.slice(5):e.slice(4))**2)**0.5)+","+r((P*i(b)**2+p*i(f)**2)**0.5)+","+r((P*i(c)**2+p*i(g)**2)**0.5)+j;
}

const RGB_Log_Shade=(p,c)=>{
    var i=parseInt,r=Math.round,[a,b,c,d]=c.split(","),P=p<0,t=P?0:p*255**2,P=P?1+p:1-p;
    return"rgb"+(d?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+t)**0.5)+","+r((P*i(b)**2+t)**0.5)+","+r((P*i(c)**2+t)**0.5)+(d?","+d:")");
}

Willst du mehr Infos? Lesen Sie den vollständigen Artikel über Github .

PT

(Ps Wenn jemand die Mathematik für eine andere Mischmethode hat, teile sie bitte mit.)


8
Eine PHP-Version für diejenigen, die es brauchen: gist.github.com/chaoszcat/5325115#file-gistfile1-php
Lionel Chan

28
Ich habe TinyColor -tinycolor.darken(color,amount);
FWrnr

4
Toller Beitrag ... :) ... habe gerade eine Swift-Erweiterung erstellt: gist.github.com/matejukmar/1da47f7a950d1ba68a95
Matej Ukmar

2
Hier ist die PHP-Version für die aktualisierte Version von shadowColor2:function shadeColor2($color, $percent) { $color = str_replace("#", "", $color); $t=$percent<0?0:255; $p=$percent<0?$percent*-1:$percent; $RGB = str_split($color, 2); $R=hexdec($RGB[0]); $G=hexdec($RGB[1]); $B=hexdec($RGB[2]); return '#'.substr(dechex(0x1000000+(round(($t-$R)*$p)+$R)*0x10000+(round(($t-$G)*$p)+$G)*0x100+(round(($t-$B)*$p)+$B)),1); }
Kevin M

2
Entschuldigung, ich habe diesen Punkt anscheinend verpasst. Es gibt vielleicht zwei Gründe. Das erste und offensichtliche ist, dass ich Math.Round verwende und Sie keine Dezimalzahlen für eine genaue Färbung verwenden können (Farben haben keine Dezimalstellen in Hex). Wenn zum Beispiel der rote Kanal ist 8, fügen 10%Sie hinzu, Sie erhalten, 8.8welche Runden zu 9. Dann 9.09%wegnehmen 9und du bekommst 8.1819. Welche Runden dazu führen 8, ist ein schlechtes Beispiel. Aber es zeigt immer noch , dass Sie nehmen 9.09%von 9und nicht 8.8. Es könnte also einige Zahlen geben, die nicht genau so abrunden wie mein Beispiel hier.
Pimp Trizkit

122

Ich habe eine Lösung gefunden, die für mich sehr gut funktioniert:

function shadeColor(color, percent) {

    var R = parseInt(color.substring(1,3),16);
    var G = parseInt(color.substring(3,5),16);
    var B = parseInt(color.substring(5,7),16);

    R = parseInt(R * (100 + percent) / 100);
    G = parseInt(G * (100 + percent) / 100);
    B = parseInt(B * (100 + percent) / 100);

    R = (R<255)?R:255;  
    G = (G<255)?G:255;  
    B = (B<255)?B:255;  

    var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
    var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
    var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));

    return "#"+RR+GG+BB;
}

Beispiel Aufhellen:

shadeColor("#63C6FF",40);

Beispiel Verdunkeln:

shadeColor("#63C6FF",-40);

4
Schön, ich mag den Prozentsatz! +1 Tho, ich würde R = ((R<255)?R:255).toString(16);dann R = R.length==1 ? "0"+R : Rfür Geschwindigkeit tun . Und ich bin mir nicht sicher, wozu der toUpperCase gut ist?
Pimp Trizkit

Es ist unnötig. Ich füge das nur für hübschen Druck während des Tests hinzu. Ich werde das bearbeiten.
Pablo

Sehr schön. Sollte jedoch 100% heller nicht vollständig weiß und 100% dunkel immer schwarz werden, egal welche Farbe? es scheint, dass -100 jede Farbe schwarz macht, aber 100 (positiv) macht es nicht vollständig weiß.
Kevin M

4
funktioniert nicht mit Volltonfarben wie # ff0000, # 00ff00, # 0000ff
Hitori

Damit es mit schwarzer Farbe funktioniert, habe ich gerade diesen Hack gemacht var R = parseInt(color.substring(1, 3), 16) var G = parseInt(color.substring(3, 5), 16) var B = parseInt(color.substring(5, 7), 16) if (R == 0) R = 32; if (G == 0) G = 32; if (B == 0) B = 32;
Irfan Raza

21

Hier ist ein supereinfacher Einzeiler, der auf Erics Antwort basiert

function adjust(color, amount) {
    return '#' + color.replace(/^#/, '').replace(/../g, color => ('0'+Math.min(255, Math.max(0, parseInt(color, 16) + amount)).toString(16)).substr(-2));
}

Beispiele:

adjust('#ffffff', -20) => "#ebebeb"
adjust('000000', 20) => "#141414"

7
"super einfach".
Andrew

5

Dies ist, was ich basierend auf Ihrer Funktion verwendet habe. Ich bevorzuge Schritte über dem Prozentsatz, weil es für mich intuitiver ist.

Beispielsweise unterscheiden sich 20% eines 200-Blau-Werts stark von 20% eines 40-Blau-Werts.

Wie auch immer, hier ist meine Modifikation, danke für deine ursprüngliche Funktion.

function adjustBrightness(col, amt) {

    var usePound = false;

    if (col[0] == "#") {
        col = col.slice(1);
        usePound = true;
    }

    var R = parseInt(col.substring(0,2),16);
    var G = parseInt(col.substring(2,4),16);
    var B = parseInt(col.substring(4,6),16);

    // to make the colour less bright than the input
    // change the following three "+" symbols to "-"
    R = R + amt;
    G = G + amt;
    B = B + amt;

    if (R > 255) R = 255;
    else if (R < 0) R = 0;

    if (G > 255) G = 255;
    else if (G < 0) G = 0;

    if (B > 255) B = 255;
    else if (B < 0) B = 0;

    var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
    var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
    var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));

    return (usePound?"#":"") + RR + GG + BB;

}

Fand dies viel nützlicher als die Top-Antwort, weil die Top-Antwort meine Farben sehr intensiv machte, anstatt nur dunkler. Prost Eric
Wurm

4

Ich habe Ihre Funktion ausprobiert und es gab einen kleinen Fehler: Wenn ein endgültiger 'r'-Wert nur eine Ziffer ist, wird das Ergebnis wie folgt angezeigt:' a0a0a ', wenn der richtige Wert beispielsweise' 0a0a0a 'ist. Ich habe es nur schnell behoben, indem ich dies anstelle Ihrer Rückgabe hinzugefügt habe:

var rStr = (r.toString(16).length < 2)?'0'+r.toString(16):r.toString(16);
var gStr = (g.toString(16).length < 2)?'0'+g.toString(16):g.toString(16);
var bStr = (b.toString(16).length < 2)?'0'+b.toString(16):b.toString(16);

return (usePound?"#":"") + rStr + gStr + bStr;

Vielleicht ist es nicht so schön, aber es macht die Arbeit. Tolle Funktion, übrigens. Genau das, was ich brauchte. :) :)


1
Vielen Dank für das Debug und Kompliment! Schade, dass es keine Antwort darauf gibt, ob es einen schnelleren Weg gibt oder nicht, was meine Hauptfrage ist. Wie möglicherweise eine, die alle hexadezimalen und keine Basiskonvertierungen verwendet. Tho, ich denke du hast mir gesagt, ob ich den richtigen Code habe (+1). Leider hat das Update erheblich mehr Overhead (jetzt 6-maliger Aufruf von String) und etwas weniger KISS hinzugefügt. Vielleicht wäre es schneller zu überprüfen, ob die base10-Nummer 15 oder weniger ist, bevor die base16-Konvertierung durchgeführt wird. Aber ich mag!
Pimp Trizkit

4

Haben Sie über eine rgb> hsl-Konvertierung nachgedacht? dann einfach die Leuchtkraft auf und ab bewegen? das ist der Weg, den ich gehen würde.

Ein kurzer Blick auf einige Algorithmen brachte mir die folgenden Seiten.

PHP: http://serennu.com/colour/rgbtohsl.php

Javascript: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript

BEARBEITEN Der obige Link ist nicht mehr gültig. Sie können für die git Hub anzuzeigen Seite Quelle oder der Kern

Alternativ könnte eine andere StackOverflow- Frage ein guter Ort sein, um nachzuschauen.


Obwohl dies nicht die richtige Wahl für das OP ist, ist das Folgende eine Annäherung an den Code, den ich ursprünglich vorgeschlagen hatte. (Angenommen, Sie haben RGB / HSL-Konvertierungsfunktionen)

var SHADE_SHIFT_AMOUNT = 0.1; 

function lightenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.min(hsl[2] + SHADE_SHIFT_AMOUNT, 1);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

function darkenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.max(hsl[2] - SHADE_SHIFT_AMOUNT, 0);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

Dies setzt voraus:

  1. Sie haben Funktionen hslToRgbund rgbToHsl.
  2. Der Parameter colorValueist eine Zeichenfolge in der Form #RRGGBB

Wenn es um CSS geht, gibt es eine Syntax für die Angabe von hsl / hsla für IE9 / Chrome / Firefox.


Interessant, aber müsste ich dann nicht von Hex-String zu RGB zu HSL konvertieren? Scheint komplizierter zu sein. Vielleicht fehlt mir etwas. Aber ich suche nach einem KISS-Weg, um dies so schnell wie möglich zu tun (Ausführungszeit). Ich fühle mich ideal, wenn ich alles in Hex machen könnte, wäre das am schnellsten. Die Lösung, die ich hier entwickelt habe, besteht jedoch darin, zu rgb zu gehen, um einen inkrementellen Betrag hinzufügen zu können.
Pimp Trizkit

Ja, ich gehe davon aus, dass es langsamer und komplizierter wäre, und wenn Sie die Konvertierung von rgb in hsl nirgendwo anders verwenden, wäre dies wahrscheinlich nicht die einfachste Lösung. Es wäre jedoch genauer als das Hinzufügen zu RGB-Werten, obwohl ich selbst keine große Farbperson bin. Es hängt alles davon ab, wie genau Sie sein wollen, denke ich.
James Khoury

Was ist der Genauigkeitsverlust, den Sie erwähnen? Ich nehme an, Sie meinen, alle [Web] -Farben sind mit RGB nicht erreichbar oder so?
Pimp Trizkit

Wie gesagt, ich weiß nicht so viel über Farbe: Wiki Color Theory
James Khoury

@Pimp Trizkit: Es ist weniger genau, weil (und das ist nur meine Theorie ... ich bin kein Farbexperte) Sie jeden Kanal um den gleichen Betrag verschieben, egal wie viel von dieser Farbe es zu Beginn gab. Ich denke , das würde zu einer Verringerung der Sättigung führen, da Sie die Kanäle einander näher bringen (prozentual). Natürlich ist ein Überlauf / Unterlauf ohnehin unvermeidlich.
Matthew Crumley

2

C # -Version ... Beachten Sie, dass ich Farbzeichenfolgen in diesem Format # FF12AE34 erhalte und die #FF ausschneiden muss.

    private string GetSmartShadeColorByBase(string s, float percent)
    {
        if (string.IsNullOrEmpty(s))
            return "";
        var r = s.Substring(3, 2);
        int rInt = int.Parse(r, NumberStyles.HexNumber);
        var g = s.Substring(5, 2);
        int gInt = int.Parse(g, NumberStyles.HexNumber);
        var b = s.Substring(7, 2);
        int bInt = int.Parse(b, NumberStyles.HexNumber);

        var t = percent < 0 ? 0 : 255;
        var p = percent < 0 ? percent*-1 : percent;

        int newR = Convert.ToInt32(Math.Round((t - rInt) * p) + rInt);
        var newG = Convert.ToInt32(Math.Round((t - gInt) * p) + gInt);
        var newB = Convert.ToInt32(Math.Round((t - bInt) * p) + bInt);

        return String.Format("#{0:X2}{1:X2}{2:X2}", newR, newG, newB);
    }

5
Nie zuvor C # verwendet, aber es sieht so aus, als wären die letzten drei Variablendeklarationen seltsam. Ein intund zwei varsfür denselben Datentyp.
Pimp Trizkit

4
Das Schlüsselwort var in C # bedeutet, dass der Compiler den Typ zur Kompilierungszeit ableiten darf. Im obigen Beispiel definieren int und var eine Variable vom gleichen Typ - int. Dies ist nützlich, wenn Sie einen langen Typnamen haben oder auf einen anonymen Typ verweisen möchten. Es ist seltsam, weil user1618171 zwei Variablendeklarationsstile gemischt hat - wahrscheinlich ein Tippfehler.
Daniel James Bryars

2

Ich wollte eine Farbe auf eine bestimmte Helligkeitsstufe ändern - egal welche Helligkeit die Farbe vorher hatte - hier ist eine einfache JS-Funktion, die gut zu funktionieren scheint, obwohl ich sicher bin, dass sie kürzer sein könnte

function setLightPercentage(col: any, p: number) {
    const R = parseInt(col.substring(1, 3), 16);
    const G = parseInt(col.substring(3, 5), 16);
    const B = parseInt(col.substring(5, 7), 16);
    const curr_total_dark = (255 * 3) - (R + G + B);

    // calculate how much of the current darkness comes from the different channels
    const RR = ((255 - R) / curr_total_dark);
    const GR = ((255 - G) / curr_total_dark);
    const BR = ((255 - B) / curr_total_dark);

    // calculate how much darkness there should be in the new color
    const new_total_dark = ((255 - 255 * (p / 100)) * 3);

    // make the new channels contain the same % of available dark as the old ones did
    const NR = 255 - Math.round(RR * new_total_dark);
    const NG = 255 - Math.round(GR * new_total_dark);
    const NB = 255 - Math.round(BR * new_total_dark);

    const RO = ((NR.toString(16).length === 1) ? "0" + NR.toString(16) : NR.toString(16));
    const GO = ((NG.toString(16).length === 1) ? "0" + NG.toString(16) : NG.toString(16));
    const BO = ((NB.toString(16).length === 1) ? "0" + NB.toString(16) : NB.toString(16));

    return "#" + RO + GO + BO;}

Coolio! Ich nehme an, das phat Reichweite 0-100? Ich weiß nicht einmal, wie man die Helligkeit in RGB richtig definiert, das ist eine HSL-Sache. Ist zum Beispiel #FF00FFheller als #FF0000? Wenn ja, würde dies bedeuten, dass Magenta doppelt so hell wie Rot ist. Daher wird der reine Rottest verwendet. Pass in reinem Rot #FF0000, eingestellt auf 50% Helligkeit, und hier bekommen wir #FF4040, ist das richtig? Ich würde raten, Rot 50% Helligkeit zu machen, wir würden dunkler werden, da es bereits vollständig hell ist. Wie in #800000oder 150% Helligkeit #FF8080. Ist Rosa ein helleres Rot? oder ist rot schon ganz hell?
Pimp Trizkit

Sie haben Recht - ich hätte erwähnen sollen, dass p im Bereich von 1-100 liegen muss!
Torbjörn Josefsson

# FF00FF hat 255 als Wert im roten Kanal, 0 im grünen Kanal und 255 im blauen Kanal. Je höher die kombinierten Werte in den Kanälen sind, desto höher ist die Helligkeit der Farbe. Die Zahl p gibt an, dass die neue Farbe 50% so hell sein soll, wie die ursprüngliche Farbe sein kann. Ich bin nicht zu 100% der Meinung, dass # FF4040 die richtige Antwort auf "50% so hell wie möglich Rot" ist. Die Erzeugung dunklerer Farbtöne (mit in diesem Fall einem niedrigeren Wert im roten Kanal) würde eine Änderung erfordern
Torbjörn Josefsson

Ja, ich habe nur auf die Mehrdeutigkeit hingewiesen, wenn es um die Helligkeit in RGB geht. Bei der Konvertierung in HSL ist der LKanal buchstäblich hell. Mein [persönliches mentales] Problem hier ist, dass es für mich #FF0000völlig hell ist. Und #FF4040ist heller, aber nicht heller ... für mich bedeutet heller näher an Weiß, wie Pink ist. Und Helligkeit ist, wie viel es hat, und es ist voll rot, so rot, ist voll hell. Daher #FF0000kann nicht heller gemacht werden .. aber eher .. leichter ... vielleicht bin ich nur ein Freak, lol !! Ich kenne die Farbtheorie wirklich nicht, sooo, ich spreche wirklich nur meine ...
Pimp Trizkit

Aber ich weiß, dass die Rottöne nicht rosa werden, wenn ich die Helligkeit auf meinem Monitor ändere ... für mich. Hier habe ich wahrscheinlich meine Logik begonnen.
Pimp Trizkit

1

Mit der folgenden Methode können Sie den Belichtungswert einer hexadezimalen (Hex) Farbzeichenfolge aufhellen oder abdunkeln:

private static string GetHexFromRGB(byte r, byte g, byte b, double exposure)
{
    exposure = Math.Max(Math.Min(exposure, 1.0), -1.0);
    if (exposure >= 0)
    {
        return "#"
            + ((byte)(r + ((byte.MaxValue - r) * exposure))).ToString("X2")
            + ((byte)(g + ((byte.MaxValue - g) * exposure))).ToString("X2")
            + ((byte)(b + ((byte.MaxValue - b) * exposure))).ToString("X2");
    }
    else
    {
        return "#"
            + ((byte)(r + (r * exposure))).ToString("X2")
            + ((byte)(g + (g * exposure))).ToString("X2")
            + ((byte)(b + (b * exposure))).ToString("X2");
    }

}

Übergeben Sie für den letzten Parameterwert in GetHexFromRGB () einen doppelten Wert zwischen -1 und 1 (-1 ist schwarz, 0 ist unverändert, 1 ist weiß):

// split color (#e04006) into three strings
var r = Convert.ToByte("e0", 16);
var g = Convert.ToByte("40", 16);
var b = Convert.ToByte("06", 16);

GetHexFromRGB(r, g, b, 0.25);  // Lighten by 25%;

0

Wie einfach Schattenfarbe in PHP?

<?php
function shadeColor ($color='#cccccc', $percent=-25) {

  $color = Str_Replace("#",Null,$color);

  $r = Hexdec(Substr($color,0,2));
  $g = Hexdec(Substr($color,2,2));
  $b = Hexdec(Substr($color,4,2));

  $r = (Int)($r*(100+$percent)/100);
  $g = (Int)($g*(100+$percent)/100);
  $b = (Int)($b*(100+$percent)/100);

  $r = Trim(Dechex(($r<255)?$r:255));  
  $g = Trim(Dechex(($g<255)?$g:255));  
  $b = Trim(Dechex(($b<255)?$b:255));

  $r = ((Strlen($r)==1)?"0{$r}":$r);
  $g = ((Strlen($g)==1)?"0{$g}":$g);
  $b = ((Strlen($b)==1)?"0{$b}":$b);

  return (String)("#{$r}{$g}{$b}");
}

echo shadeColor(); // #999999

Dies ist eine PHP-Version von Pablos Antwort. Leider ist es länger und langsamer als die endgültige Lösung und hellt die Farben nicht genau auf. Es verdunkelt sie genau. Test mit reinem Rot (# FF0000), eine Aufhellung von 25% sollte sein (# FF4040). Schauen Sie sich das Ende meiner Antwort für Kevin Ms PHP-Version der endgültigen Lösung v2 an.
Pimp Trizkit

0

Ich habe einen Port der exzellenten xcolor-Bibliothek erstellt, um die jQuery-Abhängigkeit zu entfernen. Es gibt eine Menge Funktionen, darunter das Aufhellen und Abdunkeln von Farben.

Die Konvertierung von Hex in RGB ist eine völlig andere Funktion als das Aufhellen oder Abdunkeln von Farben. Halten Sie die Dinge bitte trocken. Sobald Sie eine RGB-Farbe haben, können Sie in jedem Fall einfach die Differenz zwischen der gewünschten Lichtstärke und der Lichtstärke zu jedem der RGB-Werte hinzufügen:

var lightness = function(level) {
    if(level === undefined) {
        return Math.max(this.g,this.r,this.b)
    } else {
        var roundedLevel = Math.round(level) // fractions won't work here
        var levelChange = roundedLevel - this.lightness()

        var r = Math.max(0,this.r+levelChange)
        var g = Math.max(0,this.g+levelChange)
        var b = Math.max(0,this.b+levelChange)

        if(r > 0xff) r = 0xff
        if(g > 0xff) g = 0xff
        if(b > 0xff) b = 0xff

        return xolor({r: r, g: g, b: b})
    }
}

var lighter = function(amount) {
    return this.lightness(this.lightness()+amount)
}

Weitere Informationen zur Quelle finden Sie unter https://github.com/fresheneesz/xolor .


Ich habe den Code noch nicht analysiert, da er sich auf mein OP bezieht (Geschwindigkeit / Größe / Genauigkeit). Beim ersten Lesen sind jedoch einige Anmerkungen zu machen: 1) Ich stimme zu, dass die Konvertierung von Hex in RGB als völlig separate Funktion angesehen werden kann. WENN mein Problem mit einer Trockenfunktion gelöst werden sollte, was nicht erforderlich war. Die Absicht hier war, eine Antwort (siehe meine Version 2) zu haben, die superschnell und super winzig war (2 Zeilen!) Und eine, die eine hexadezimale Farbe aufhellte und abdunkelte ... speziell ... als eigenständige eigenständige Funktion. Damit es sich in seiner endgültigen Verwendung um einen einfachen Einzelfunktionsaufruf handelt. <Forts.>
Pimp Trizkit

2) Und der Fall mit Version 3 ist auf vielfachen Wunsch die Absicht, eine völlig eigenständige universelle Funktion zu haben, die so schnell und so klein wie möglich ist und blind eine Hex- oder RGB-Farbe annehmen kann Variationen. Daher ist eine Umwandlung von hex in RGB erforderlich. <Forts.>
Pimp Trizkit

3) Nach einfacher Analyse des Codes. Es scheint, dass es viel langsamer laufen würde und es ist offensichtlich viel größer als meine Version 2 (was die wahre Antwort auf mein OP ist; Version 3 war für die Massen). Um fair zu sein, sollte ich diesen Code mit meiner RGB-Version 2 vergleichen, die keine Konvertierung durchführt und Ihren Standpunkt zur Trockenheit zu beantworten scheint. Und ehrlich gesagt ist Ihr Port nicht viel einfacher zu verstehen als mein 2-Liner für Hex. Also, während es trockener ist, ist es nicht wirklich so viel, wenn überhaupt, einfacher. (Die Trockenheit half nicht viel für das Verständnis) <Forts.>
Pimp Trizkit

4) Mein RGB Version 2 ist eine 2-Zeilen-Funktion ohne Konvertierung, wenn Sie das möchten. Meine spezielle Lösung für mein ursprüngliches OP wollte hex. Aus diesem Grund gibt es zwei verschiedene Arten von Version 2. Sie erwähnen jedoch den Punkt Trockenheit und Hex-Konvertierungen, sodass wir uns jetzt wirklich auf Version 3 konzentrieren. Version 3 kam viel später. erst nach Version 2 war beliebt. <Forts.>
Pimp Trizkit

5) Ich stimme zwar zu, dass Trockenheit im Allgemeinen zur Universalität beiträgt. Und in den meisten Fällen zum Verständnis. Leider kostet es in diesem Beispiel etwas. Diese Kosten sind, dass es viel größer und scheinbar viel langsamer ist und scheinbar mehr Speicher sowohl auf dem Stapel (mit seiner rekursiven Natur) als auch global (2 Funktionen; im Vergleich zu v2) verbraucht.
Pimp Trizkit

0

Ich wollte schon lange Farbtöne erzeugen können. Hier ist meine JavaScript-Lösung:

const varyHue = function (hueIn, pcIn) {
    const truncate = function (valIn) {
        if (valIn > 255) {
            valIn = 255;
        } else if (valIn < 0)  {
            valIn = 0;
        }
        return valIn;
    };

    let red   = parseInt(hueIn.substring(0, 2), 16);
    let green = parseInt(hueIn.substring(2, 4), 16);
    let blue  = parseInt(hueIn.substring(4, 6), 16);
    let pc    = parseInt(pcIn, 10);    //shade positive, tint negative
    let max   = 0;
    let dif   = 0;

    max = red;

    if (pc < 0) {    //tint: make lighter
        if (green < max) {
            max = green;
        }

        if (blue < max) {
            max = blue;
        }

        dif = parseInt(((Math.abs(pc) / 100) * (255 - max)), 10);

        return leftPad(((truncate(red + dif)).toString(16)), '0', 2)  + leftPad(((truncate(green + dif)).toString(16)), '0', 2) + leftPad(((truncate(blue + dif)).toString(16)), '0', 2);
    } else {    //shade: make darker
        if (green > max) {
            max = green;
        }

        if (blue > max) {
            max = blue;
        }

        dif = parseInt(((pc / 100) * max), 10);

        return leftPad(((truncate(red - dif)).toString(16)), '0', 2)  + leftPad(((truncate(green - dif)).toString(16)), '0', 2) + leftPad(((truncate(blue - dif)).toString(16)), '0', 2);
    }
};

Einige Anwendungsbeispiele würden helfen. Und vielleicht eine Erklärung, warum diese Version die anderen übertrifft. Diese Version scheint erheblich langsamer zu laufen. Und es ist viel länger. Und es scheint nicht genau zu schattieren. Es sieht so aus, als würden Sie LERP oder ähnliches verwenden. Das ist gut. Leider ist es nur von einem Kanal, dann wird der gleiche Wert für alle Kanäle verwendet. Dies ist nicht richtig. Um eine höhere Genauigkeit zu erzielen, sollten Sie jeden Kanal einzeln LERPEN. Wie meine Antwort auf diese Frage. Plus es ist kleiner und schneller und prüft auf Fehler und behandelt RGB und macht Konvertierungen, ich könnte weitermachen
Pimp Trizkit

Ein Verwendungsbeispiel: variHue ("6e124c", 77), wobei das erste Argument die Farbe in Hex und das zweite die prozentuale Änderung ist. Eine positive prozentuale Änderung schattiert (verdunkelt), während ein negativer Wert das Ergebnis färbt (aufhellt). Ich schrieb die Routine als meinen ersten Versuch, nur wenige Stunden bevor ich auf diese Seite stieß und sie einfach aus Interesse veröffentlichte. Mir war nicht bewusst, dass ich Ihre Bemühungen verbessern musste oder dass ich Ihre Zustimmung benötigte, bevor ich dies tat. Es ist ganz meine eigene Arbeit ohne Bezug zu irgendjemand anderem. Ich habe noch nichts von LERP gehört. Ich werde es überprüfen, danke für den Vorschlag.
user2655360

Hehe, natürlich musst du nichts tun! Und wir alle danken Ihnen für Ihre Bemühungen! Meine ersten Hauptanliegen waren die zuerst aufgeführten. Ich versuche dir bei deiner Antwort zu helfen, damit sie Stimmen bekommt. (Zeigen Sie die Verwendung und erklären Sie, wie es funktioniert usw.) Das andere Zeug ist offensichtlich eine schnelle Analyse, um das Wissen aller zu fördern. Entschuldigung, wenn es ein bisschen aggressiv schien. Ein weiterer Vorschlag ist, die #Hex-Farben zu akzeptieren . Entschuldigung, wenn es so aussah ... "Zustimmung" ... Ich sah es als Peer Review. Wenn Sie nicht möchten, dass jemand Ihren Code analysiert oder Feedback gibt, entschuldige ich mich.
Pimp Trizkit

0

Ihr Ansatz ist in Ordnung :) Ich vereinfache Ihre kürzeste Version ein wenig (zur Sättigungskontrolle siehe hier )

(col,amt)=> (+('0x'+col)+amt*0x010101).toString(16).padStart(6,0)

Und Version mit # und Farbbereichsprüfung


0

Ich habe auch ein einfaches Paket gemacht. Ich habe die Konvexität von IR ^ 3 verwendet, natürlich sind die RGB-Werte in IN ^ 3, was nicht konvex ist, also ist dies nicht wirklich perfekt

Zum Abdunkeln habe ich folgendes verwendet

for (let i = 0; i < rgb.length; i++) {
   rgb[i] = Math.floor(rgb[i] - ratio * rgb[i]);
}

Und zu erleichtern

for (let i = 0; i < rgb.length; i++) {
   rgb[i] = Math.ceil(rgb[i] + ratio * (255 - rgb[i]));
}

Hier ist das Paket https://github.com/MarchWorks/colortone

Demo https://colortone.now.sh/

Mit der Art und Weise, wie ich Dinge tue, wenn Sie ein Verhältnis von -1 übergeben, erhalten Sie Schwarz, Weiß, wenn das Verhältnis 1 ist. Wenn Sie 0 als Verhältnis übergeben, ändert sich die Farbe nicht


0

Ich brauchte es in C #, es kann .net-Entwicklern helfen

public static string LightenDarkenColor(string color, int amount)
    {
        int colorHex = int.Parse(color, System.Globalization.NumberStyles.HexNumber);
        string output = (((colorHex & 0x0000FF) + amount) | ((((colorHex >> 0x8) & 0x00FF) + amount) << 0x8) | (((colorHex >> 0xF) + amount) << 0xF)).ToString("x6");
        return output;
    }

Sie haben die Funktion "nicht funktioniert" konvertiert, die sich nicht mit führenden Nullen befasst und in den Summen über FF hinausgehen kann. = Ändern Sie die Farbkomponente über ...
B. Gehen Sie

Als ich die Funktion ausprobierte, funktionierte sie wegen nicht hexadezimaler Werte (16 = 0xF) und (8 = 0x8) nicht und gab eine Farbe in 8 Positionen an, aber jetzt funktioniert sie sehr gut
Nassim

Hast du versucht, von FF zu steigen? (z. B. von 0xFFFFFF + 0x000004): Ihr Code überschreitet diesen Maximalwert (z. B. 0x1000003), anstatt ihn nicht zu erhöhen, und setzt insbesondere die beiden oberen Farbkomponenten auf 00, was die größte Änderung darstellt, die sie vornehmen könnten ...
B. Gehen Sie

Sie haben Recht, danke für die Bemerkung, außer einer Eingabe von Grenzwerten um fff und 000 wird es gut funktionieren.
Nassim
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.