1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【完走賞ゲット-21】p5.js で描画する複数の色でのグラデーション:chroma.js を使った方法と drawingContext.createLinearGradient を使った方法の比較

Posted at

はじめに

こちらは、完走賞ゲットのため小ネタを毎日投稿しようとチャレンジする Advent Calendar 2022 の 21日目の記事です。

内容は、以下の記事で扱った chroma.js を使ったカラースケールに関する話です。

●【JavaScript 2022】chroma.js を使った複数色のカラースケールでカラーパレットを生成して p5.js で描画(chroma.bezier() や chroma.scale() の scale.correctLightness() などを利用) - Qiita
 https://qiita.com/youtoy/items/6b1f11238a76e327d078

上記の記事では、カラースケールからカラーパレットを生成しましたが、この記事では複数の色を使った線形のグラデーションを描画するのに利用してみようと思います。また、線形のグラデーションを描画する方法に drawingContext.createLinearGradient を使った方法もありますが、それとの比較もやってみます。

chroma.js を使った複数色のカラースケールからグラデーションを描画

上で掲載していた前の記事で、カラーパレットを作る場合は、指定した数の色を取り出すというのを scale.colors() を使ってやりました。

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

グラデーションを描画する場合、この部分を「指定の割合の値から色を取得する」ということをやります。そのためには、 out("hex") というのが利用できるようです。
※ 情報源 ⇒ https://fukuno.jig.jp/3743

具体的にソースコードで書くと、以下のとなります。

カラーパレット用の色指定
const colorList = ["white", "yellow", "blue", "black"];

chroma.scale(colorList).mode("rgb").colors(10),
  chroma.scale(colorList).mode("rgb").correctLightness().colors(10),
グラデーション用の色指定
const colorList = ["white", "yellow", "blue", "black"];

const outputColors = [
  chroma.scale(colorList).mode("rgb").out("hex"),
  chroma.scale(colorList).mode("rgb").correctLightness().out("hex"),
];

グラデーションの描画: 3種類

以下は、グラデーションを 3つの方法で描画してみたものです。

グラデーションの描画: 3種類

上記のグラデーションは、それぞれ以下の方法で描画しています。また、グラデーションの元になる色は、共通のものを用いました。

  1. chroma.scale() を利用
  2. 上記に scale.correctLightness() を追加
  3. drawingContext.createLinearGradient() を利用し、真横へグラデーションを作成

ソースコードも掲載しておきます。

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

const outputColors = [
  chroma.scale(colorList).mode("rgb").out("hex"),
  chroma.scale(colorList).mode("rgb").correctLightness().out("hex"),
];

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

function draw() {
  background(220);

  for (i = 0; i < width; i++) {
    noFill();
    stroke(outputColors[0](map(i, 0, width, 0, 1)));
    line(i, 30, i, 110);
  }

  for (i = 0; i < width; i++) {
    noFill();
    stroke(outputColors[1](map(i, 0, width, 0, 1)));
    line(i, 130, i, 210);
  }

  noStroke();
  fill(255);
  let gradient = drawingContext.createLinearGradient(0, 180, width, 180);

  for (let i = 0; i < colorList.length; i++) {
    const ratio = map(i, 0, colorList.length - 1, 0, 1);
    gradient.addColorStop(ratio, colorList[i]);
  }

  drawingContext.fillStyle = gradient;
  rect(0, 250, width, 80);
}

比較結果

chroma.scale() を利用したものと、 drawingContext.createLinearGradient() を利用したものは、同じ結果を得られました。

また、 chroma.scale()scale.correctLightness() を追加したものは、カラースケールに補正がかかっているため、他の 2つとは異なる結果になりました。

その他の書き方: hex() を使う

上記のプログラムで、 chroma.scale() を使った方法では、以下のようなやり方でした。

out() を使う方法
const colorList = ["white", "yellow", "blue", "black"];

const outputColors = [
  chroma.scale(colorList).mode("rgb").out("hex"),
  ...,
];
...
    stroke(outputColors[1](map(i, 0, width, 0, 1)));
...

これは、以下のような書き方もできるようです。

hex() を使う方法
const colorList = ["white", "yellow", "blue", "black"];

const outputColors = [
  chroma.scale(colorList).mode("rgb"),
  ...,
];
...
    stroke(outputColors[0](map(i, 0, width, 0, 1)).hex());
...
1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?