JavaScript Color Functions

Jason Sturges
The Startup
Published in
4 min readJul 20, 2020
Photo by Andrew Ridley on Unsplash

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 — Red
  • 0x00ff00 — Green
  • 0x0000ff— 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; // 0x4c
const 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; // 0x36
const 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

--

--

Jason Sturges
The Startup

Avant-garde experimental artist — creative professional leveraging technology for immersive experiences