LoginSignup
3
1

More than 1 year has passed since last update.

【JavaScript 2022】chroma.js を使った複数色のカラースケールでカラーパレットを生成して p5.js で描画(chroma.bezier() や chroma.scale() の scale.correctLightness() などを利用)

Last updated at Posted at 2022-12-19

はじめに

この記事は、JavaScript Advent Calendar 2022 の 20日目の記事です。

内容は、過去に以下の記事でも扱った chroma.js の話です。

●chroma.js を使った HSB(HSV) と16進数カラーコードの変換やその他の処理を p5.js Web Editor上で試す - Qiita
 https://qiita.com/youtoy/items/513009ebfdd04872e059

もう少し補足すると、以下の記事に出てくる chroma.js での複数の色を使ったカラースケールの話と、p5.js でカラーパレットを使う話とを組み合わせた内容になります。

●Mastering Multi-hued Color Scales with Chroma.js
 https://www.vis4.net/blog/2013/09/mastering-multi-hued-color-scales/
Combining Bezier interpolation and lightness correction

複数の色を使ったカラースケール

上で掲載していた「Mastering Multi-hued Color Scales with Chroma.js」という記事で、複数の色を使ったカラースケールの話について書かれています。

細かな話は省略しますが、その話の中で、複数の色を使ったカラースケールを改善するための方法について説明されています。
そして、chroma.js の「chroma.bezier()」や「chroma.scale() + scale.correctLightness()」を使った話が出てきていました。これらを使うと、複数の色を使ったスケールの結果を、良い感じにできるようです。
※ 自分が色の理論にそこまで詳しくないので、ざっくりな内容しか把握できてないのですが...

その話が気になったので、具体的にどんな結果が得られるかを、普段よく使っている p5.js を使って確かめてみる、というのが、これ以降の内容です。
(そして、良い感じのカラーパレットが生成できたら、今後、活用していけそうかなという思いもあり...)

chroma.js関連の話

以下で、今回利用する chroma.js の機能の、公式情報を見ていきます。

chroma.scale()

指定した 2色以上の色で、カラースケールを作成できます。色指定をしない場合、デフォルトは白黒の 2色になるようです。
https://gka.github.io/chroma.js/#chroma-scale
chroma.scale()

scale.mode()

カラースケールのモードを切り替えるもので、デフォルトは RGB ですが、HSL など他のものに変更することができます。
https://gka.github.io/chroma.js/#scale-mode
image.png

scale.colors()

カラースケールから、数字指定で色を取り出すためのものです。
https://gka.github.io/chroma.js/#scale-colors
scale.colors()

scale.correctLightness() と chroma.bezier()

上に掲載した記事で出てきた、複数の色のカラースケールを作成する際に、良い感じの出力を得るために用いられていたものです。

https://gka.github.io/chroma.js/#scale-correctlightness
scale.correctLightness()

https://gka.github.io/chroma.js/#chroma-bezier
image.png

生成した色を p5.js で描画してみる

ここから、chroma.js でカラースケールを生成し、そこから色を取り出してカラーパレットを作るというのをやってみます。さらに、そのカラーパレットを使った描画を、p5.js を用いて行います。

p5.js で得た出力

まずは、p5.js で得た出力を掲載してみます。
生成した色を p5.js で描画
6パターンのカラーパレットがありますが、補足などを以下で書いていきます。

出力の全てに共通の内容: 元にした色と出力した色の数

カラースケールを作成する際、元になる色として指定した内容を、ソースコードベースで示します。以下のように、「白・黄色・青・黒」の 4色を、元になる色として指定しました。

const colorList = ["white", "yellow", "blue", "black"];

また、出力する色の数は 10色としました。

const outputColorNum = 10;

出力の上 2つ

最初に、以下の 2つについて補足します。
出力の上 2つ

chroma.scale().mode("rgb") で得た出力と、scale.correctLightness() を加えたものの 2つです。scale.correctLightness() を加えたことで、左半分の色の変化の段階が、はっきりした感じになりました。

  chroma.scale(colorList).mode("rgb").colors(outputColorNum), 
  chroma.scale(colorList).mode("rgb").correctLightness().colors(outputColorNum),

出力の真ん中の 2つ

次に、以下の 2つについて補足します。
出力の真ん中の 2つ

chroma.scale().mode("hsl") で得た出力と、scale.correctLightness() を加えたものの 2つです。上の事例とは異なり、scale.correctLightness() を加えたことで、左半分の出力がずいぶん異なるものになりました。

  chroma.scale(colorList).mode("hsl").colors(outputColorNum),
  chroma.scale(colorList).mode("hsl").correctLightness().colors(outputColorNum),

出力の下 2つ

最後に、以下の 2つについて補足します。
出力の下 2つ

chroma.bezier().scale() で生成したカラースケールと、それに scale.correctLightness() を加えたものとなっています。左端から真ん中あたりの色が少し補正されているのが分かります。

   chroma.bezier(colorList).scale().colors(outputColorNum),
  chroma.bezier(colorList).scale().correctLightness().colors(outputColorNum),

ただ、他の事例と比べると、補正の影響が大きくはないようです。
このあたりは、元にする色の組み合わせなどで変わるのか、chroma.bezier().scale() を使うとこういった感じになるのか、そのあたりを判断するにはもう少しお試しをする必用がありそう...

p5.js Web Editor上での実装

最後に、上で掲載した出力を得るために、p5.js Web Editor上で作った内容を掲載します。CSS は特に変更してないため、HTML と JavaScript のファイルの内容のみ掲載します。

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.4.2/chroma.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css" />
    <meta charset="utf-8" />
  </head>
  <body>
    <main></main>
    <script src="sketch.js"></script>
  </body>
</html>
const outputColorNum = 10;

const colorList = ["white", "yellow", "blue", "black"];

const outputColorList = [
  chroma.scale(colorList).mode("rgb").colors(outputColorNum), 
  chroma.scale(colorList).mode("rgb").correctLightness().colors(outputColorNum),
  chroma.scale(colorList).mode("hsl").colors(outputColorNum),
  chroma.scale(colorList).mode("hsl").correctLightness().colors(outputColorNum),
   chroma.bezier(colorList).scale().colors(outputColorNum),
  chroma.bezier(colorList).scale().correctLightness().colors(outputColorNum),
];

function setup() {
  createCanvas(400, 350);
  noStroke();
}

function draw() {
  background(220);

  const size = width / outputColorNum;

  for (i = 0; i < outputColorList.length; i++) {
    for (j = 0; j < outputColorNum; j++) {
      fill(outputColorList[i][j]);
      rect(
        (j * width) / outputColorNum,
        height * (0.05 + i * 0.16),
        size,
        size
      );
    }
  }
}

あと上記を試した後に、「塗りつぶしの部分で透明度を設定する」というのもやってみました。

fill(outputColorList[i][j]);`
         ↓
`fill(`${outputColorList[i][j]}aa`);`
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1