¿Cómo hacer que un color determinado sea un poco más oscuro o más claro?

9

Tengo esta foto:

colores

Las flechas muestran dos colores diferentes, pero en realidad deberían ser del mismo color pero un poco más claros u oscuros.

Hice esta captura de pantalla de la aplicación que hago y el color parduzco en los bordes es solo el color azul sumado con 30. Como puede ver, no funciona, es decir, agregar 30 al color real no funcionará para todos colores.

colores reales

¿Cómo puedo sombrear un color dado, es decir, hacerlo más brillante o más oscuro?

Además, ¿qué debo hacer si quiero que se vea semitransparente con alfa?

Vlad
fuente
Estoy votando para cerrar esta pregunta como fuera de tema porque debería hacerse en stackoverflow.
joojaa
3
Técnicamente sigue siendo una cuestión de diseño gráfico, ya que discutimos las matemáticas detrás de los colores y los colores de sombreado, produciendo diferentes variantes de colores.
Vlad
1
no, discutimos la conversión hexadecimal. Estaría bien con una pregunta de color, pero lo ha vinculado tan fuertemente con su entorno de cómputo que ya no satisface su reclamo. Por lo tanto, lo ha especificado para que se convierta en una pregunta de JavaScript y marcado de nodos y eso no es diseño gráfico.
joojaa
1
No, la pregunta dice bien, ¿qué debo hacer para que un color sea más oscuro o más brillante? La conversión al valor hexadecimal es una adición útil pero no una necesidad.
Vlad
1
No voy a discutir. No entiendo los colores y cómo funcionan, estaba pidiendo un "cómo", no un código que alguien codificará para mí.
Vlad

Respuestas:

12

Buena pregunta

Para trabajar con valores hexadecimales, debe pensar en términos de proporción relativa de los valores RGB.

Usaré una escala en números, no con letras, para que podamos ver las matemáticas detrás de ella.

Imagina que tienes una naranja.

Puede tener un valor de R255 G128 B0

Si desea un color más oscuro, debe reducir los valores, por ejemplo, al 50%

Esto le dará R128 G64 B0 Observe que todos los colores se modificaron usando una escala proporcional.

Un color más complejo podría ser R255 G200 B100 . Oscurezcamos pero no tanto como en el caso anterior. Solo oscurezcamos un 80%.

R255x0.8 G200x0.8 B100x0.8 = R204 G160 B80

Para hacer que un color sea más claro, la idea es más o menos la misma, pero es más complicado porque los colores tendrán un límite de 255, por lo que puede pensar en la diferencia entre el 255 y sus valores.

Por ejemplo la misma naranja

R255 G128 B0

Ya no puede aumentar R, y no puede aumentar el verde y el azul con los mismos valores, por ejemplo, 100 más, porque tendrá

R255 G228 B100

que es muy amarillo

Las matemáticas serían

1) La diferencia de 255 al valor actual (R255 G128 B0) es: R0 G127 B255

2) Hagamos una naranja más clara en un 50%

3) Rx50% Gx50% Bx50% = R0 G64 B128

4) Agregue eso a su valor inicial: R255 + 0 G128 + 64 B0 + 128 = R255 G192 B128.

Estoy agregando una imagen para darle la idea básica. Los valores RGB no son los mismos de mi texto, solo porque es un trabajo perezoso, pero puede ver que las "escaleras" naranjas conservan sus proporciones intrínsecas.

ingrese la descripción de la imagen aquí

Editado

Soy muy tonto También puede usar la notación de color HSL:

{background-color: hsl (45, 60%, 70%);} y modifica el tercer color para colores más oscuros, y el segundo y el tercero para colores más claros.

También puede usar una variante hsla para incluir alfa.

Rafael
fuente
Por supuesto, si se trata de un navegador, es completamente capaz de calcularlo por usted
joojaa
Sí, una aplicación JS / navegador. Pero Js no reconoce el color formateado # 345464. Yo uso parseInt (hashString.replace ('#', ''), 16); donde hashString es un color con formato CSS como # 345464.
Vlad
Traduces tus números como quieras. Le dije que estaba usando números para que pueda ver las matemáticas detrás de esto. Pero el principio es el mismo. 8 es la mitad de F.
Rafael
Y siempre puede usar la notación rgba (255,128,0,1).
Rafael
Realmente uso el elemento Canvas y es JS puro, sin CSS incluido. Pero tengo una idea de cómo resolver esto con código.
Vlad
2

Has entendido mal las cosas un poco, javaScript no modela el color como hexadecimal, ni el sistema. La notación hexadecimal es solo para el documento legible por humanos. Internamente su sistema almacena tres valores enteros. Puede consultarlos y manipularlos directamente.

Pero digamos que desea manipular el documento real en lugar de los elementos internos del sistema. Entonces es mejor diferir su cálculo a alguna biblioteca que haga esto por usted. Verá que el navegador puede representar colores de muchas maneras, por lo que necesitaría programar todo tipo de casos, como entradas de anuncios rgb y hsv. Por lo tanto, le sugiero que use algo como Color.js, le ahorrará mucho dolor de cabeza, ya que no necesita implementar mezclas, oscurecimientos, aclaraciones, etc. usted mismo.

Edity

En caso de que quiera hacer esto usted mismo, no lo recomiendo. Comience por convertir la representación hexadecimal en tripletes numéricos de enteros o números de coma flotante en el rango 0-1, esto facilita el cálculo.

