Colour mixer

by Dominic Myers

HTML

<div class="progress-bar" id="bar" data-value="0">
  <span class="progress-bar-filler"></span>
</div>

SCSS

:root {
  --under-third: #FF0000;
  --third-to-two-thirds: #FF9900;
  --over-two-thirds: #33FF00;
}
.progress-bar {
  width: 100%;
  height: 20px;
  border: 1px solid #888;
  background-color: #ddd;
  position: relative;
  .progress-bar-filler {
    width: 0%;
    height: 100%;
    background-color: #fff;
    position: absolute;
  }
}

JavaScript

/* functions */
const hexToRGB = hex => hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (m, r, g, b) => '#' + r + r + g + g + b + b).substring(1).match(/.{2}/g).map(x => parseInt(x, 16))
const mixColour = (c1, c2, pc) => RGBToHex(Math.round(mix(c1[0], c2[0], pc)), Math.round(mix(c1[1], c2[1], pc)), Math.round(mix(c1[2], c2[2], pc)))
const RGBToHex = (r, g, b) => `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`
const mix = (s, e, pc) => s + ((pc) * (e - s))
/* value */
let value = 0;
/* elements */
const container = document.getElementById('bar');
const bar = container.querySelector('.progress-bar-filler');
/* colours */
const red = hexToRGB(getComputedStyle(document.documentElement).getPropertyValue('--under-third').trim())
const amber = hexToRGB(getComputedStyle(document.documentElement).getPropertyValue('--third-to-two-thirds').trim())
const green = hexToRGB(getComputedStyle(document.documentElement).getPropertyValue('--over-two-thirds').trim())
/* do stuff */
const interval = setInterval( 
	() => {
  	value = value === 100 ? 0 : value + 1;
  	/* top bar */
		container.setAttribute('data-value', value);
    bar.style.width = value + "%";
    bar.style.backgroundColor = value < 50
    	? mixColour(red, amber, (value / 50))
    	: mixColour(amber, green, ((value - 50) / 50))
  }, 100);