Js Function to Calculate Complementary Colour

JS function to calculate complementary colour?

Parsed through http://design.geckotribe.com/colorwheel/

    // Complement    temprgb={ r: 0, g: 0xff, b: 0xff }; // Cyan    temphsv=RGB2HSV(temprgb);    temphsv.hue=HueShift(temphsv.hue,180.0);    temprgb=HSV2RGB(temphsv);    console.log(temprgb); // Complement is red (0xff, 0, 0)        function RGB2HSV(rgb) {     hsv = new Object();     max=max3(rgb.r,rgb.g,rgb.b);     dif=max-min3(rgb.r,rgb.g,rgb.b);     hsv.saturation=(max==0.0)?0:(100*dif/max);     if (hsv.saturation==0) hsv.hue=0;      else if (rgb.r==max) hsv.hue=60.0*(rgb.g-rgb.b)/dif;     else if (rgb.g==max) hsv.hue=120.0+60.0*(rgb.b-rgb.r)/dif;     else if (rgb.b==max) hsv.hue=240.0+60.0*(rgb.r-rgb.g)/dif;     if (hsv.hue<0.0) hsv.hue+=360.0;     hsv.value=Math.round(max*100/255);     hsv.hue=Math.round(hsv.hue);     hsv.saturation=Math.round(hsv.saturation);     return hsv;    }        // RGB2HSV and HSV2RGB are based on Color Match Remix [http://color.twysted.net/]    // which is based on or copied from ColorMatch 5K [http://colormatch.dk/]    function HSV2RGB(hsv) {     var rgb=new Object();     if (hsv.saturation==0) {      rgb.r=rgb.g=rgb.b=Math.round(hsv.value*2.55);     } else {      hsv.hue/=60;      hsv.saturation/=100;      hsv.value/=100;      i=Math.floor(hsv.hue);      f=hsv.hue-i;      p=hsv.value*(1-hsv.saturation);      q=hsv.value*(1-hsv.saturation*f);      t=hsv.value*(1-hsv.saturation*(1-f));      switch(i) {      case 0: rgb.r=hsv.value; rgb.g=t; rgb.b=p; break;      case 1: rgb.r=q; rgb.g=hsv.value; rgb.b=p; break;      case 2: rgb.r=p; rgb.g=hsv.value; rgb.b=t; break;      case 3: rgb.r=p; rgb.g=q; rgb.b=hsv.value; break;      case 4: rgb.r=t; rgb.g=p; rgb.b=hsv.value; break;      default: rgb.r=hsv.value; rgb.g=p; rgb.b=q;      }      rgb.r=Math.round(rgb.r*255);      rgb.g=Math.round(rgb.g*255);      rgb.b=Math.round(rgb.b*255);     }     return rgb;    }
//Adding HueShift via Jacob (see comments) function HueShift(h,s) { h+=s; while (h>=360.0) h-=360.0; while (h<0.0) h+=360.0; return h; } //min max via Hairgami_Master (see comments) function min3(a,b,c) { return (a<b)?((a<c)?a:c):((b<c)?b:c); } function max3(a,b,c) { return (a>b)?((a>c)?a:c):((b>c)?b:c); }

How can I generate the opposite color according to current color?

UPDATE: Production-ready code on GitHub.


This is how I'd do it:

  1. Convert HEX to RGB
  2. Invert the R,G and B components
  3. Convert each component back to HEX
  4. Pad each component with zeros and output.
function invertColor(hex) {
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
// invert color components
var r = (255 - parseInt(hex.slice(0, 2), 16)).toString(16),
g = (255 - parseInt(hex.slice(2, 4), 16)).toString(16),
b = (255 - parseInt(hex.slice(4, 6), 16)).toString(16);
// pad each with zeros and return
return '#' + padZero(r) + padZero(g) + padZero(b);
}

function padZero(str, len) {
len = len || 2;
var zeros = new Array(len).join('0');
return (zeros + str).slice(-len);
}

Example Output:

Sample Image

Advanced Version:

This has a bw option that will decide whether to invert to black or white; so you'll get more contrast which is generally better for the human eye.

function invertColor(hex, bw) {
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
var r = parseInt(hex.slice(0, 2), 16),
g = parseInt(hex.slice(2, 4), 16),
b = parseInt(hex.slice(4, 6), 16);
if (bw) {
// https://stackoverflow.com/a/3943023/112731
return (r * 0.299 + g * 0.587 + b * 0.114) > 186
? '#000000'
: '#FFFFFF';
}
// invert color components
r = (255 - r).toString(16);
g = (255 - g).toString(16);
b = (255 - b).toString(16);
// pad each with zeros and return
return "#" + padZero(r) + padZero(g) + padZero(b);
}

