Average 2 hex colors together in javascript

A quick/dirty/convenient/ES6 way to blend two hex colors by a specified perecentage:

// blend two hex colors together by an amount
function blendColors(colorA, colorB, amount) {
  const [rA, gA, bA] = colorA.match(/\w\w/g).map((c) => parseInt(c, 16));
  const [rB, gB, bB] = colorB.match(/\w\w/g).map((c) => parseInt(c, 16));
  const r = Math.round(rA + (rB - rA) * amount).toString(16).padStart(2, '0');
  const g = Math.round(gA + (gB - gA) * amount).toString(16).padStart(2, '0');
  const b = Math.round(bA + (bB - bA) * amount).toString(16).padStart(2, '0');
  return '#' + r + g + b;
}

console.log(blendColors('#00FF66', '#443456', 0.5));

Where amount should be 0 to 1, with 0 being exactly colorA, 1 being exactly colorB, and 0.5 being the "midpoint".


Smells like homework to me, but here's my clue.

Take each hex value for R, G, and B, and average each of them. If necessary convert to Decimal to do the math.

function d2h(d) {return d.toString(16).padStart(2,'0');}

function h2d(h) {return parseInt(h,16);}

Then return a string containing the concatenated values of the three elements.


I hate sounding like the oh-so-broken jQuery record, but there is a jQuery plugin for this already.

$.xcolor.average(color, color)


Only requires a few lines of POJS if you don't want to bother with lots of unnecessary stuff:

// Expects input as 'nnnnnn' where each nn is a 
// 2 character hex number for an RGB color value
// e.g. #3f33c6
// Returns the average as a hex number without leading #
var averageRGB = (function () {

  // Keep helper stuff in closures
  var reSegment = /[\da-z]{2}/gi;

  // If speed matters, put these in for loop below
  function dec2hex(v) {return v.toString(16);}
  function hex2dec(v) {return parseInt(v,16);}

  return function (c1, c2) {

    // Split into parts
    var b1 = c1.match(reSegment);
    var b2 = c2.match(reSegment);
    var t, c = [];

    // Average each set of hex numbers going via dec
    // always rounds down
    for (var i=b1.length; i;) {
      t = dec2hex( (hex2dec(b1[--i]) + hex2dec(b2[i])) >> 1 );

      // Add leading zero if only one character
      c[i] = t.length == 2? '' + t : '0' + t; 
    }
    return  c.join('');
  }
}());