|
| 1 | +# Three.jsでの最適なリサイズ処理 |
| 2 | + |
| 3 | +Three.jsでの最適なリサイズ処理の方法を紹介します。この手順を覚えれば次のような希望に対応できます。 |
| 4 | + |
| 5 | +- どんなディスプレイでもThree.jsを綺麗に見せたい |
| 6 | +- 異なるディスプレイでも全画面に3Dを表示させたい |
| 7 | +- ブラウザのサイズを変更してもThree.jsを全画面にフィットさせたい |
| 8 | + |
| 9 | +## リサイズのサンプル |
| 10 | + |
| 11 | +- [サンプルを再生する](https://ics-creative.github.io/tutorial-three/samples/renderer_resize.html) |
| 12 | +- [サンプルのソースコードを確認する](../samples/renderer_resize.html) |
| 13 | + |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | + |
| 21 | + |
| 22 | +## 設定方法 |
| 23 | + |
| 24 | +### HTMLのメタタグ |
| 25 | + |
| 26 | +HTMLの`meta`タグに`viewport`の設定をします。 |
| 27 | + |
| 28 | +```html |
| 29 | +<meta name="viewport" content="width=device-width, initial-scale=1"/> |
| 30 | +``` |
| 31 | + |
| 32 | +スマートフォンのブラウザには横幅の大きなPCサイトも柔軟に見れるように自動的に拡大縮小する機能があります。WebGLを綺麗に見せたいときには、その機能が余計な処お世話となります。 |
| 33 | + |
| 34 | +`width=device-width`と指定することでデバイスの最適な幅で表示させるようにします。また、初期状態で拡大・縮小していない見え方にするために`initial-scale=1`を指定します。 |
| 35 | + |
| 36 | +### スタイルシート |
| 37 | + |
| 38 | +`body`タグに余白が存在するので、それを消すように`margin: 0`を指定します。 |
| 39 | + |
| 40 | +```html |
| 41 | +<style> |
| 42 | + body { |
| 43 | + margin: 0; |
| 44 | + overflow: hidden; |
| 45 | + } |
| 46 | +</style> |
| 47 | +``` |
| 48 | + |
| 49 | +また、`overflow: hidden`を指定すると、macOSのデスクトップブラウザのオーバースクロール(例えば画面上部にスクロールすると、画面上部を一瞬超えて表示される挙動)を抑制できます。全画面コンテンツを作るときにオーバースクロールの挙動は余計なお世話なので、`overflow: hidden`を指定しておきましょう。 |
| 50 | + |
| 51 | +### Three.jsの調整 |
| 52 | + |
| 53 | +`resize`イベントを監視し、画面サイズである`window.innerWidth`と`window.innerHeight`の値を使います。 |
| 54 | + |
| 55 | +```js |
| 56 | +// 初期化のために実行 |
| 57 | +onResize(); |
| 58 | +// リサイズイベント発生時に実行 |
| 59 | +window.addEventListener('resize', onResize); |
| 60 | + |
| 61 | +function onResize() { |
| 62 | + // サイズを取得 |
| 63 | + const width = window.innerWidth; |
| 64 | + const height = window.innerHeight; |
| 65 | + |
| 66 | + // レンダラーのサイズを調整する |
| 67 | + renderer.setPixelRatio(window.devicePixelRatio); |
| 68 | + renderer.setSize(width, height); |
| 69 | + |
| 70 | + // カメラのアスペクト比を正す |
| 71 | + camera.aspect = width / height; |
| 72 | + camera.updateProjectionMatrix(); |
| 73 | +} |
| 74 | +``` |
| 75 | + |
| 76 | +実装のポイントは次の通りです。 |
| 77 | + |
| 78 | +- リサイズ時にはレンダラーのサイズを`setSize`メソッドで画面幅に合わせること |
| 79 | +- デスクトップでは、メインディスプレイ・サブディスプレイでPixelRatioが異なる可能性があるので、リサイズイベントで`setPixelRatio`メソッドで更新するべき |
| 80 | +- リサイズ時にはカメラの縦横比が狂うので、リサイズ時に縦横比を正しく調整する |
| 81 | +- 画面サイズの設定処理は、初期化時もリサイズ時も同じ |
| 82 | + - `onResize`関数は初期化時とリサイズイベント発生の両方で呼び出す |
| 83 | + |
| 84 | + |
| 85 | +以上となります。詳しくはサンプルのコードをコピーするなどして取り組んでください。 |
| 86 | + |
| 87 | +<article-author>[池田 泰延](https://twitter.com/clockmaker)</article-author> |
| 88 | +<article-date-published>2017-11-16</article-date-published> |
| 89 | +<article-date-modified>2017-11-16</article-date-modified> |
0 commit comments