Three.jsのリサイズ対応の実装で少し迷うことがあったのでメモ。
サンプルコード
まずは対応前の状態です。
import * as THREE from 'three'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setAnimationLoop( animate ); document.body.appendChild( renderer.domElement ); const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); camera.position.z = 5; function animate() { cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); }
ページアクセス後に画面を狭めた際、canvasのサイズが変更されないため横スクロールバーが表示されます。
対応前のデモページ
setSize()でレンダラーのサイズの変更と、aspectでカメラのアスペクト比の変更を行います。
import * as THREE from 'three'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setAnimationLoop( animate ); document.body.appendChild( renderer.domElement ); const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); camera.position.z = 5; function animate() { cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } window.addEventListener('resize', resize_canvas); function resize_canvas() { const w = window.innerWidth; const h = window.innerHeight; // サイズの変更 renderer.setSize(w, h); camera.aspect = w / h; camera.updateProjectionMatrix(); }
カメラの設定変更時の注意点として、updateProjectionMatrix()を呼び出して変更を有効にする必要があるようです。
対応後のデモページ
コメントが承認されるまで時間がかかります。