Three.jsにはカメラの動きを自動的に制御する OrbitControls
クラスが存在します。
次の用途で役立つ機能です。
- 周回軌道を描くように、カメラを配置する
- ポインター操作でカメラの配置やアングルを変更する
導入方法
OrbitControls.js
は、Three.jsライブラリの本体に含まれていないので注意が必要です。CDNで利用するときは、以下のimportmap
を記載して、three/addons/
というエイリアスを貼ります。
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.167.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.167.0/examples/jsm/"
}
}
</script>
処理のほうではimport
文で読み込みます。
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// …
</script>
※公式GitHubのexamples/jsm/controls
フォルダーにJavaScriptファイルにはいっています。該当ファイルはこちらで確認できます。
※Three.js r148(2022年12月リリース)よりexamples/js
フォルダーでの提供はなくなりました。OrbitControls
はES Modulesで利用します。
使い方
OrbitControls
は次の書式で利用します。OrbitControls
クラスのコンストラクターへ、カメラのインスタンスとDOM要素を引数として指定します。これだけで、自動的にマウスと連動してインタラクションが効くようになります。
OrbitControls
クラスの第2引数は、ポインターの操作を受け付ける対象のDOM要素を指定します。多くの利用用途ではdocument.body
かcanvas
要素が妥当でしょう。以下の例ではdocument.body
として指定しています(画面内のどこでもポインター操作を受け付けるようになります)。
// カメラを作成
const camera = new THREE.PerspectiveCamera(/*省略*/);
// カメラの初期座標を設定
camera.position.set(0, 0, 1000);
// カメラコントローラーを作成
const controls = new OrbitControls(camera, document.body);
マウス操作で次のようにカメラを制御できます。
- オービット(周回軌道): 左ボタンでドラッグ
- ズーム: マウスホイール
- パン: 右ボタンでドラッグ
実行可能な最小のサンプルコードはこちらです。次の例では、OrbitControls
クラスの第2引数にcanvas
要素を指定しており、ポインター操作の対象をCanvasだけに絞っています。
// サイズを指定
const width = 960;
const height = 540;
// レンダラーを作成
const canvasElement = document.querySelector('#myCanvas')
const renderer = new THREE.WebGLRenderer({
canvas: canvasElement,
});
renderer.setSize(width, height);
// シーンを作成
const scene = new THREE.Scene();
// カメラを作成
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
camera.position.set(0, 0, 1000);
// カメラコントローラーを作成
const controls = new OrbitControls(camera, canvasElement);
// 形状とマテリアルからメッシュを作成します
const mesh = new THREE.Mesh(
new THREE.BoxGeometry(300, 300, 300),
new THREE.MeshNormalMaterial());
scene.add(mesh);
tick();
// 毎フレーム時に実行されるループイベントです
function tick() {
// レンダリング
renderer.render(scene, camera);
requestAnimationFrame(tick);
}
滑らかにコントロールする
OrbitControls
インスタンスのenableDamping
やdampingFactor
プロパティーを設定すると、ドラッグ時にカメラが滑らかに動くようになります。デフォルトだと機械的な動きになってしまいますが、これらのプロパティーを設定するだけで心地良い操作感になります。
enableDamping
やdampingFactor
プロパティーを使う場合は、requestAnimationFrame
内でOrbitControls
インスンタンスのupdate
メソッドを呼び出す必要があります。
// カメラを作成
const camera = new THREE.PerspectiveCamera(/*省略*/);
// カメラの初期座標を設定
camera.position.set(0, 0, 1000);
// カメラコントローラーを作成
const controls = new OrbitControls(camera, canvasElement);
// 滑らかにカメラコントローラーを制御する
controls.enableDamping = true;
controls.dampingFactor = 0.2;
tick();
// 毎フレーム時に実行されるループイベントです
function tick() {
// カメラコントローラーを更新
controls.update();
// レンダリング
renderer.render(scene, camera);
requestAnimationFrame(tick);
}
まとめ
カメラを手軽に制御できるので、小さな作例ではOrbitControls
を使われることが多いです。ただし、手軽である分、カスタマイズの自由度の制限があるので、細かいカメラワークを作ろうとしたらOrbitControls
では物足りません。カメラの制御はいろんなコードを書いて自作して覚えていくといいでしょう。
次回の記事では、モデリングデータの読み込み方法を説明します。
関連
Node.js関連のバンドルツールでOrbitControls
を利用する場合は、以下の解説を参照ください。