色の変化 – 日本語で書くアニメーションプログラム

このシリーズではアニメーションのためのプログラムを日本語に置き換えて解説します。
プログラムとして書かれた数式を日本語にすることで言語の仕様に依存しない「なぜそのように動くか?」という理解の一助となればと思います。

※私がWeb制作を生業にするフロントエンドエンジニアなのでプログラムの箇所はPixiJSで記述しています。

プログラムを日本語に。

色の変化は日本語で書くと、以下のような書き方で実装出来ます。これまでの座標や回転を用いるものに比べて、色関係はプログラムやライブラリによる差異がやや大きいですが、理屈は一緒なので読み解いていきましょう。

色相の値 = 0

アニメーションさせるためのループ処理{
 色相の値 += 1
 条件分岐( 色相の値 > 360 ){ 色相の値 = 0 }
 オブジェクトに設定する色 = 適切な色空間へ変換する関数(HSL色空間(色相の値,80,50))
 オブジェクトの色プロパティ = オブジェクトに設定する色
}

これを実際のプログラムで書くとこうなります。
※アニメーションに関係ない記述に関しては一部割愛しています。

// HSL色空間をRGBの16進数コードへと変換する関数
const hslToRgb16 = function(hue, saturation, lightness) {
  /* 〜中略〜 */
}

// 動かすオブジェクトを定義
let obj = new PIXI.Graphics();
obj.beginFill(0xFFFFFF, 1);
obj.drawRoundedRect(0, 0, 100, 100, 16);
obj.endFill();
obj.pivot.x = 50;
obj.pivot.y = 50;

let  hue = 0;

app.ticker.add((delta) => {
  hue += 1;
  if(hue > 360){hue=0;}
  const color = '0x'+hslToRgb16(hue,80,50);

  // .tintでGraficsの色を設定出来る。
  obj.tint = color;
});

これを上から順番に日本語にするとこうなります。

HSL色空間をRGBの16進数コードへと変換する変換関数を定義

オブジェクト名 = オブジェクトの入れ物を作成
オブジェクト.色の塗りつぶし(白,透明度)
オブジェクト.角丸の四角を作成(x座標, y座標, 横幅, 縦幅, 角丸サイズ)
オブジェクト.色の塗りつぶし終了
オブジェクト.中心点x = オブジェクトの幅の半分
オブジェクト.中心点y = オブジェクトの高さの半分

色相の値 = 0

アニメーションさせるためのループ処理{
 色相の値 += 1
 条件分岐( 色相の値 > 360 ){ 色相の値 = 0 }
 オブジェクトに設定する色 = 色変換関数(HSL色空間(色相の値,80,50))
 オブジェクトの色プロパティ = オブジェクトに設定する色
}

色の変化で一番大事なのはコードそのものより色をアニメーションさせるとはどういう事かという考え方かもしれません。

プログラミングで色を扱う場合には、RGB、RGB16進数、HSV、HSLなど様々な色空間の指定方法があります。

しかし今回のように隣接した色へのなめらかな変化を行う場合、直感的にわかりやすいRGB(red、green、blue)やCSSでお馴染みのRGB16進数で行うのは現実的には難しい。

こういう場合はHSV(色相、彩度、明度)やHSL(色相、彩度、輝度)といった色相を指定する色空間を使うと綺麗な変化を実装することが出来ます。
色相とは色味を数値として表すもので、大雑把に言うと赤>黄>緑>青>紫>赤という円状の環として表される図が有名です。

つまり色相の値(大抵の場合0〜360が入る)を描画ループの度に加算もしくは減算していく、というのが色変化のアニメーションの肝となります。

この色相の変化が一番劇的なのでピックアップしましたが、例えば色相の代わりに彩度を変化させれば、鮮やかな色がだんだん色褪せたり、明度をいじればだんだん暗くなるといった描写を行う事が出来ます。

また、色の操作で厄介なのは前述したように色空間の指定はプログラムやライブラリによって違い、都度どのような指定が必要か調べる必要があります。
そしてRGBやRGB16進数でしか色の指定を受け付けていない場合、HSVやHSLの色空間から適切な色空間へと変換する関数が必要になります。そういった関数については、デフォルトで実装されている事もあればネット上で公開されているライブラリやコードもいくつもあります。自分で使いやすいコードを見極めて使うのが良いでしょう。

ちなみに僕はこちらのサイトのコードを参考にさせて頂きました!
HSLから16進数RGBへ変換