Chapter 52

ゲージ

miku
miku
2021.11.16に更新

この章ではロードの割合を表示するときに利用されるゲージの作り方について扱う。

他の利用例としては、今流している動画の割合をゲージとして表示したり、スライドショーで次のスライドに切り替わる時間の割合、ゲームのプレイヤーや敵の体力を表示するなどがある。

ゲージの作り方

結局の所、ゲージというのは値が最大値に比べてどれだけの量が残っているのかの割合を棒で表現しているものになる。

const maxValue = 100;
let value;

必要なものはまず最大値と現在値だ。

const ratio = value / maxValue;

現在地を最大値で割って正規化を行い0~1の範囲に変換する。

const gaugeWidth = gaugeMaxWidth * ratio;

あとはゲージの最大の長さに割合を掛ければ今の値に応じたゲージを長さを作ることができる。

const maxValue = 100;
let value, gauge;

function setup() {
  createCanvas(windowWidth, windowHeight);
  value = 0;
  gauge = Gauge.init(10, height / 2 - 5, width - 20, 10, value, maxValue, "#f0f0f0", "#ed1a3d");
}

function draw() {
  clear();
  Gauge.updateValue(gauge, value);
  Gauge.draw(gauge);

  value++;
  value %= (maxValue + 30);
}

const Gauge = {
  init: function (x, y, width, height, value, maxValue, bgColor, frontColor) {
    return { x, y, width, height, value, maxValue, bgColor, frontColor };
  },

  updateValue(gauge, value) {
    gauge.value = constrain(value, 0, gauge.maxValue);
    gauge.ratio = gauge.value / gauge.maxValue;
  },

  updateRatio(gauge, ratio) {
    gauge.ratio = constrain(gauge.maxValue * ratio, 0, 1);
    gauge.value = galue.maxValue * gauge.ratio;
  },

  draw: function (gauge) {
    fill(gauge.bgColor);
    rect(gauge.x, gauge.y, gauge.width, gauge.height);

    fill(gauge.frontColor);
    rect(gauge.x, gauge.y, gauge.width * gauge.ratio, gauge.height);
  },
};

Gauge.init() でゲージを作るための情報を渡し、オブジェクトを受け取る。画面の描画は Gauge.draw() を呼び出せばいいので、この関数を draw() にでも書いておけばいい。値の更新は Gauge.updateValue() か、割合を直接指定する updateRatio() で行う。一応、範囲外の値を指定された場合は constrain() でクランプを行うように調整している。

ゲージを分割する

const maxValue = 300;
let value, gauge;

function setup() {
  createCanvas(windowWidth, windowHeight);
  value = 0;
  gauge = Gauge.init(10, height / 2 - 5, width - 20, 10, 10, value, maxValue, "#f0f0f0", "#ed1a3d");
}

function draw() {
  clear();
  Gauge.updateValue(gauge, value);
  Gauge.draw(gauge);

  value++;
  value %= (maxValue + 30);
}

const Gauge = {
  init: function (x, y, width, height, blockNum, value, maxValue, bgColor, frontColor) {
    return { x, y, width, height, blockNum, value, maxValue, bgColor, frontColor };
  },

  updateValue(gauge, value) {
    gauge.value = constrain(value, 0, gauge.maxValue);
    gauge.ratio = gauge.value / gauge.maxValue;
  },

  updateRatio(gauge, ratio) {
    gauge.ratio = constrain(gauge.maxValue * ratio, 0, 1);
    gauge.value = galue.maxValue * gauge.ratio;
  },

  draw: function (gauge) {
    fill(gauge.bgColor);

    fill(gauge.frontColor);
    const num = floor(map(gauge.value, 0, gauge.maxValue, 0, gauge.blockNum));
    for (let i = 0; i < num; i++) {
      const blockWidth = gauge.width / gauge.blockNum;
      rect(gauge.x + blockWidth * i, gauge.y, blockWidth, gauge.height);
    }
  },
};

イージングを付ける

ゲージをローディング表示などで使用する際、後半になると速くなるように調整する場合がある。そのためにイージングを使用したい。

let ratio;
let gauge1, gauge2;

function setup() {
  createCanvas(windowWidth, windowHeight);
  ratio = 0;
  gauge1 = Gauge.init(10, height / 2 - 20, width - 20, 10, 0, 1, "#f0f0f0", "#ed1a3d");
  gauge2 = Gauge.init(10, height / 2 - 5 + 40, width - 20, 10, 0, 1, "#f0f0f0", "#ed1a3d");
}

function draw() {
  clear();
  Gauge.updateRatio(gauge1, ratio);
  Gauge.updateRatio(gauge2, easing(ratio));
  Gauge.draw(gauge1);
  Gauge.draw(gauge2);

  ratio += 0.01;
  ratio %= 1.5;
}

function easing(t) {
  return t * t;
}

const Gauge = {
  init: function (x, y, width, height, value, maxValue, bgColor, frontColor) {
    return { x, y, width, height, value, maxValue, bgColor, frontColor };
  },

  updateValue(gauge, value) {
    gauge.value = constrain(value, 0, gauge.maxValue);
    gauge.ratio = gauge.value / gauge.maxValue;
  },

  updateRatio(gauge, ratio) {
    gauge.ratio = constrain(gauge.maxValue * ratio, 0, 1);
    gauge.value = gauge.maxValue * gauge.ratio;
  },

  draw: function (gauge) {
    fill(gauge.bgColor);
    rect(gauge.x, gauge.y, gauge.width, gauge.height);

    fill(gauge.frontColor);
    rect(gauge.x, gauge.y, gauge.width * gauge.ratio, gauge.height);
  },
};