javascript - poner - tabla de codigo de colores
Aclarar o oscurecer programáticamente un color hexadecimal(o rgb y combinar colores) (11)
¿Has pensado en una conversión rgb> hsl? entonces solo mueve la luminosidad hacia arriba y hacia abajo? esa es la forma en que me gustaría ir
Un vistazo rápido a algunos algoritmos me dio los siguientes sitios.
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
EDITAR el enlace anterior ya no es válido. Puede ver git hub para la fuente de la página o la gist
Alternativamente, otra question StackOverflow puede ser un buen lugar para mirar.
Aunque esta no es la elección correcta para el OP, la siguiente es una aproximación del código que sugerí originalmente. (Suponiendo que tiene funciones de conversión rgb / hsl)
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;
}
Esto asume:
- Tiene las funciones
hslToRgb
yrgbToHsl
. - El parámetro
colorValue
es una cadena con el formato #RRGGBB
Aunque si estamos hablando de css, hay una sintaxis para especificar hsl/hsla para IE9 / Chrome / Firefox.
Aquí hay una función en la que estaba trabajando para aclarar u oscurecer programáticamente un color hexadecimal en una cantidad específica. Simplemente pase una cadena como "3F6D2A"
para el color ( col
) y un entero base10 ( amt
) para la cantidad a aclarar u oscurecer. Para oscurecer, pase un número negativo (es decir, -20).
La razón por la que hice esto fue porque todas las soluciones que encontré, hasta ahora, parecían complicar el problema en exceso. Y tuve la sensación de que podría hacerse con solo un par de líneas de código. Por favor, avíseme si encuentra algún problema, o tiene algún ajuste para hacer que eso lo acelere.
function LightenDarkenColor(col,amt) {
col = parseInt(col,16);
return (((col & 0x0000FF) + amt) | ((((col>> 8) & 0x00FF) + amt) << 8) | (((col >> 16) + amt) << 16)).toString(16);
}
Para el uso de Desarrollo aquí es una versión más fácil de leer:
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);
}
Y, finalmente, una versión para manejar colores que pueden (o no) tener el "#" al principio. Además de ajustar los valores de color incorrectos:
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);
}
Bien, ahora no es solo un par de líneas, pero parece mucho más simple y si no está utilizando el "#" y no necesita verificar los colores fuera del rango, es solo un par de líneas.
Si no usa el "#", puede agregarlo en un código como:
var myColor = "3F6D2A";
myColor = LightenDarkenColor(myColor,10);
thePlaceTheColorIsUsed = ("#" + myColor);
Supongo que mi pregunta principal es, ¿estoy en lo cierto aquí? ¿Esto no abarca algunas situaciones (normales)?
El siguiente método le permitirá aclarar u oscurecer el valor de exposición de una cadena de color hexadecimal (hexadecimal):
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");
}
}
Para el último valor de parámetro en GetHexFromRGB (), pase un valor doble entre -1 y 1 (-1 es negro, 0 no cambia, 1 es blanco):
// 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%;
Esto es lo que usé basado en su función. Prefiero usar pasos sobre porcentaje porque es más intuitivo para mí.
Por ejemplo, el 20% de un valor de 200 azul es muy diferente al 20% de un valor de 40 azul.
De todos modos, aquí está mi modificación, gracias por su función original.
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;
}
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 Aligerar:
shadeColor("#63C6FF",40);
Ejemplo Oscurecer:
shadeColor("#63C6FF",-40);
Probé su función y hubo un pequeño error: si algún valor ''r'' final es solo de 1 dígito, el resultado aparece como: ''a0a0a'' cuando el valor correcto es ''0a0a0a'', por ejemplo. Solo lo arreglé rápidamente agregando esto en lugar de tu devolución:
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;
Tal vez no sea tan bonito pero hace el trabajo. Gran función, por cierto. Justo lo que necesitaba. :)
¿Cómo simple color de sombra en 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
TL; DR? - ¿Desea aclarar / oscurecer (sombrear)? Salta a la versión 2, elige la de RGB o Hex. - ¿Quieres un shader / blender / conversor con todas las funciones con errorcheck y alpha y hex de 3 dígitos? Use la versión 3 cerca de la parte inferior.
Juega con la versión 3.1: jsfiddle> shadeBlendConvert Example
Versión 3.1 en GitHub: Ir a GitHub> PJs> pSBC
Después de reflexionar un poco ... decidí responder mi propia pregunta. Un año y medio después. Esta fue verdaderamente una aventura con ideas de varios usuarios útiles, ¡y les agradezco a todos! ¡Este es para el equipo! Si bien no es necesariamente la respuesta que estaba buscando. Porque si lo que James Khoury está diciendo es verdad, entonces no hay matemáticas hexadecimales verdaderas en JavaScript, tengo que usar decimales, esta doble conversión es necesaria. Si hacemos esta suposición, entonces esta es probablemente la manera más rápida que he visto (o se me ocurre) de aclarar (agregar blanco) u oscurecer (agregar negro) un color RBG arbitrario por porcentaje. También da cuenta de los problemas que Cool Acid mencionó en su respuesta a esta pregunta (rellena 0s). Pero esta versión llama toString
solo una vez. Esto también representa fuera de rango (aplicará 0 y 255 como límites).
Pero cuidado, la entrada de color tiene que ser EXACTAMENTE 7 caracteres, como #08a35c
. (o 6 si usa la versión superior)
Gracias a Pablo por la inspiración y la idea de usar el porcentaje. Para esto mantendré el nombre de la función igual! jajaja Sin embargo, este es diferente, ya que normaliza el porcentaje a 255 y, por lo tanto, agrega la misma cantidad a cada color (más blanco). Si pasas 100 por percent
, hará que tu color sea blanco puro. Si pasas 0 por percent
, no pasará nada. Si pasa 1 por percent
, agregará 3 tonos a todos los colores (2,55 tonos por 1%, redondeado). Así que realmente estás pasando en un porcentaje de blanco (o negro, usa negativo). Por lo tanto, esta versión le permite aligerar el rojo puro (FF0000), por ejemplo.
También utilicé la información de la respuesta de Keith Mashinter a esta pregunta: ¿Cómo convertir un decimal a hexadecimal en JavaScript?
Quité algunos, aparentemente, paréntesis innecesarios. (como en la declaración doble ternaria y en la elaboración de G) No estoy seguro de si esto va a interferir con la prioridad del operador en algunos entornos. Probado bien en FireFox.
function shadeColor1(color, percent) { // deprecated. See below.
var num = parseInt(color,16),
amt = Math.round(2.55 * percent),
R = (num >> 16) + amt,
G = (num >> 8 & 0x00FF) + amt,
B = (num & 0x0000FF) + amt;
return (0x1000000 + (R<255?R<1?0:R:255)*0x10000 + (G<255?G<1?0:G:255)*0x100 + (B<255?B<1?0:B:255)).toString(16).slice(1);
}
O, si quieres que maneje el "#":
function shadeColor1(color, percent) { // deprecated. See below.
var num = parseInt(color.slice(1),16), amt = Math.round(2.55 * percent), R = (num >> 16) + amt, G = (num >> 8 & 0x00FF) + amt, B = (num & 0x0000FF) + amt;
return "#" + (0x1000000 + (R<255?R<1?0:R:255)*0x10000 + (G<255?G<1?0:G:255)*0x100 + (B<255?B<1?0:B:255)).toString(16).slice(1);
}
¿Cómo es que para dos líneas de código?
EDIT: Fix B <-> G swap goof. Gracias svachalek!
- ACTUALIZACIÓN - Versión 2 con Blending - Un poco más de un año después, otra vez, y todavía está en marcha. Pero esta vez creo que está hecho. Tomando nota de los problemas mencionados acerca de no usar HSL para aclarar adecuadamente el color. Existe una técnica que elimina la mayor parte de esa inexactitud sin tener que convertir a HSL. El principal problema es que un canal de color se saturará completamente antes que el resto del color. Causando un cambio en el tono después de ese punto. Encontré estas preguntas here , here y here que me pusieron en marcha. La publicación de Mark Ransom me mostró la diferencia, y here me mostró el camino. Lerp es el salvador. Es lo mismo que combinar colores, así que también creé una función blendColors
.
TL; DR : para aclarar / oscurecer de manera simple, use esta función shadeColor2
continuación. O su contraparte RGB shadeRGBColor
más abajo, y dame un voto. Pero, si quieres alguna y / o todas las golosinas. Como la capacidad de usar colores RGB y Hex, Comprobación de errores, Decodificación hexadecimal de 3 dígitos, Mezcla, Canales alfa y Conversiones RGB2Hex / Hex2RGB. Luego, pase a la Versión 3 para shadeBlendConvert
para obtener todas las campanas y silbidos y darme dos votos. Luego puede eliminar algunas líneas para eliminar algunas de estas funciones, si lo desea. Y obtienes un voto si recuerdas que la versión 1 shadeColor1
anterior está obsoleta para todos los usos.
Así que sin más preámbulos:
-Versión 2 Hex.
function shadeColor2(color, percent) {
var f=parseInt(color.slice(1),16),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=f>>16,G=f>>8&0x00FF,B=f&0x0000FF;
return "#"+(0x1000000+(Math.round((t-R)*p)+R)*0x10000+(Math.round((t-G)*p)+G)*0x100+(Math.round((t-B)*p)+B)).toString(16).slice(1);
}
function blendColors(c0, c1, p) {
var f=parseInt(c0.slice(1),16),t=parseInt(c1.slice(1),16),R1=f>>16,G1=f>>8&0x00FF,B1=f&0x0000FF,R2=t>>16,G2=t>>8&0x00FF,B2=t&0x0000FF;
return "#"+(0x1000000+(Math.round((R2-R1)*p)+R1)*0x10000+(Math.round((G2-G1)*p)+G1)*0x100+(Math.round((B2-B1)*p)+B1)).toString(16).slice(1);
}
Más preámbulos:
No hay comprobación de errores, por lo que los valores que se pasan y están fuera de rango causarán resultados inesperados. Además, la entrada de color tiene que ser EXACTAMENTE 7 caracteres, como #08a35c
. Pero todas las demás novedades aún están aquí como el límite del rango de salida (salidas 00-FF), el relleno (0A), los mangos #
y se pueden utilizar en colores sólidos, como #FF0000
.
Esta nueva versión de shadeColor incorpora un flotador para su segundo parámetro. Para shadeColor2
el rango válido para el segundo parámetro (porcentaje) es -1.0
a 1.0
.
Y para blendColors
el rango válido para el tercer parámetro (porcentaje) es de 0.0
a 1.0
, los negativos no se permiten aquí.
Esta nueva versión ya no admite un porcentaje de blanco puro, como la versión anterior. Su toma en un porcentaje de la DISTANCIA del color dado al blanco puro. En la versión anterior, era fácil saturar el color y, como resultado, muchos colores se computaban a blanco puro cuando se usaba un porcentaje considerable. Esta nueva forma, solo se calcula a blanco puro si pasas 1.0
, o negro puro, usa -1.0
.
Llamar a blendColors(color, "#FFFFFF", 0.5)
es lo mismo que shadeColor2(color,0.5)
. Además, blendColors(color,"#000000", 0.5)
es el mismo que shadeColor2(color,-0.5)
. Sólo un toque más lento.
shadeColor2
es más lento que shadeColor1
, pero no en una cantidad notable. (Espera, eso es una afirmación auto-contradictoria!)
La precisión obtenida se puede ver aquí:
- Versión 2 RGB -
function shadeRGBColor(color, percent) {
var f=color.split(","),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=parseInt(f[0].slice(4)),G=parseInt(f[1]),B=parseInt(f[2]);
return "rgb("+(Math.round((t-R)*p)+R)+","+(Math.round((t-G)*p)+G)+","+(Math.round((t-B)*p)+B)+")";
}
function blendRGBColors(c0, c1, p) {
var f=c0.split(","),t=c1.split(","),R=parseInt(f[0].slice(4)),G=parseInt(f[1]),B=parseInt(f[2]);
return "rgb("+(Math.round((parseInt(t[0].slice(4))-R)*p)+R)+","+(Math.round((parseInt(t[1])-G)*p)+G)+","+(Math.round((parseInt(t[2])-B)*p)+B)+")";
}
Usos:
var color1 = "rbg(63,131,163)";
var lighterColor = shadeRGBColor(color1, 0.5); // rgb(159,193,209)
var darkerColor = shadeRGBColor(color1, -0.25); // rgb(47,98,122)
var color2 = "rbg(244,128,0)";
var blend1 = blendRGBColors(color1, color2, 0.75); // rgb(199,129,41)
var blend2 = blendRGBColors(color2, color1, 0.62); // rgb(132,130,101)
- Versión 2 Universal A -
function shade(color, percent){
if (color.length > 7 ) return shadeRGBColor(color,percent);
else return shadeColor2(color,percent);
}
function blend(color1, color2, percent){
if (color1.length > 7) return blendRGBColors(color1,color2,percent);
else return blendColors(color1,color2,percent);
}
Uso:
var color1 = shade("rbg(63,131,163)", 0.5);
var color2 = shade("#3f83a3", 0.5);
var color3 = blend("rbg(63,131,163)", "rbg(244,128,0)", 0.5);
var color4 = blend("#3f83a3", "#f48000", 0.5);
- Versión 2 Universal B -
¡Está bien! La popularidad de esta respuesta me hizo pensar que podría hacer una versión universal mucho mejor de esto. Así que aquí tienes! Esta versión es una función todo en uno que puede copiar / pegar y sombrear / mezclar para colores RGB y Hex. Esta no es realmente diferente a la otra versión de Uni proporcionada anteriormente. Excepto que es mucho más pequeño y solo una función para pegar y usar. Creo que el tamaño pasó de aproximadamente 1,592 caracteres a 557 caracteres, si se comprime en una línea. Por supuesto, si no necesita usarlo indistintamente entre RGB y Hex, entonces no necesita una versión Universal como esta, lol. Solo usa una de las versiones mucho más pequeñas y rápidas de arriba; apropiado para su esquema de color. Continuando ... De alguna manera es un poco más rápido, de alguna manera es un poco más lento. No hice ningún análisis final de prueba de velocidad. Hay dos diferencias de uso: Primero, el porcentaje es ahora el primer parámetro de la función, en lugar del último. Segundo, al combinar, puedes usar números negativos. Simplemente se convertirán a números positivos.
No más preámbulos:
function shadeBlend(p,c0,c1) {
var n=p<0?p*-1:p,u=Math.round,w=parseInt;
if(c0.length>7){
var f=c0.split(","),t=(c1?c1:p<0?"rgb(0,0,0)":"rgb(255,255,255)").split(","),R=w(f[0].slice(4)),G=w(f[1]),B=w(f[2]);
return "rgb("+(u((w(t[0].slice(4))-R)*n)+R)+","+(u((w(t[1])-G)*n)+G)+","+(u((w(t[2])-B)*n)+B)+")"
}else{
var f=w(c0.slice(1),16),t=w((c1?c1:p<0?"#000000":"#FFFFFF").slice(1),16),R1=f>>16,G1=f>>8&0x00FF,B1=f&0x0000FF;
return "#"+(0x1000000+(u(((t>>16)-R1)*n)+R1)*0x10000+(u(((t>>8&0x00FF)-G1)*n)+G1)*0x100+(u(((t&0x0000FF)-B1)*n)+B1)).toString(16).slice(1)
}
}
Uso:
var color1 = "#FF343B";
var color2 = "#343BFF";
var color3 = "rgb(234,47,120)";
var color4 = "rgb(120,99,248)";
var shadedcolor1 = shadeBlend(0.75,color1);
var shadedcolor3 = shadeBlend(-0.5,color3);
var blendedcolor1 = shadeBlend(0.333,color1,color2);
var blendedcolor34 = shadeBlend(-0.8,color3,color4); // Same as using 0.8
¡Ahora podría ser perfecto! ;) @ Mevin
* V2 OTROS IDIOMAS *
- Swift Extension - RGB (por Matej Ukmar) -
extension UIColor {
func shadeColor(factor: CGFloat) -> UIColor {
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
var t: CGFloat = factor < 0 ? 0 : 1
var p: CGFloat = factor < 0 ? -factor : factor
getRed(&r, green: &g, blue: &b, alpha: &a)
r = (t-r)*p+r
g = (t-g)*p+g
b = (t-b)*p+b
return UIColor(red: r, green: g, blue: b, alpha: a)
}
}
- Versión PHP - HEX (por Kevin M) -
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);
}
- ACTUALIZACIÓN - Versión 3.1 Universal -
(Esto ha sido añadido a mi biblioteca en GitHub )
En un par de meses habrá pasado un año más desde la última versión universal. Así que ... gracias al comentario perspicaz sricks''s . He decidido llevarlo al siguiente nivel, de nuevo. Ya no es el demonio de velocidad de dos líneas como había empezado, jajaja. Pero, por lo que hace, es bastante rápido y pequeño. Sus alrededor de 1600 bytes. Si elimina ErrorChecking y elimina la decodificación de 3 dígitos, puede obtener hasta 1200 bytes y es más rápido. Esto es un montón de poder en aproximadamente una K. ¡Imagínate, podrías cargarlo en un Commodore64 y aún tener espacio para 50 más! (Sin tener en cuenta el hecho de que el motor de JavaScript es más grande que 63k)
Aparentemente había más ganas de hacer:
const shadeBlendConvert = function (p, from, to) {
if(typeof(p)!="number"||p<-1||p>1||typeof(from)!="string"||(from[0]!=''r''&&from[0]!=''#'')||(to&&typeof(to)!="string"))return null; //ErrorCheck
if(!this.sbcRip)this.sbcRip=(d)=>{
let l=d.length,RGB={};
if(l>9){
d=d.split(",");
if(d.length<3||d.length>4)return null;//ErrorCheck
RGB[0]=i(d[0].split("(")[1]),RGB[1]=i(d[1]),RGB[2]=i(d[2]),RGB[3]=d[3]?parseFloat(d[3]):-1;
}else{
if(l==8||l==6||l<4)return null; //ErrorCheck
if(l<6)d="#"+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]+(l>4?d[4]+""+d[4]:""); //3 or 4 digit
d=i(d.slice(1),16),RGB[0]=d>>16&255,RGB[1]=d>>8&255,RGB[2]=d&255,RGB[3]=-1;
if(l==9||l==5)RGB[3]=r((RGB[2]/255)*10000)/10000,RGB[2]=RGB[1],RGB[1]=RGB[0],RGB[0]=d>>24&255;
}
return RGB;}
var i=parseInt,r=Math.round,h=from.length>9,h=typeof(to)=="string"?to.length>9?true:to=="c"?!h:false:h,b=p<0,p=b?p*-1:p,to=to&&to!="c"?to:b?"#000000":"#FFFFFF",f=this.sbcRip(from),t=this.sbcRip(to);
if(!f||!t)return null; //ErrorCheck
if(h)return "rgb"+(f[3]>-1||t[3]>-1?"a(":"(")+r((t[0]-f[0])*p+f[0])+","+r((t[1]-f[1])*p+f[1])+","+r((t[2]-f[2])*p+f[2])+(f[3]<0&&t[3]<0?")":","+(f[3]>-1&&t[3]>-1?r(((t[3]-f[3])*p+f[3])*10000)/10000:t[3]<0?f[3]:t[3])+")");
else return "#"+(0x100000000+r((t[0]-f[0])*p+f[0])*0x1000000+r((t[1]-f[1])*p+f[1])*0x10000+r((t[2]-f[2])*p+f[2])*0x100+(f[3]>-1&&t[3]>-1?r(((t[3]-f[3])*p+f[3])*255):t[3]>-1?r(t[3]*255):f[3]>-1?r(f[3]*255):255)).toString(16).slice(1,f[3]>-1||t[3]>-1?undefined:-2);
}
Juega con la versión 3.1: jsfiddle> shadeBlendConvert Example
La matemática central de esta versión es la misma que antes. Pero, hice algunas refactorizaciones importantes. Esto ha permitido una mayor funcionalidad y control. Ahora convierte inherentemente RGB2Hex y Hex2RGB.
Todas las características antiguas de la v2 anterior aún deberían estar aquí. He intentado probarlo todo, por favor, publique un comentario si encuentra algo incorrecto. De todos modos, aquí están las nuevas características:
- Acepta códigos de color HEX de 3 dígitos (o 4 dígitos), en la forma #RGB (o #ARGB). Los ampliará. Elimine la línea marcada con
//3 digit
para eliminar esta función. - Acepta y mezcla canales alfa. Si el color
from
o el color tiene un canal alfa, el resultado tendrá un canal alfa. Si ambos colores tienen un canal alfa, el resultado será una combinación de los dos canales alfa utilizando 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 se pasará al resultado. Esto permite mezclar / sombrear un color transparente mientras se mantiene el nivel transparente. O bien, si el nivel transparente también se mezcla, asegúrese de que ambos colores tengan alfas. El sombreado pasará a través del canal alfa, si desea un sombreado básico que también combine el canal alfa, usergb(0,0,0,1)
orgb(255,255,255,1)
como colorto
su color (o sus equivalentes hexadecimales). Para los colores RGB, el canal alfa resultante se redondeará a 4 decimales. - Las conversiones RGB2Hex y Hex2RGB ahora están implícitas cuando se usa la mezcla. El color resultante siempre estará en la forma de colorear, si existe. Si no hay color
to
color, pase''c''
como el color para que se sombree y se convierta. Si solo se desea la conversión, entonces pase0
como porcentaje también. - También se agrega una función secundaria al global.
sbcRip
se le puede pasar un color hexadecimal o rbg y devuelve un objeto que contiene esta información de color. Está en la forma:{0:R,1:G,2:B,3:A}
. Donde R G y B tienen rango de0
a255
. Y cuando no hay alfa: A es-1
. De lo contrario: A tiene un rango de0.0000
a1.0000
. - Se ha añadido la comprobación de errores menores. No es perfecto Todavía puede estrellarse. Pero atrapará algunas cosas. Básicamente, si la estructura es errónea de alguna manera o si el porcentaje no es un número o está fuera de alcance, devolverá el
null
. Un ejemplo:shadeBlendConvert(0.5,"salt") = null
, donde, como cree,#salt
es un color válido. Elimine las cuatro líneas marcadas con//ErrorCheck
para eliminar esta función.
Usos:
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)";
let c;
// Shade (Lighten or Darken)
c = shadeBlendConvert ( 0.42, color1 ); // rgb(20,60,200) + [42% Lighter] => rgb(119,142,223)
c = shadeBlendConvert ( -0.4, color5 ); // #F3A + [40% Darker] => #991f66
c = shadeBlendConvert ( 0.42, color8 ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(223,142,119,0.98631)
// Shade with Conversion (use "c" as your "to" color)
c = shadeBlendConvert ( 0.42, color2, "c" ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #778edfac
// RGB2Hex & Hex2RGB Conversion Only (set percentage to zero)
c = shadeBlendConvert ( 0, color6, "c" ); // #F3A9 + [Convert] => rgba(255,51,170,0.6)
// Blending
c = shadeBlendConvert ( -0.5, color2, color8 ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(110,60,110,0.8303)
c = shadeBlendConvert ( 0.7, color2, color7 ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(146,60,74,0.67423)
c = shadeBlendConvert ( 0.25, color3, color7 ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(127,179,185)
c = shadeBlendConvert ( 0.75, color7, color3 ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #7fb3b9
// Error Checking
c = shadeBlendConvert ( 0.42, "#FFBAA" ); // #FFBAA + [42% Lighter] => null (Invalid Input Color)
c = shadeBlendConvert ( 42, color1, color5 ); // rgb(20,60,200) + #F3A + [4200% Blend] => null (Invalid Percentage Range)
c = shadeBlendConvert ( 0.42, {} ); // [object Object] + [42% Lighter] => null (Strings Only for Color)
c = shadeBlendConvert ( "42", color1 ); // rgb(20,60,200) + ["42"] => null (Numbers Only for Percentage)
c = shadeBlendConvert ( 0.42, "salt" ); // salt + [42% Lighter] => null (A Little Salt is No Good...)
// Error Check Fails (Some Errors are not Caught)
c = shadeBlendConvert ( 0.42, "#salt" ); // #salt + [42% Lighter] => #6b6b6b00 (...and a Pound of Salt is Jibberish)
// Ripping
c = sbcRip ( color4 ); // #5567DAF0 + [Rip] => [object Object] => {''0'':85,''1'':103,''2'':218,''3'':0.9412}
Ahora dudo en terminar esto ... otra vez ...
PT
--EDIT: Cambió la versión 3 para usar let
, y una función de flecha, y lo agregó a sbcRip
llamadas sbcRip
.
---- === <| EDICIÓN PRINCIPAL (3/9/18) |> === ----
¡Estoy tan avergonzada! (y sorprendido de que nadie haya mencionado esto) Aparentemente no uso canales alfa en mis propios proyectos ... Y ... aparentemente hice pruebas terribles. La versión 3 no leyó ni escribió colores con canales alfa correctamente. Hubo algunos puntos que, o bien tuve mal o que nunca aprendí:
- Los colores hexadecimales con alfa son #RGBA (no #ARGB). La versión 3 estaba leyendo y escribiendo esto al revés.
- Los colores RGB con alfas deben ser
rgba()
y norgb()
; La versión 3 nunca da salida argba()
. - La versión 3 no aceptaba
rgba()
pero aceptaba alfas enrgb()
, lo que no debería ocurrir.
Acabo de reemplazar la versión 3 con la versión 3.1, donde se tratan estos problemas. No lo publiqué aquí como una función separada; viendo que la antigua versión 3 debería ser eliminada de la existencia y reemplazada con esta. Y eso es lo que hice. La versión 3 anterior es en realidad la versión 3.1.
Todas las características antiguas de arriba todavía están aquí con estas actualizaciones:
- Lee y escribe correctamente los colores con canales alfa. Tanto Hex y RGB.
- El color
to
aceptar ahora acepta un color de cadena o un falsy (que aún puede serundefined
). - La función es ahora constante.
... Me alegro de haber dudado en volver a hacerlo. Aquí estamos, más o menos un año después ... aún perfeccionándolo ...
PT
Hace mucho tiempo que quería poder producir tonos / tonos de colores, aquí está mi solución de JavaScript:
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);
}
};
Versión de C # ... tenga en cuenta que estoy obteniendo cadenas de color en este formato # FF12AE34, y necesito cortar el #FF.
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);
}
Hice un puerto de la excelente biblioteca xcolor para eliminar su dependencia jQuery. Hay una tonelada de funciones que incluyen colores de aclarado y oscurecimiento.
Realmente, convertir hexadecimal a RGB es una función completamente separada de aclarar u oscurecer colores. Mantenga las cosas secas por favor. En cualquier caso, una vez que tenga un color RGB, puede agregar la diferencia entre el nivel de luz que desea y el nivel de luz que tiene a cada uno de los valores RGB:
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)
}
Consulte https://github.com/fresheneesz/xolor para obtener más información sobre la fuente.
Quería cambiar un color a un nivel de brillo específico , sin importar el brillo del color anterior, aquí hay una función JS simple que parece funcionar bien, aunque estoy seguro de que podría ser más corto
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;}