Dynamic Color Contrast

by David Kyle

HTML

<div class="output">
  <h2>
    Color Output
  </h2>
  <sup>Determines the appropriate contrast test color for a given background color.</sup>
  <div class="test">
    hello
  </div>
</div>

<div class="errors">
</div>

<div class="input">
  <label for="color">Color (in hex):</label><input type="text" name="color" id="color" />
  <br />
  <button type="button" id="checkColor" name="checkColor">
    Check
  </button>
</div>

CSS

body {
  font-family: Verdana, Arial, sans-serif;
  font-size: small;
  color: #121212;
}

.output {
  display: block;
  border: solid 1px #000000;
  border-radius: 3px;
  padding: 3px;
  background-color: #efefef;
  width: 60%;
  margin: 0px auto;
}

.output .test {
  border-radius: 3px;
  padding: 3px;
}

.errors {
  display: none;
  color: #ff0000;
}

.input {
  margin-top: 15px;
}

.input label {
  margin-right: 4px;
}

.input button {
  text-align: right;
  align-content: right;
}

JavaScript

let ColorWork = (function() {
  let self = {},
    maxDensity = 255 + 255 + 255,
    minDensity = 0,
    hexNumbers = {
      '0': 0,
      '1': 1,
      '2': 2,
      '3': 3,
      '4': 4,
      '5': 5,
      '6': 6,
      '7': 7,
      '8': 8,
      '9': 9,
      'a': 10,
      'b': 11,
      'c': 12,
      'd': 13,
      'e': 14,
      'f': 15
    };

  let convertToDecimal = function(hex) {
    let decimalNotation = 0;
    console.log(hex);
    if (hex === 0 || (hex.length > 6 || hex.length < 3 || (hex !== 0 && (hex / 1) != 0 && !Number("0x" + hex)))) {
      throw new Error("Invalid Hex string");
    }

    let r = '',
      g = '',
      b = '';

    if (hex.length === 6) {
      r = hex.substring(0, 1).toLowerCase();
      g = hex.substring(2, 3).toLowerCase();
      b = hex.substring(4, 5).toLowerCase();
    } else {
      r = hex[0].toLowerCase();
      g = hex[1].toLowerCase();
      b = hex[2].toLowerCase();
    }

    let rVal = computeHex(r),
      gVal = computeHex(g),
      bVal = computeHex(b);

    return rVal + gVal + bVal;
  };

  function computeHex(hex) {
    if (hex.length === 2) {
      return (hexNumbers[hex[0]] * 16) + (hexNumbers[hex[1]]);
    } else {
      return (hexNumbers[hex[0]] * 16) + (hexNumbers[hex[0]]);
    }
  }

  self.SetColors = function(e) {
    let colorDensity = '',
      textColor = '';

    try {
      colorDensity = convertToDecimal(e.data.color().replace('#', ''));
    } catch (er) {
      let $errors = $('.errors');
      $errors.text(er);
      $errors.fadeIn(500);
      setTimeout(function() {
        $errors.fadeOut(500);
      }, 5000);
      return;
    }

    if (colorDensity > (maxDensity / 2)) {
      textColor = '#000000';
    } else {
      textColor = '#ffffff';
    }

    let $testOutput = $('.test');
    $testOutput.css('background-color', ('#' + e.data.color()).replace('##', '#'));
    $testOutput.css('color', textColor);
  };

  return self;
})();

$(function() {
  console.log('ready');
 ...