JavaScript Color Functions
Colors are typically expressed through hexadecimal codes, either prefixed using a pound sign (#
) or 0x
to denote base 16 values.
These values represent individual channels of red, green, blue, and optionally alpha for transparency. Each channel specifies 8 bits:
minimum maximum
--------- ---------
base 10: 0 255
base 16: 0x00 0xff
binary: 0000 0000 1111 1111
Combining these channels together, we end up with RGB codes, such as:
0xff0000
— Red0x00ff00
— Green0x0000ff
— Blue
There may be times when computational operations need performed.
24-bit RGB
Most of the time color codes are RGB, meaning 8-bits red, 8-bits green, and 8-bits blue for a total of 24-bits to store the entire value. Here are a set of functions for manipulating color data.
If you have a 24-bit color value, and want to get individual values of each channel, use the zero fill right shift bitwise operator:
const color = 0x123456;const r = color >>> 16 & 0xff; // 0x12
const g = color >>> 8 & 0xff; // 0x34
const b = color & 0xff; // 0x56
Or inverse of that, if you need to construct a 24-bit color from red, green, and blue values:
const r = 0x12;
const g = 0x34;
const b = 0x56;const color = r << 16 | g << 8 | b; // 0x123456
Color Contrast
When text is overlaid on top of a colorful background, it may become difficult to read — black text on a dark background, white text on a light background, or any assortment of colors can affect legibility.
One strategy is a YIQ color contrast calculation, returning black or white determination of optimal text color based upon the 24-bit RGB value passed into the function.
function contrastYiq(color) {
const r = (color >>> 16) & 0xff;
const g = (color >>> 8) & 0xff;
const b = color & 0xff;
const yiq = (r * 299 + g * 587 + b * 114) / 1000; return yiq >= 128 ? 0x0 : 0xffffff;
};
Pass your color to the function, and use the return value as your text color.
Grayscale
Converting color to grayscale has numerous options yielding different results, but here are examples of averaging and desaturation using Luma ITU-R algorithms:
One approach to converting RGB colors to black and white grayscale is to average their values by dividing by three.
const r = 0xff;
const g = 0x00;
const b = 0x00;const gray = (r + g + b) / 3 >> 0; // 0x55const color = gray << 16 | gray << 8 | gray; // 0x555555
Another approach is desaturation using Luma ITU-R BT.601 conversion.
const r = 0xff;
const g = 0x00;
const b = 0x00;const gray = (r * 0.299 +
g * 0.587 +
b * 0.114) >> 0; // 0x4cconst color = gray << 16 | gray << 8 | gray; // 0x4c4c4c
Slight variant, using Luma ITU-R BT.709
const r = 0xff;
const g = 0x00;
const b = 0x00;const gray = (r * 0.2126 +
g * 0.7152 +
b * 0.0722) >> 0; // 0x36const color = gray << 16 | gray << 8 | gray; // 0x363636
Negate
If you want the inverse, negating the color, use the bitwise XOR operator:
const color = 0xff00ff;const negated = color ^ 0xffffff; // 0x00ff00;
Alpha Channel Transparency
With transparency comes an added 8-bit alpha channel, which can be specified before the RGB values (ARGB) or after (RGBA).
32-bit ARGB
If you have a 32-bit ARGB color value, and want to get individual values of each channel, use the zero fill right shift bitwise operator:
const color = 0xff123456;const a = color >>> 24; // 0xff
const r = color >>> 16 & 0xff; // 0x12
const g = color >>> 8 & 0xff; // 0x34
const b = color & 0xff; // 0x56
Or inverse of that, if you need to construct a 32-bit color from alpha, red, green, and blue values:
const a = 0xff;
const r = 0x12;
const g = 0x34;
const b = 0x56;const color = a << 24 | r << 16 | g << 8 | b; // 0xff123456
32-bit RGBA
Alternatively, if you have a 32-bit RGBA color value, and want to get individual values of each channel, use the zero fill right shift bitwise operator:
const color = 0x123456ff;const r = color >>> 24; // 0x12
const g = color >>> 16 & 0xff; // 0x34
const b = color >>> 8 & 0xff; // 0x56
const a = color & 0xff; // 0xff
Or inverse of that, if you need to construct a 32-bit color from red, green, blue, and alpha values:
const r = 0x12;
const g = 0x34;
const b = 0x56;
const a = 0xff;const color = r << 24 | g << 16 | b << 8 | a; // 0x123456ff
If you need to translate ARGB to RGBA:
const color = 0xff123456;const rgba = color << 8 | color >>> 24; // 0x123456ff