Mona Coder
Mona Coder

Reputation: 6316

How to calculate a darker hex color

Using this solution I am trying to calculate the darker range of a color but the output is doesn't look like correct Hex value (missing one value).

> #84079

What am I doing wrong?

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);
  
}
var firstColor = LightenDarkenColor("#3068A1", -20); 
var NewColor = LightenDarkenColor(firstColor, -20); 

console.log(NewColor);

Upvotes: 2

Views: 96

Answers (1)

Intervalia
Intervalia

Reputation: 10975

Change this:

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

to this

(usePound?"#":"") + ('00000'+(b | (g << 8) | (r << 16)).toString(16)).slice(-6);

This will make sure that there are 6 digits and it fixes the green and blue location which were off in the original article.

  • (r << 16) moves the red to bits 32 to 47
  • (g << 8) moves the green to bits 16 to 31
  • and b leaves the blue in bits 0-15.

UPDATE

As was pointed out the b and g variables are reading the wrong values as well. So you want to do the following as well:

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

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

Swap where the b and g get their values.

If you don't want to swap those then change my original line to this:

(usePound?"#":"") + ('00000'+(g | (b << 8) | (r << 16)).toString(16)).slice(-6);

Upvotes: 3

Related Questions