Ahora, para una fácil manipulación de los valores de conversión de color RGB a HSL o HSB, esto hace que los cálculos de brillo sean triviales (Wikipedia tiene formulaciones). Entonces, simplemente agregue o reste ligereza o brillo. Para la simulación de luz real, el cálculo es bastante fácil, simplemente multiplique el color de la luz por el color base. Por lo tanto, para luz neutral es simplemente:

Resultado = Intensidad * Color

Como explicó Rafael, la fórmula se repite por canal de color. Puedes simular luz de color haciendo

Resultado = Intensidad * LigtColor * Color

Para esto es mejor convertir a flotante primero, quizás también lineal. Esto permite una luz cálida o fría en su área que puede brindar una sensación más natural.

La mezcla alfa (capa de color encima de otra) es simplemente

Resultado = ColorTop * alpha + ColorBottom * (1-alpha)

Edición final

Finalmente, aquí hay un código que hace algo hacia lo que pides. La razón por la que esto es difícil de ver es porque es una especie de resumen en forma en este momento. Código en vivo disponible aquí

ingrese la descripción de la imagen aquí

Imagen 1 : Resultado del código a continuación, vea también la versión en vivo .

{
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    var Color = function(r, g, b) {
      this.r = r;
      this.g = g;
      this.b = b;
    }
    Color.prototype.asHex = function() {
      return "#" + ((1 << 24) + (this.r << 16) + (this.g << 8) + this.b).toString(16).slice(1);
    }
    Color.prototype.asRGB = function() {
      return 'rgb(' + this.r + ',' + this.g + ',' + this.b + ')';
    }
    Color.prototype.blendWith = function(col, a) {
      r = Math.round(col.r * (1 - a) + this.r * a);
      g = Math.round(col.g * (1 - a) + this.g * a);
      b = Math.round(col.b * (1 - a) + this.b * a);
      return new Color(r, g, b);
    }
    Color.prototype.Mul = function(col, a) {
      r = Math.round(col.r/255 * this.r * a);
      g = Math.round(col.g/255 * this.g * a);
      b = Math.round(col.b/255 * this.b * a);
      return new Color(r, g, b);
    }
    Color.prototype.fromHex = function(hex) {
      // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
      hex = hex.substring(1,7)
      var bigint = parseInt(hex, 16);
      this.r = (bigint >> 16) & 255;
      this.g = (bigint >> 8) & 255;
      this.b = bigint & 255;
    }

    ctx.font = "16px Arial";
    ctx.fillText("Manual Alpha Blend", 18, 20);

    var a = new Color(220, 0, 150);

    var b = new Color();
    b.fromHex('#00C864');

    //Alpha blend
    ctx.fillStyle = a.asHex();
    ctx.fillRect(25, 25, 100, 100);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(a.asHex(), 30, 45);
    ctx.fillStyle = b.asRGB()
    ctx.fillRect(50, 50, 100, 100);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(a.asHex(), 55, 145);
    var bl = a.blendWith(b, 0.3);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(50, 50, 75, 75);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(bl.asHex(), 55, 70);

    // lighten 1

    ctx.fillStyle = '#000000';
    ctx.fillText('Neutral Light', 200, 20);

    var c = new Color(100, 100, 100);
    var purelight= new Color(255, 255, 255);

    ctx.fillStyle = c.asRGB();
    ctx.fillRect(200, 25, 100, 100);

    var bl = c.Mul(purelight,1.2);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(225, 50, 100, 100);

    var bl = c.Mul(purelight, 0.8);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(250, 75, 100, 100);

     // lighten 2

    ctx.fillStyle = '#000000';
    ctx.fillText('Yellowish Light', 400, 20);

    var c = new Color(100, 100, 100);
    var yellowlight= new Color(255, 255, 220);

    var bl = c.Mul(yellowlight,1.0);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(400, 25, 100, 100);

    var bl = c.Mul(yellowlight,1.2);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(425, 50, 100, 100);

    var bl = c.Mul(yellowlight, 0.8);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(450, 75, 100, 100);
  }
}

PD: debe preguntar en stackoverflow ya que la mayoría de esto ya se puede encontrar en stackoverfow.

joojaa
fuente
¿Puede esta biblioteca ser independiente?
Vlad
@Vlad seguro que no veo ninguna razón por la que no.
joojaa
Lo probé, usa algunos módulos NodeJS, pero no quiero hacer que la aplicación sea pesada en bibliotecas de terceros. Intentaré hacer mi propio código.
Vlad
@Vlad agregó un código para que te
cape el
: D wow, ¡trabajo fantástico!
Vlad
1

Manualmente si desea cambiar la oscuridad / brillo de un color a mano y sin siquiera mirarlo. en hexadecimal o rgb es realmente fácil simplemente agregue o reste una cantidad igual de luz a cada canal.
Digamos que en rgb tienes 132,145,167 yo puedes sumar 30 a cada número para obtener una versión más clara del mismo color, así 162,175,207, y si te das cuenta de que lo hiciste un poco, resta 2 de cada uno, así 160,173,205. Lo mismo con hexadecimal pero en números hexadecimales. entonces e4c3d5 es e4 c3 d5, puede agregar 16 para hacerlo más claro f4d3e5 o restar 16 para hacer una versión más oscura del mismo color d4b3c5.
Puede sumar o restar tanto como desee, y mejorará al adivinar la cantidad correcta para sumar y restar horas extras, siempre que agregue la misma cantidad a los tres canales (los tres números) solo cambiará la forma mucho blanco agrega o elimina de la mezcla.

Ricardex el maestro
fuente
¡Frio! ¡Esto fue muy fácil y útil para un no codificador!
brookdancer