Chapter 28

グラデーション

miku
miku
2021.11.12に更新

グラデーション

function setup() {
  createCanvas(windowWidth, windowHeight);
  noStroke();

  for (let x = 0; x < width; x++) {
    fill(map(x, 0, width, 0, 255), 0, 0);
    rect(x, 0, 1, height);
  }
}

x座標の値が大きいほどそのピクセルの赤色の値を増やす作例。

x の範囲は 0 ~ width、赤色の範囲は 0~255 なので、map(x, 0, width, 0, 255) で変換を行う。x / width * 255 でもいい。他にも colorMode(RGB, width) で色の最大値を width にして fill(x, 0, 0) と書くこともできる。

ピクセル単位で描いてもいいが、縦のラインの色がすべて同じなので rect() を使用している。

function setup() {
  createCanvas(windowWidth, windowHeight);
  noStroke();

  for (let x = 0; x < width; x++) {
    fill(map(x, 0, width, 255, 0), 0, 0);
    rect(x, 0, 1, height);
  }
}

今度は逆に x の値が大きいほど赤色の値が減っていく作例。255 - x / width * 255 でもいい。

段階を分ける

function setup() {
  createCanvas(windowWidth, windowHeight);
  noStroke();

  const n = 10;
  const step = width / n;

  for (let x = 0; x < width; x++) {
    fill(map(floor(x / step), 0, n - 1, 0, 255), 0, 0);
    rect(x, 0, 1, height);
  }
}

先程と同様にx座標の値が大きいほど赤色の値が増えていくが、n 種類のグラデーションに分ける作例。

まず width / n で段階あたりの幅を求めたものを step とする。x / step0 以上 n 未満の値が出てくる。たとえば 1.51.7 のようになるが、これを floor() で小数点以下を切り捨て 1 にする。これで 0~n-1 のグループができるので map() を利用して赤の範囲に変換する。

軸ごとに色を分ける

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(0);
  loadPixels();

  for (let y = 0; y < height; y++) {
    for (let x = 0; x < width; x++) {
      const c = [(x / width) * 255, (y / height) * 255, 0];
      setPixel(x, y, c);
    }
  }

  updatePixels();
}

function setPixel(x, y, c) {
  const i = (y * width + x) * 4;
  pixels[i + 0] = c[0];
  pixels[i + 1] = c[1];
  pixels[i + 2] = c[2];
}

x座標の値が増えるほど赤色が、y座標の値が増えるほど緑色が増える作例。

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(0);
  loadPixels();

  for (let y = 0; y < height; y++) {
    for (let x = 0; x < width; x++) {
      const c = [(y / height) * 255, (x / width) * 255, (x / width) * 255];
      setPixel(x, y, c);
    }
  }

  updatePixels();
}

function setPixel(x, y, c) {
  const i = (y * width + x) * 4;
  pixels[i + 0] = c[0];
  pixels[i + 1] = c[1];
  pixels[i + 2] = c[2];
}

x座標の値が増えるほど緑色と青色が、y座標の値が増えるほど赤色が増える作例。

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(0);
  colorMode(HSB, width, height, 1);
  loadPixels();

  for (let y = 0; y < height; y++) {
    for (let x = 0; x < width; x++) {
      // 色相と彩度の最大値を(width, height)にしているので(x, y)と直接指定できる
      const c = color(x, y, 1);
      setPixel(x, y, [red(c), green(c), blue(c)]);
    }
  }

  updatePixels();
}

function setPixel(x, y, c) {
  const i = (y * width + x) * 4;
  pixels[i + 0] = c[0];
  pixels[i + 1] = c[1];
  pixels[i + 2] = c[2];
}

x座標の値が増えるほど色相が、y座標の値が増えるほど彩度が増える作例。

function setup() {
  createCanvas(windowWidth, windowHeight);
  colorMode(HSB);
}

function draw() {
  for (let i = 0; i < 10; i++) {
    const tx = random(width);
    const ty = random(height);

    fill((ty / height) * 360, 100, 100);
    circle(tx, ty, random(10, 60));
  }
}

毎フレーム、円をランダムな位置に描画するが、y座標に応じて、円の色相を変化させる作例。