ICS MEDIA - インタラクションデザイン×ウェブテクノロジー

WebGL と JavaScript で学ぶ3D表現

Three.jsでの最適なリサイズ処理

Three.jsでの最適なリサイズ処理の方法を紹介します。この手順を覚えれば次のような希望に対応できます。

  • どんなディスプレイでもThree.jsを綺麗に見せたい
  • 異なるディスプレイでも全画面に3Dを表示させたい
  • ブラウザのサイズを変更してもThree.jsを全画面にフィットさせたい

リサイズのサンプル

設定方法

HTMLのメタタグ

HTMLのmetaタグにviewportの設定をします。

<meta name="viewport" content="width=device-width, initial-scale=1"/>

スマートフォンのブラウザには横幅の大きなPCサイトも柔軟に見れるように自動的に拡大縮小する機能があります。WebGLを綺麗に見せたいときには、その機能が余計な処お世話となります。

width=device-widthと指定することでデバイスの最適な幅で表示させるようにします。また、初期状態で拡大・縮小していない見え方にするためにinitial-scale=1を指定します。

スタイルシート

bodyタグに余白が存在するので、それを消すようにmargin: 0を指定します。

<style>
  body {
    margin: 0;
    overflow: hidden;
  }
</style>

また、overflow: hiddenを指定すると、macOSのデスクトップブラウザのオーバースクロール(例えば画面上部にスクロールすると、画面上部を一瞬超えて表示される挙動)を抑制できます。全画面コンテンツを作るときにオーバースクロールの挙動は余計なお世話なので、overflow: hiddenを指定しておきましょう。

Three.jsの調整

resizeイベントを監視し、画面サイズであるwindow.innerWidthwindow.innerHeightの値を使います。

// 初期化のために実行
onResize();
// リサイズイベント発生時に実行
window.addEventListener('resize', onResize);

function onResize() {
  // サイズを取得
  const width = window.innerWidth;
  const height = window.innerHeight;

  // レンダラーのサイズを調整する
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);

  // カメラのアスペクト比を正す
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
}

実装のポイントは次の通りです。

  • リサイズ時にはレンダラーのサイズをsetSizeメソッドで画面幅に合わせること
  • デスクトップでは、メインディスプレイ・サブディスプレイでPixelRatioが異なる可能性があるので、リサイズイベントでsetPixelRatioメソッドで更新するべき
  • リサイズ時にはカメラの縦横比が狂うので、リサイズ時に縦横比を正しく調整する
  • 画面サイズの設定処理は、初期化時もリサイズ時も同じ
    • onResize関数は初期化時とリサイズイベント発生の両方で呼び出す

以上となります。詳しくはサンプルのコードをコピーするなどして取り組んでください。