11

I have this picture:

colors

The arrows show two different colors but in fact they should be same color but a bit lighter or darker.

I made this screen-shot of the application I make and the brownish color on the edges is just the blue color summed with 30. As you can see it does not do the trick, i.e adding 30 to the actual color will not work for all colors.

actual colors

How can I just shade a given color i.e make it brighter or darker?

Also what should I do If I want it to look semitransparent with alpha?

6
  • I'm voting to close this question as off-topic because it should be asked on stackoverflow.
    – joojaa
    Jul 29, 2016 at 8:39
  • 4
    Technically its still a graphics design question since we discuss math behind colors and shading colors, producing different variants of colors.
    – Vlad
    Jul 29, 2016 at 8:44
  • 1
    no we discuss hexadecimal conversion. I would be fine with a color question but you have bound this so heavily with your computation environment that it nolonger satisfies your claim. So youve over specified it to become a javascript and markup nodeling question and that is not graphic design.
    – joojaa
    Jul 29, 2016 at 9:08
  • 1
    No the question says right, what should I do to make a color darker or brighter. Conversion to hexadecimal value is useful addition but not a necessity.
    – Vlad
    Jul 29, 2016 at 9:16
  • 1
    I am not going to argue. I don't understand colors and how they work, I was asking for a "how to", not a piece of code that somebody will code for me.
    – Vlad
    Jul 29, 2016 at 9:49

3 Answers 3

16

Cool question.

To work with hexadecimal values you need to think in terms of relative proportion of the RGB values.

I will use a scale in numbers, not with letters, so we can see the math behind it.

Imagine you have an orange.

You can have a value of R255 G128 B0

If you want a darker color you need to reduce the values for example at 50%

This will give you R128 G64 B0 Notice that all colors were modified using a proportional scale.

A more complex color could be R255 G200 B100 Let us darken it but not as much as the previous case. Let us just darken it one 80%.

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

To make one color lighter the idea is pretty much the same, But it is more tricky because the colors will cap at 255, so you can think on the diference between the 255 to your values.

For example the same orange

R255 G128 B0

You can not augment R anymore, and you can not increase the Green and the blue with the same values, for example 100 more, because you will have

R255 G228 B100

which is too yellow.

The math would be

1) The difference from 255 to the current value (R255 G128 B0) is: R0 G127 B255

2) Let us make a lighter orange by 50%

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

4) Add that to your initial value: R255+0 G128+64 B0+128 = R255 G192 B128.

I am adding an image to give you the basic idea. The RGB values are not the same of my text, just because a lazy work, but you can see that the orange "stairs" retain its intrinsect proportions.

enter image description here

Edited

I am so dumb. You can also use the HSL Color notation:

{background-color: hsl(45, 60%, 70%);} and modify the third color for darker colors, and the second and third for lighter ones.

You also can use an hsla variant to include alpha.


Edited: and here is part two about transparency.

Restoring transparency lost when a single color image was overlaid on white

And how to find the inverse color.

How do you find an inverse colour?

6
  • Offcourse if this is a browser its completely capable of calculating that for you
    – joojaa
    Jul 29, 2016 at 8:30
  • Yes a JS/browser application. But Js does not recognize #345464 formated color. I use parseInt(hashString.replace('#', ''), 16); where hashString is CSS formated color like #345464.
    – Vlad
    Jul 29, 2016 at 8:39
  • You translate your numbers as you please. I sayed that was using numbers so you can see the math behind it. But the principle is the same. 8 is the half of F.
    – Rafael
    Jul 29, 2016 at 8:53
  • And you can always use the rgba(255,128,0,1) notation.
    – Rafael
    Jul 29, 2016 at 8:55
  • Actuall I use Canvas element and it is pure JS, no CSS inculded. But I got an idea of how to solve this with code.
    – Vlad
    Jul 29, 2016 at 9:20
2

You have misunderstood things a bit, javaScript does not model color as hexadecimal, neither does the system. The hexadecimal notation is just for the human readable document. Internally your system stores three integer values. You can querry and manipulate those directly.

But lets just say that you want to manipulate the actual document instead of system internals. Then its best to defer your computation to some library that does this for you. You see the browser can represent colors in many ways so you would need to program all kinds of cases such ad rgb and hsv inputs. So I suggest you use something like Color.js it saves you a lot of headache, as you do not need to implement blending, darkening, lightening etc... yourself.

Edity:

In case you want to do this yourself, which i do not recommend. Start by turning the hexarepresentation into numeric triplets of integers or floating point numbers in range 0-1 this makes computation easier.

Now for easy manipulation of color convert RGB values to HSL or HSB this makes brightness calculations trivial to do (Wikipedia has formulations). So then just add or subtract lightness or brightess. For real light simulation the computation is easy enough just multiply the light color by base color. Thus for neutral light its simply:

Result = Intensity*Color

As Rafael explained, formula repeated by color channel. You can simulate colored light by doing

Result = Intensity * LigtColor * Color

For this best to convert to float first, maybe linear also. This allows for warm or cool light on your area which can bring in more natural feel.

Alpha blending (layerimg of color on top of other) is simply

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

Final Edit

Finally here is some code that does something towards what you ask. The reason this is hard to see is that its sort of abstract in form right now. Live code available here

enter image description here

Image 1: Result of code below see also live version.

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

PS you should ask on stackoverflow since most of this can in fact allready be found on stackoverfow.

5
  • Can this library be standalone?
    – Vlad
    Jul 29, 2016 at 8:46
  • @Vlad sure i see no reason why not.
    – joojaa
    Jul 29, 2016 at 9:06
  • I tried it, it uses some NodeJS modules, but I don't want to make app heavy on third party libraries. Will try to make my own code.
    – Vlad
    Jul 29, 2016 at 9:12
  • @Vlad added some code for you to scalp
    – joojaa
    Jul 29, 2016 at 12:09
  • :D wow, fantastic work!
    – Vlad
    Aug 1, 2016 at 6:05
1

Manually if you want to change the darkness/brightness of a color by hand and without even looking at it. in hex or rgb is really easy just add or substract an equal ammount of light to each channel.
Say in rgb you have 132,145,167 yo can add 30 to each number to get a lighter version of the same color so 162,175,207, and if the you realize you over did it by just a bit then subtract 2 from each so 160,173,205. Same with hex but in hex numbers. so e4c3d5 is e4 c3 d5 you can add 16 to make it lighter f4d3e5 or subtract 16 to make darker version of the same color d4b3c5.
You can add or substract as much as you want, and you will get better at guessing the right ammount to add and substract overtime, as long as you add the same ammount to all three channels (all three numbers) you will only change the how much white you add or remove from the mixture.

1
  • Cool! This was so easy and helpful for a non-coder! Aug 2, 2016 at 21:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.