Chapter 10

レスポンシブデザイン

miku
miku
2021.11.10に更新

閲覧する側の画面サイズは多種多様なので、描画によっては画面からはみ出てしまう可能性がある。この章ではそのことについて、どのように対応するかの方法について扱う。

問題の分別

描画が画面からはみ出るといっても、理由は複数あり、一つ一つ原因を挙げて対応していく必要がある。

ここでは大きく分けて3つの原因があると考える。

  • Canvasがブラウザの表示枠からはみ出ている
  • 座標がCanvasの領域からはみ出ている
  • 形状の一部分がCanvasからはみ出ている

Canvasの調整

まずは、描画の土台となるCanvasがブラウザの表示からはみ出ている場合だ。対応方法として、CSSによる調整が考えられる。

canvas {
  width: 100%;
  height: auto;
}

たとえばこのように書いて対応する方法もあるが、createCanvas() で指定した幅と高さがCanvasの width, height, style に直接書き込まれる仕様になっているので、!important と併用しないと適用の優先順位の関係でうまく動作しない。

このため、Canvasの生成と同じく、Canvasのレスポンシブ対応もp5.js側で行いたい。

function setup() {
  createCanvas(windowWidth, windowHeight);
  reset();
}

function reset() {
}

function draw() {
}

function windowResized() {
  // createCanvas() で生成したCanvasのサイズを変更する
  resizeCanvas(windowWidth, windowHeight);
  reset();
}

常にブラウザの画面サイズに合わせてCanvasを広げる作例。

画面サイズが変更されるたびに windowResized() が呼ばれる。そのたびに resizeCanvas() でCanvasのサイズを改めて画面サイズに合わせておく。

画面サイズが変更されると今表示している描画が切れてしまう可能性があるので、この際、表示をクリアして、初めから描画をやり直したい。たとえば setup() を改めて呼び出すという方法が考えられるが、これにはいくつか問題がある。

1つ目は createCanvas() が多重に呼び出されることだ。一応、多重に呼び出してもCanvasが複数作られないようにできてはいるが、resizeCanvas() という専用のリサイズ関数がある以上、できるだけこちらを使いたい。

2つ目は、必ずしも1回目の実行と、2回目以降のやり直しコードが共通するとは限らないということだ。

上記の理由から、setup() とは別にリセット用の関数を作っておきたい。

ここで reset() という関数を用意しよう。そこにやり直すコードを書けばいい。なんなら setup() と共通している部分はすべて reset() に移して、setup() からも reset() を呼び出せば無駄がない。

座標の調整

circle(300, 300, 500);

座標をピクセル単位で指定すると、画面からはみ出る可能性がある。

対処方法としては、たとえば横だけで見ると、画面横幅である width より小さい位置であれば、はみ出ることはないので、width に依存した位置にすればいい。つまり、幅や高さの割合で座標を調整する。

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

  circle(width / 2, height / 2, 100);
}

これまでに何度も出てきた、画面中央に表示するというのは座標の調整の代表例だ。

座標の調整の作例

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

  circle(width / 4, height / 2, 50);
  circle((width / 4) * 2, height / 2, 50);
  circle((width / 4) * 3, height / 2, 50);
}

複数のオブジェクトを等間隔に並べる作例。詳細は後の章で扱う。

座標の調整の作例 その2

function setup() {
  createCanvas(windowWidth, windowHeight);
  stroke(240);
  noFill();

  line(width * 0.1, height * 0.1, width * 0.9, height * 0.9);
}

画面の10%から90%の位置まで線を引く作例。

大きさの調整

点以外の描画には幅があるので、座標が画面内にあっても、描画の一部分が画面外にはみ出る可能性がある。この場合は、座標と同じように画面の幅、高さに依存して大きさを決めればいい。

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

  const d = min(width, height);
  circle(width / 2, height / 2, d);
}

円を中央に配置して画面内に描画を収めたい場合、画面の縦横短いほうが円の直径の最大サイズになる。

次に複数の円を配置した場合、どう対応するのかを考える。

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

  const w = width / 2;
  const h = height / 2;

  drawCircle(0, 0, w, h);
  drawCircle(w, 0, w, h);
  drawCircle(0, h, w, h);
  drawCircle(w, h, w, h);
}

function drawCircle(x, y, width, height) {
  circle(x + width / 2, y + height / 2, min(width, height));
}

まず、円を描く部分を切り出し、新しい関数内に移動する。そしてその関数の引数には座標と幅・高さを渡す。

この引数に渡された範囲を新たな画面だと思い、この範囲からはみ出ないように描画すれば、結果全体もはみ出ないことになる。

左上が (x, y) から始まるので、中央が (x + width / 2, y + height / 2)(x, y) の下駄を履かせる形になるが、これは面倒な指定なのでなんとかしたい。詳細は次の章で扱う。