Skip to content

Instantly share code, notes, and snippets.

@ExFlo
Forked from jedfoster/.gitignore
Created April 14, 2020 14:20
Show Gist options
  • Select an option

  • Save ExFlo/f1e0620a09f437af6bde400e879e98ac to your computer and use it in GitHub Desktop.

Select an option

Save ExFlo/f1e0620a09f437af6bde400e879e98ac to your computer and use it in GitHub Desktop.
JavaScript version of Sass' mix() function

I recently found myself needing to combine two colors. Sass has a great function for doing this, even allowing you to control the percentage of each color, but in my case the two colors needed to change every few seconds, so Sass was out of the question. Enter JavaScript.

Here's my JavaScript version of Sass' mix() function.

var mix = function(color_1, color_2, weight) {
  function d2h(d) { return d.toString(16); }
  function h2d(h) { return parseInt(h, 16); }

  weight = (typeof(weight) !== 'undefined') ? weight : 50;

  var color = "#";

  for(var i = 0; i <= 5; i += 2) {
    var v1 = h2d(color_1.substr(i, 2)),
        v2 = h2d(color_2.substr(i, 2)),
        val = d2h(Math.floor(v2 + (v1 - v2) * (weight / 100.0)));

    while(val.length < 2){
      val = '0' + val;
    }
    color += val;
  }
    
  return color;
};

Unlike the Sass version, my JavaScript version only accepts 6-digit hex values for the colors (#ff0000 works, but #f00 does not.) Like the Sass version, the weight argument is an integer value between 0 and 100.

var mixed = mix('ff0000', '0000bb', 75); // returns #bf002e

Because it only accepts 6-digit hex values you may need to convert your color from RGB, particularly if you obtained it using something like window.getComputedStyle(div).backgroundColor;, as I did. In that case, this function has you covered:

var rgb2hex = function(rgb) {
  rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d\.]+))?\)$/);
  function hex(x) {
    return ("0" + parseInt(x).toString(16)).slice(-2);
  }
  return (hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3])).toUpperCase();
};

Use it like so:

var color1 = window.getComputedStyle(element1).backgroundColor; // 'ff0000'
var color2 = window.getComputedStyle(element2).backgroundColor; // '0000bb'

var mixed = mix(rgb2hex(color1), rgb2hex(color2), 75); // returns #bf002e

Play with the Sass version over on SassMeister.com

// ----
// Sass (v3.3.0.rc.1)
// Compass (v0.13.alpha.10)
// ----
body {
width: 100%;
height: 10em;
background: mix(#ff0000, #0000bb, 75);
}
body {
width: 100%;
height: 10em;
background: #bf002e;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment