jnobuyukiのブログ

研究していて困ったことやその解決に関するメモ。同じように困ったあなたのために。twitter ID: @j_nobuyuki

加法混色と減法混色

今回は色を混ぜるという話です。色を混ぜるといっても二種類のやり方があるので、それを整理しながら、D3.jsでSVGオブジェクトの色を変換する方法を紹介します。

混ざると明るくなる加法混色

混ざると明るくなるのは、いわゆるRGBに基づく色の場合です。光の3原色(赤、緑、青)の値のどれでも増やすほど、輝度が増して白に近づいていきます。ディスプレイはこの原理を利用して色が表示されています。

混ざると暗くなる減法混色

混ざると暗くなるのは、いわゆるCMYに基づく混色です。Cはシアン、Mはマゼンタ、Yはイエローを示しています。直感的な例として、絵の具をパレット上で混ぜる場合が減法混色です。

D3.jsを利用したSVGオブジェクトの色変換

D3.jsではrbg()というメソッドが用意されているので簡単に色を決められます。

まずは色を変えるためのオブジェクトを作成します。

HTML

<html>
<head>
  <meta charset = "utf-8">
  <script src = "http://d3js.org/d3.v3.min.js" charset = "utf-8"></script>
</head>

<body>
  <form>
  <table><tr><td>赤</td><td><input type = "text" id = "red" value = "0"></td></tr>
  <tr><td>緑</td><td><input type = "text" id = "green" value = "0"></td></tr>
  <tr><td>青</td><td><input type = "text" id = "blue" value = "0"></td></tr>
  </table>
 
  </form>
   <button id = "start" onclick = "colorTransform();">スタート</button>
  <div id = "stage"></div>
</body>
</html>

HTMLではhead部でD3.jsのライブラリを呼び出します。次にテーブルの中にラベルとテキストボックスを並べて、RGBの各コンポーネントの値を入力できるようにします。そしてスタートというラベルのボタンを押すとcolorTransform()という関数の起動を設定します。

では次にJavaScriptのcolorTransform()を作りましょう。

var svg = d3.select("#stage").append("svg").attr("width",500).attr("height",500);

var rect = svg.append("rect").attr("width",400).attr("height",400)
.attr("x",50).attr("y",50).style("fill", "#ffffff").style("stroke","black");

最初にHTML内のdivオブジェクトにSVGを加えます。その上に四角を作りました。この四角の色を変更することにします。

加法混色の場合
function colorTransform(){
  
  var currentRed =  parseInt(document.getElementById("red").value);
  var currentGreen = parseInt(document.getElementById("green").value);
  var currentBlue = parseInt(document.getElementById("blue").value);

  var currentColor = d3.rgb(currentRed, currentGreen, currentBlue);
  console.log(currentColor);
  
  rect.transition().delay(0).duration(1000).style("fill",function(){ return currentColor;});  
}

colorTransform()では最初に3つのテキストボックスの値を抽出します。それをrgb()メソッドで一つの色名を示す数字に変換します。最後にtransition()メソッドでrectの色を変更します。

減法混色の場合

減法混色でもrgb()メソッドを近似的に利用できます。たとえばシアンの値を上げるというのは加法原色に基づけば緑と青の値を上げることに相当しますが、減法混色では補色である赤の値を下げることに相当します。そこでcolorTransform()の最初の部分を次のように直します。(HTMLでcyan,magenta,yellowを入力するためのテキストボックスも作ります)

  var currentRed =  255 - parseInt(document.getElementById("cyan").value);
  var currentGreen = 255 - parseInt(document.getElementById("magenta").value);
  var currentBlue = 255 - parseInt(document.getElementById("yellow").value);

ここまでをまとめると以下のようになります。