Example Output:

Sample Image

Is there a formula that I can apply to find out a complementary color?

Here is how you can compute complementary colors with JavaScript:

// complement
temprgb=thisrgb;
temphsv=RGB2HSV(temprgb);
temphsv.hue=HueShift(temphsv.hue,180.0);
temprgb=HSV2RGB(temphsv);

function RGB2HSV(rgb) {
hsv = new Object();
max=max3(rgb.r,rgb.g,rgb.b);
dif=max-min3(rgb.r,rgb.g,rgb.b);
hsv.saturation=(max==0.0)?0:(100*dif/max);
if (hsv.saturation==0) hsv.hue=0;
else if (rgb.r==max) hsv.hue=60.0*(rgb.g-rgb.b)/dif;
else if (rgb.g==max) hsv.hue=120.0+60.0*(rgb.b-rgb.r)/dif;
else if (rgb.b==max) hsv.hue=240.0+60.0*(rgb.r-rgb.g)/dif;
if (hsv.hue<0.0) hsv.hue+=360.0;
hsv.value=Math.round(max*100/255);
hsv.hue=Math.round(hsv.hue);
hsv.saturation=Math.round(hsv.saturation);
return hsv;
}

// RGB2HSV and HSV2RGB are based on Color Match Remix [http://color.twysted.net/]
// which is based on or copied from ColorMatch 5K [http://colormatch.dk/]
function HSV2RGB(hsv) {
var rgb=new Object();
if (hsv.saturation==0) {
rgb.r=rgb.g=rgb.b=Math.round(hsv.value*2.55);
} else {
hsv.hue/=60;
hsv.saturation/=100;
hsv.value/=100;
i=Math.floor(hsv.hue);
f=hsv.hue-i;
p=hsv.value*(1-hsv.saturation);
q=hsv.value*(1-hsv.saturation*f);
t=hsv.value*(1-hsv.saturation*(1-f));
switch(i) {
case 0: rgb.r=hsv.value; rgb.g=t; rgb.b=p; break;
case 1: rgb.r=q; rgb.g=hsv.value; rgb.b=p; break;
case 2: rgb.r=p; rgb.g=hsv.value; rgb.b=t; break;
case 3: rgb.r=p; rgb.g=q; rgb.b=hsv.value; break;
case 4: rgb.r=t; rgb.g=p; rgb.b=hsv.value; break;
default: rgb.r=hsv.value; rgb.g=p; rgb.b=q;
}
rgb.r=Math.round(rgb.r*255);
rgb.g=Math.round(rgb.g*255);
rgb.b=Math.round(rgb.b*255);
}
return rgb;
}

//Adding HueShift via Jacob (see comments)
HueShift(h,s) {
h+=s; while (h>=360.0) h-=360.0; while (h<0.0) h+=360.0; return h;
}

//min max via Hairgami_Master (see comments)
function min3(a,b,c) {
return (a<b)?((a<c)?a:c):((b<c)?b:c);
}
function max3(a,b,c) {
return (a>b)?((a>c)?a:c):((b>c)?b:c);
}

Source

Is there a formula that I can apply to find out a complementary color?

Here is how you can compute complementary colors with JavaScript:

// complement
temprgb=thisrgb;
temphsv=RGB2HSV(temprgb);
temphsv.hue=HueShift(temphsv.hue,180.0);
temprgb=HSV2RGB(temphsv);

function RGB2HSV(rgb) {
hsv = new Object();
max=max3(rgb.r,rgb.g,rgb.b);
dif=max-min3(rgb.r,rgb.g,rgb.b);
hsv.saturation=(max==0.0)?0:(100*dif/max);
if (hsv.saturation==0) hsv.hue=0;
else if (rgb.r==max) hsv.hue=60.0*(rgb.g-rgb.b)/dif;
else if (rgb.g==max) hsv.hue=120.0+60.0*(rgb.b-rgb.r)/dif;
else if (rgb.b==max) hsv.hue=240.0+60.0*(rgb.r-rgb.g)/dif;
if (hsv.hue<0.0) hsv.hue+=360.0;
hsv.value=Math.round(max*100/255);
hsv.hue=Math.round(hsv.hue);
hsv.saturation=Math.round(hsv.saturation);
return hsv;
}

