jQuery カラーピッカー plugin で補色計算してみた。

jQuery カラーピッカー plugin を使う機会があったので、サンプルを作って「補色」を求めたら興味深いことが出てきました。
ColorPicker - jQuery plugin
を使います。昔からあるピッカーで有名なもの。
f:id:posturan:20160924163005j:plain
HTML をサンプルとして以下のように準備しました。CSSなどは割愛します。プラグインで配布された colorpicker.css
colorpicker.js を読み込むようにしておきます。

<div class="box">
   <div>Target</div>
   <div id="target"><div>#00ff00</div></div>
</div>
<div class="box">
   <div>反転色</div>
   <div id="reverse"><div>#ff00ff</div></div>
</div>
<div class="box">
   <div>補色</div>
   <div id="comple"><div>#ff00ff</div></div>
</div>
<div class="box">
   <div>背景:Target  文字:補色</div>
   <div id="stringcomple"><div>#ff00ff</div></div>
</div>
<div class="clear">
   <div id="customWidget">
      <div id="colorSelector"><div style="background-color: #00ff00"></div></div>
      <div id="colorpickerHolder"></div>
   </div>
</div>

反転色、補色の区別があるのかどうかよくわかってないのですが、今回は、、

反転色:RGB 値を各々、255 から差し引いたコードを指定
補色: Adobe Illustrator CS4方式、RGB コードの最小値+最大値を各RGB コードで差し引いた結果で RGB コードに指定

で計算してみました。

// picker の初期色表示
$('#colorSelector div').css("background-color", $('#target div').html());
// picjer 設定
$('#colorpickerHolder').ColorPicker({
   flat: true,
   color: $('#target div').html(),
   onSubmit: function(hsb, hex, rgb, el){
      $('#colorSelector div').css('backgroundColor', '#' + hex);
      // 反転色
      var r = ((255-rgb['r']) < 16 ? "0" : "") + (255-rgb['r']).toString(16);
      var g = ((255-rgb['g']) < 16 ? "0" : "") + (255-rgb['g']).toString(16);
      var b = ((255-rgb['b']) < 16 ? "0" : "") + (255-rgb['b']).toString(16);
      var reverse = "#" + r + g + b;
      // 補色計算
      var sum = Math.max(rgb['r'], Math.max(rgb['g'], rgb['b'])) +  Math.min(rgb['r'], Math.min(rgb['g'], rgb['b']));
      console.log(sum);
      var cr = sum - rgb['r'];
      var cg = sum - rgb['g'];
      var cb = sum - rgb['b'];
      var complementary = "#" + (cr < 16 ? "0" : "") + cr.toString(16)
                        + (cg < 16 ? "0" : "") + cg.toString(16)
                        + (cb < 16 ? "0" : "") + cb.toString(16)
      console.log(complementary);

      // 結果を別のエリアにセット
      /*---------- target -------------------------------------*/
      $('#target div').html("#" + hex);
      $('#target').css("background-color", "#" + hex);
      // 文字は反転色で。
      $('#target').css("color", reverse);
      /*---------- reverse -------------------------------------*/
      $('#reverse div').html(reverse);
      $('#reverse').css("background-color", reverse);
      // 文字は反転色で。
      $('#reverse').css("color", "#" + hex);
      /*---------- complementary -------------------------------*/
      $('#comple div').html(complementary);
      $('#comple').css("background-color", complementary);
      // 文字は反転色で。
      var complevarse = "#" + ((255-cr) < 16 ? "0" : "") + (255-cr).toString(16)
                       + ((255-cg) < 16 ? "0" : "") + (255-cg).toString(16)
                       + ((255-cb) < 16 ? "0" : "") + (255-cb).toString(16);
      $('#comple').css("color", complevarse);
      /*---------- stringcomple 背景:Target  文字:補色 ------*/
      $('#stringcomple div').html(complementary);
      $('#stringcomple').css("background-color", "#" + hex);
      $('#stringcomple').css("color", complementary);

      // 閉じる
      $('#colorpickerHolder').stop().animate({ height: 0 }, 500 );
   }
});
$('#colorpickerHolder>div').css('position', 'absolute');
var widt = false;
$('#colorSelector').bind('click', function(){
   $('#colorpickerHolder').stop().animate({ height: widt ? 0 : 173 }, 500 );
   widt = !widt;
});

色が濃い場合は、反転色も補色も見た目の差があまりないのですが、薄い色で実行すると、、

f:id:posturan:20160924163858j:plain

この補色を文字色にするとなんとも醜い。

補色=色相環図の反対側にある色と言われているけど、色が薄い場合、Adobe Illustrator CS4方式の計算は正しく見えるけど
2つの色を並べた時に鮮明な違いを起こすのが、補色というなら、反転色の計算の方が仕様にあってる思えます。
では、色相環のサークル(円)は、いったい何なの?意味あるの?

補色の目的によると思うが、自動計算で求めるのにもっと良い計算式があるのだろうか?
それとも、配色の感じ方が人それぞれ違うはずだから、計算で普遍的に色コードを求めた結果を押し付けるのはナンセンス?