Saltar al contenido

Aclarar u oscurecer programáticamente un color hexadecimal (o rgb, y mezclar colores)

Este team especializado pasados varios días de trabajo y de recopilar de datos, han obtenido la respuesta, esperamos que resulte de utilidad en tu plan.

Solución:

Bueno, esta respuesta se ha convertido en su propia bestia. Muchas versiones nuevas, se estaba volviendo estúpidamente largo. Muchas gracias a todos los grandes colaboradores de esta respuesta. Pero, para que sea sencillo para las masas. Archivé todas las versiones / historial de la evolución de esta respuesta en mi github. Y lo comencé de nuevo en StackOverflow aquí con la versión más reciente. Un agradecimiento especial para Mike ‘Pomax’ Kamermans por esta versión. Me dio las nuevas matemáticas.


Esta función (pSBC) tomará un color web HEX o RGB. pSBC puede sombrearlo más oscuro o más claro, o mezclarlo con un segundo color, y también puede pasarlo directamente pero convertir de Hex a RGB (Hex2RGB) o de RGB a Hex (RGB2Hex). Todo sin que usted sepa siquiera qué formato de color está utilizando.

Esto funciona muy rápido, probablemente el más rápido, especialmente considerando sus muchas características. Fue un largo tiempo de preparación. Vea la historia completa en mi github. Si desea la forma más pequeña y rápida posible de sombrear o difuminar, consulte las Micro Funciones a continuación y use uno de los demonios de velocidad de 2 líneas. Son excelentes para animaciones intensas, pero esta versión aquí es lo suficientemente rápida para la mayoría de las animaciones.

Esta función utiliza Log Blending o Linear Blending. Sin embargo, NO se convierte a HSL para aclarar u oscurecer correctamente un color. Por lo tanto, los resultados de esta función serán diferentes de esas funciones mucho más grandes y mucho más lentas que usan HSL.

jsFiddle con pSBC

github> Wiki pSBC

Características:

  • Detecta automáticamente y acepta colores hexadecimales estándar en forma de cadenas. Por ejemplo: "#AA6622" o "#bb551144".
  • Detecta automáticamente y acepta colores RGB estándar en forma de cadenas. Por ejemplo: "rgb(123,45,76)" o "rgba(45,15,74,0.45)".
  • Sombrea los colores a blanco o negro por porcentaje.
  • Combina colores por porcentaje.
  • Hace conversión Hex2RGB y RGB2Hex al mismo tiempo, o solo.
  • Acepta códigos de color HEX de 3 dígitos (o 4 dígitos con alfa), en la forma #RGB (o #RGBA). Los expandirá. Por ejemplo: "#C41" se convierte en "#CC4411".
  • Acepta y (lineal) combina canales alfa. Si el c0 (de) color o el c1 (a) color tiene un canal alfa, entonces el color devuelto tendrá un canal alfa. Si ambos colores tienen un canal alfa, entonces el color devuelto será una combinación lineal de los dos canales alfa usando el porcentaje dado (como si fuera un canal de color normal). Si solo uno de los dos colores tiene un canal alfa, este alfa solo pasará al color devuelto. Esto permite mezclar / sombrear un color transparente mientras se mantiene el nivel de transparencia. O, si los niveles de transparencia también deben combinarse, asegúrese de que ambos colores tengan alfas. Al sombrear, pasará el canal alfa directamente. Si desea un sombreado básico que también sombree el canal alfa, utilice rgb(0,0,0,1) o rgb(255,255,255,1) como tu c1 (a) color (o sus equivalentes hexadecimales). Para los colores RGB, el canal alfa del color devuelto se redondeará a 3 decimales.
  • Las conversiones RGB2Hex y Hex2RGB están implícitas cuando se usa la combinación. A pesar de c0 (de) color; el color devuelto siempre estará en el formato de color del c1 (a) color, si existe. Si no hay c1 (a) colorear, luego pasar 'c' en como el c1 color y sombreará y convertirá cualquier c0 color es. Si solo desea la conversión, pase 0 en como porcentaje (p) así como. Si el c1 se omite el color o nostring se pasa, no se convertirá.
  • También se agrega una función secundaria a la global. pSBCr se puede pasar un color Hex o RGB y devuelve un objeto que contiene esta información de color. Tiene el formato: r: XXX, g: XXX, b: XXX, a: X.XXX. Dónde .r, .g, y .b tienen un rango de 0 a 255. Y cuando no hay alfa: .a es -1. De lo contrario: .a tiene un rango de 0.000 a 1.000.
  • Para salida RGB, genera rgba() sobre rgb() cuando un color con un canal alfa se pasó a c0 (de) y / o c1 (para).
  • Se ha agregado la comprobación de errores menores. No es perfecto Todavía puede fallar o crear jibberish. Pero atrapará algunas cosas. Básicamente, si la estructura es incorrecta de alguna manera o si el porcentaje no es un número o está fuera de alcance, devolverá null. Un ejemplo: pSBC(0.5,"salt") == null, donde como piensa #salt es un color válido. Borre las cuatro líneas que terminan con return null; para eliminar esta función y hacerla más rápida y más pequeña.
  • Utiliza Log Blending. Aprobar true En para l (el cuarto parámetro) para usar Linear Blending.

Código:

// Version 4.0
const pSBC=(p,c0,c1,l)=>

Uso:

// 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

La siguiente imagen ayudará a mostrar la diferencia entre los dos métodos de mezcla:


Funciones micro

Si realmente desea velocidad y tamaño, tendrá que usar RGB, no HEX. RGB es más sencillo y directo, HEX escribe demasiado lento y viene en demasiados sabores para un simple dos líneas (es decir, podría ser un código HEX de 3, 4, 6 u 8 dígitos). También deberá sacrificar algunas funciones, sin verificación de errores, sin HEX2RGB ni RGB2HEX. Además, deberá elegir una función específica (según el nombre de la función a continuación) para las matemáticas de combinación de colores, y si desea sombrear o mezclar. Estas funciones admiten canales alfa. Y cuando ambos colores de entrada tengan alfa, los combinará linealmente. Si solo uno de los dos colores tiene un alfa, lo pasará directamente al color resultante. A continuación se muestran dos funciones de revestimiento que son increíblemente rápidas y pequeñas:

const RGB_Linear_Blend=(p,c0,c1)=>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

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


¿Quieres más información? Lea el artículo completo en github.

PT

(Ps, si alguien tiene las matemáticas para otro método de combinación, por favor comparta).

Hice una solución que funciona muy bien para mí:

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;

Ejemplo Aclarar:

shadeColor("#63C6FF",40);

Ejemplo Oscurecer:

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

Aquí hay una línea super simple basada en la respuesta de Eric

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

Ejemplos:

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

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *