JavaScript
HTML5

canvas で色相環を作ってみた


色相環って知っていますか?


いわゆる色相環

カラーピッカーとかでよく見かけるこういうのですね。

色相環

via 色相 - Wikipedia


マンセルの色相環

ただ、僕が言ってる色相環はこっちのこと。

マンセルの色相環

マンセル表色系 1 が提唱している 色相の連続的な変化を順序立てて円環にして並べたもの を指しています。

via マンセル・カラー・システム - Wikipedia


PCCS の色相環

更に PCCS(Practical Color Co-ordinate System:日本色研配色体系)によって作られた色相環もあります。

向かい合う色が心理補色 2 になるものでこんな感じのものです。

pccs-hue.png

今回はこの PCCS の色相環の12色に簡略化されたものを作っていきたいと思います!

via PCCS(Practical Color Co-ordinate System:日本色研配色体系)


作ってみよう!


ってどうやって作ろう?

色々と考えました。


  • CSS でがんばる とか

  • 正十二角形の辺を太くして色変えて丸める とか

  • もう画像でいいじゃん

ふたつ目の案が良さそうだと思いましたが、正十二角形を描画するのどうするの?

canvas でやってみるか!となったわけです :yum:


canvas で実装


HTML

<canvas id="hue-circle"></canvas>

これだけ。


CSS

なし(canvas は CSS で高さとか色とか指定できない)。


JS

大半は JS で実装します。


1. canvas 要素を取得して高さとか決める

const canvas = document.getElementById('hue-circle');

canvas.width = '300px';
canvas.height = '300px';


2. 描画できるように2Dコンテキストを取得する

const ctx = canvas.getContext('2d');


3. 円弧を描いてみる

canvas の円弧を描く基本はこんな感じです。

/**

* 円弧の描画
* @param {Object} ctx - 描画用 2D コンテキスト
* @param {number} x - 円弧の中心の X 座標
* @param {number} y - 円弧の中心の Y 座標
* @param {number} radius - 円弧の半径
* @param {number} startAngle - 円弧の開始角度
* @param {number} endAngle - 円弧の終了角度
* @param {string} colorCode - (任意)円弧の塗りつぶしカラーコード
*/

function fill(ctx, x, y, radius, startAngle, endAngle, colorCode) {

// 描画用にパスを作成
ctx.beginPath();

// "注記"参照
ctx.moveTo(x, y);

// 開始角度~終了角度の円弧描画をパスに登録(toRadianメソッドはラジアン角へ変換している)
ctx.arc(x, y, radius, toRadian(startAngle), toRadian(endAngle));

// 塗りつぶしの色を登録
ctx.fillStyle = colorCode;

// パスの内部エリアを塗りつぶして、単色の図形を描く
ctx.fill();
}

moveTo については次のような 注記 が有りました。


注記: beginPath() を呼び出した直後や canvas を新規作成した直後など、現在のパスが空であるときに最初にパスを構築するコマンドは、実際は何であるかにかかわらず常に moveTo() として扱われます。このためパスをリセットした後はほぼ必ず、開始位置を明示することが必要になるでしょう。


via canvas に図形を描く - MDN web docs

今回は塗りつぶしだけど、縁取りする図形を描画する場合は stroke でいけます。


4. 12色の円弧を描いてみる

先程の fill 関数を12回呼び出すことで実現しています。

// 黄色始まりのカラーコード一式(vivid トーン)

const colors = Object.values({
'Y' : '#FFE600',
'YG': '#99CF15',
'G' : '#33A23D',
'GB': '#008678',
'gB': '#055D87',
'B' : '#0F218B',
'V' : '#281285',
'P' : '#56007D',
'RP': '#AF0065',
'R' : '#EE0026',
'rO': '#FE4118',
'yO': '#FF7F00'
});

// 円弧の最も高い位置 270° から 15° 引いた角度から描画をはじめる
let angle = 255

// 12 回ループ
for (let i = 0; i < 12; i++) {

// 30° 分を描画する
fill(ctx, x, y, radius, angle, angle + 30, colors[i]);

// 次回描画用に 30° 加算する
angle += 30;
}

黄色の円弧の中心を一番上にしたいために 255° という中途半端な角度から開始しています。

270 - (30 / 2) ってことですね。


5. 真ん中を白い円でくり抜こう

くり抜くというか、白い小さな円弧を上から描画しているだけです。

fill(ctx, x, y, radius / 2, 0, 360, '#FFFFFF');

半径を 1 / 2 して 360° まるっと描画しています。


色相環出来ました!

CodePen :pencil2: にUPしてみました!

描画の様子がわかりやすいように、1色ずつ止めながら描画させています。

See the Pen HueCircle by あずきしろもち (@azukisiromochi) on CodePen.


おわりに

canvas を直接利用したのは初めてでしたが、なんとか出来ました。

座標を扱うので少しとっつきにくい感じはしますが、慣れれば便利なのかな~ :thinking::question:

ちなみに arc 関数使っているところを lineTo 関数に変えてやれば正多角形が作れたりもします。

座標計算がそれこそしんどいけど

こんどは CSS で作ってみようかな! :yum:





  1. マンセル・カラー・システム (Munsell color system) とは、色を定量的に表す体系である表色系の1つ。色彩を色の三属性(色相、明度、彩度)によって表現する。マンセル表色系、マンセル色体系、マンセル システムとも言う。 



  2. ある色の残像として現われる色をその色の心理補色(または生理補色)と呼ぶ。例えば赤をしばらく見たあとに、白紙に目を移すと見える青緑が該当する。