#+TITLE: On the Interaction of Color

* Introduction                                                       :ignore:

As I[fn:why] read through Josef Albers' Interaction of Color I realized I
could replace his choice of papers for color[fn:sp] with some carefully
applied javascript and a full screen web browser.

I've attempted to recreate the plates in the book to allow exploration
without having to collect a lot of paper. I've found that attempting
to reproduce the existing plates and just exploring values has been
leading to a much better understanding of the point of the chapter (I
think).

A warning: the plates rely on some Chrome/Webkit specific APIs —
there's only so much time and I have things to do and places to be;
none of which include cross browser javascript compatibility.

-----

[fn:sp] Out of deference to the author I've used color instead of colour throughout.

[fn:why] If you're curious why I would read this book — I know I like
certain color combinations, but have a ridiculously hard time choosing them
from scratch — and I hope to start developing an eye for
color by working through this book. There’s a reason this blog is mostly black and white.

* Utility code                                                       :ignore:
#+BEGIN_EXPORT html
<style type='text/css'>
  .plate {
    border-top: solid #000 8px;
    border-bottom: solid #000 8px;
    overflow: hidden;
    position: relative;
    width: 100%;
  }

  .colorpickers {
    background-color: #ddd;
    padding: 1em 0;
    text-align: center;
  }

  .colorpickers label {
    margin: 0 1em;
    text-transform: uppercase;
  }

  .plate {
    height: 400px;
  }
</style>

<script type='text/javascript'>

  function getBackgroundColor(id) {
    var elem = document.getElementById(id);
    var style = getComputedStyle(elem);
    var bgColor = style.getPropertyValue('background-color');

    // We're done for hex values
    if (bgColor.startsWith('#')) {
      return bgColor;
    }

    // Otherwise convert rgb[a](rr, gg, bb, [aa]) into hex
    var rgbRegex = /rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*.*?\)/;
    var matches = rgbRegex.exec(bgColor);
    var hexString = matches
        .slice(1, 4)
        .map(color => parseInt(color, 10).toString(16))
        .map(hex => hex.length < 2 ? '0' + hex : hex)
        .join('');
    return '#' + hexString;
  }

  function attachInput(sourceId, targetIds) {
    var source = document.getElementById(sourceId);
    source.value = getBackgroundColor(targetIds[0]);

    source.onchange = function() {
      for(var targetId of targetIds) {
        console.info(sourceId, source.value);
        document.getElementById(targetId).style.backgroundColor = source.value;
      }
    }
  }

  function launchFullScreenOnClick(element) {
    var el = document.getElementById(element);
    el.onclick = function() {
      el.webkitRequestFullScreen();
    }
  }
</script>
#+END_EXPORT

* ‘Color is the most relative medium in art’
#+BEGIN_EXPORT html
<style type='text/css'>
  #rc-bg-1, #rc-bg-2 {
    height: 400px;
  }

  #rc-bg-1 {
    background-color: #2a6182;
    float: left;
    width: 50%;
  }

  #rc-bg-2 {
    background-color: #ff8225;
    float: right;
    width: 50%;
  }

  #rc-fg-1, #rc-fg-2 {
    height: 20%;
    margin: 160px auto;
    width: 20%;
    transform: rotate(19deg)
  }

  #rc-fg-3 {
    display: none;
    height: 20%;
    left: 30%;
    position: absolute;
    top: 160px;
    width: 40%;
  }

  #rc-fg-1, #rc-fg-2, #rc-fg-3 {
    background-color: #f07504;
  }
</style>

<div class='colorpickers'>
  <label>
    Left
    <input type='color' id='input-rc-bg-1'>
  </label>
  <label>
    Rectangles
    <input type='color' id='input-rc-fg'>
  </label>
  <label>
    Right
    <input type='color' id='input-rc-bg-2'>
  </label>
</div>
<div id='relative-color' class='plate'>
  <div id='rc-bg-1'>
    <div id='rc-fg-1' class='rc-hover'>
    </div>
  </div>
  <div id='rc-bg-2'>
    <div id='rc-fg-2' class='rc-hover'>
    </div>
  </div>
  <div id='rc-fg-3'></div>
</div>

<script type='text/javascript'>
launchFullScreenOnClick('relative-color');

var rcfgs = document.getElementsByClassName('rc-hover');
var rcfg3 = document.getElementById('rc-fg-3');
for (var i = 0, l = rcfgs.length; i < l; i++) {
  rcfgs[i].onmouseover = function(){ rcfg3.style.display = 'block'; }
  rcfgs[i].onmouseout = function(){ rcfg3.style.display = 'none'; }
}

attachInput('input-rc-bg-1', ['rc-bg-1']);
attachInput('input-rc-bg-2', ['rc-bg-2']);
attachInput('input-rc-fg', ['rc-fg-1', 'rc-fg-2', 'rc-fg-3']);
</script>
#+END_EXPORT

-----

* ‘Lighter and / or darker’
** Source                                                           :ignore:
#+BEGIN_EXPORT html
<style type='text/css'>
  #lighter-darker {
    background-color: #000;
  }

  #ld-container {
    height: 300px;
    width: 600px;
    margin: 50px auto;
  }

  #ld-left, #ld-right {
    height: 300px;
    position: relative;
    width: 300px;
  }

  #ld-left {
    float: left;
  }

  #ld-right {
    float: right;
  }

  #ld-1, #ld-2 {
    height: 200px;
    margin-top: 50px;
    transform: rotate(45deg);
    width: 200px;
  }

  #ld-1 {
    background-color: #5d3ca8;
    float: right;
    left: 0;
  }

  #ld-2 {
    background-color: #4771cb;
    float: left;
    right: 0;
  }
</style>

<div class='colorpickers'>
  <label>
    Left
    <input type='color' id='input-ld-1'>
  </label>
  <label>
    Right
    <input type='color' id='input-ld-2'>
  </label>
</div>
<div id='lighter-darker' class='plate'>
  <div id='ld-container'>
    <div id='ld-left'>
      <div id='ld-1'>
      </div>
    </div>
    <div id='ld-right'>
      <div id='ld-2'>
      </div>
    </div>
  </div>
</div>

<script type='text/javascript'>
  launchFullScreenOnClick('lighter-darker')

  attachInput('input-ld-1', ['ld-1']);
  attachInput('input-ld-2', ['ld-2']);

  var ld1 = document.getElementById('ld-1');
  var ld2 = document.getElementById('ld-2');
  ld1.onmouseover = () => ld2.style.float = 'right';
  ld1.onmouseout = () => ld2.style.float = 'left';

  var input1 = document.getElementById('input-ld-1');
  var input2 = document.getElementById('input-ld-2');
  ld1.onclick = (event) => {
    event.stopPropagation();

    var ld2Color = getBackgroundColor('ld-2');
    var ld1Color = getBackgroundColor('ld-1')
    input1.value = ld1.style.backgroundColor = ld2Color;
    input2.value = ld2.style.backgroundColor = ld1Color;
  }
</script>
#+END_EXPORT

-----
** Notes                                                          :noexport:
*** I'm having trouble understanding this chapter for color
*** TODO Evaluate luminance to understand brightness and verify

* Notes                                                            :noexport:
** TODO Make it more touch friendly (hover interactions)
** TODO Show hash codes of colorpickers somewhere
** TODO Try to derive some mathematical relations to automate color choice
** TODO Explain UI
** TODO Explain dev setup