// RGB2HSV and HSV2RGB are based on Color Match Remix [http://color.twysted.net/]
// which is based on or copied from ColorMatch 5K [http://colormatch.dk/]
function HSV2RGB(hsv) {
var rgb=new Object();
if (hsv.saturation==0) {
rgb.r=rgb.g=rgb.b=Math.round(hsv.value*2.55);
} else {
hsv.hue/=60;
hsv.saturation/=100;
hsv.value/=100;
i=Math.floor(hsv.hue);
f=hsv.hue-i;
p=hsv.value*(1-hsv.saturation);
q=hsv.value*(1-hsv.saturation*f);
t=hsv.value*(1-hsv.saturation*(1-f));
switch(i) {
case 0: rgb.r=hsv.value; rgb.g=t; rgb.b=p; break;
case 1: rgb.r=q; rgb.g=hsv.value; rgb.b=p; break;
case 2: rgb.r=p; rgb.g=hsv.value; rgb.b=t; break;
case 3: rgb.r=p; rgb.g=q; rgb.b=hsv.value; break;
case 4: rgb.r=t; rgb.g=p; rgb.b=hsv.value; break;
default: rgb.r=hsv.value; rgb.g=p; rgb.b=q;
}
rgb.r=Math.round(rgb.r*255);
rgb.g=Math.round(rgb.g*255);
rgb.b=Math.round(rgb.b*255);
}
return rgb;
}

//Adding HueShift via Jacob (see comments)
HueShift(h,s) {
h+=s; while (h>=360.0) h-=360.0; while (h<0.0) h+=360.0; return h;
}

//min max via Hairgami_Master (see comments)
function min3(a,b,c) {
return (a<b)?((a<c)?a:c):((b<c)?b:c);
}
function max3(a,b,c) {
return (a>b)?((a>c)?a:c):((b>c)?b:c);
}

Source

Create Complementary, Triad, and Monochromatic Color palette from single Hex Color

I actually wrote a small script which can do much of this, colorflow.js.

Say your starting color was red (hex: #ff0000)

  1. Complementary color: colorflow.complement('#ff0000')
  2. Complementary color, palette of 5: colorflow.complement('#ff0000', 'double')
  3. Triadic: colorflow.triadic('#ff0000')
  4. Monochromatic: colorflow.rotational_dispersion('#c0c0c0', 5, 'saturation')

etc...

Calculating contrasting colours in javascript

In terms of sheer readability, you want to use black and white text on whatever background it is. So convert RGB to HSV, and just check whether V is < 0.5. If so, white, if not, black.

Try that first and see if you find it attractive.

If you don't, then you probably want the white and black not to be so stark when your background is too bright or too dark. To tone this down, keep the same hue and saturation, and use these values for brightness:

background V  foreground V
0.0-0.25 0.75
0.25-0.5 1.0
0.5-0.75 0.0
0.75-1.0 0.25

On a medium color, you'll still see black or white text which will be nicely readable. On a dark color or light color, you'll see the same color text but at least 3/4 away in terms of brightness and therefore still readable. I hope it looks nice :)

Generating complimentary hex color of randomly generated hex color in JS?

I recommend that you keep your colours as numbers, thereby making generation of the complementary colour a simple mathematical operation.

Only when required should you convert those colours to hexadecimal format, or indeed any other string format, such as rgb(r, g, b)

One option would be a single 24-bit integer, with red in the topmost 8 bits, then green, and blue in the least significant bits:

function getRandomColor() {
return Math.floor(Math.random() * 0x1000000);
}

function getComplementColor(c) {
return 0xffffff - c;
}

function getHexColor(c) {
return '#' + ("000000" + c.toString(16)).substr(-6);
}

[The concatenation and substr call in the getHexColor() function is a neat way of padding out the hex number with leading zeroes]

Formula to find the split complementaries of a color?

Convert to HSV then modify your hue angle by 180°±30° or so.

Conversions to HSV are common and easy to get. But you just need the angle bit, tweak it by the complement and then by the split and feed that sucker back into RGB.

rgb2hsv(r,g,b);
h += 180;
h0 = h + 30;
h1 = h - 30;
hsv2rgb(h0,s,v);
hsv2rgb(h1,s,v);

More or less. Pick up rgb2hsv and hsv2rgb from chroma.js or any any code base. Or grab copies of both and mash them together with just the stuff you want and make a single function thing to do it.



Related Topics



Leave a reply



Submit