Three.jsでOrbitControlsを使って簡単にマウスで視点の操作する方法を紹介します。
まずはデモを確認してみましょう。
OrbitControlsとは?
OrbitControlsは、3Dシーン内でのカメラの操作を容易にするためのThree.jsのツールです。
マウスのドラッグで回転、ホイールでズーム、右ドラッグ(またはShift+ドラッグ)で平行移動ができるようになり、自分で座標計算をするとかなり面倒なことがとても簡単に実装できます。
使い方は3ステップです。
OrbitControlsをimportし、new OrbitControls(camera, renderer.domElement)でインスタンス化し、慣性(enableDamping)や自動回転(autoRotate)を使うならanimate関数の中でupdate()を呼びます。
Three.jsでOrbitControlsを使ったサンプルデモ
Three.jsでOrbitControlsを使ったサンプルコード
import * as THREE from "three";
// 1. 読み込み
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
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);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.TorusGeometry(10, 3, 200, 20);
const material = new THREE.MeshBasicMaterial({
color: 0x0000ff,
wireframe: true,
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 2. インスタンス化
// カメラ、キャンバスのDOMエレメント
const control = new OrbitControls(camera, renderer.domElement);
// 3. もし慣性が必要ならenableDamping、もしくはautoRotateをtrueにする
control.enableDamping = true;
control.autoRotate = true;
camera.position.z = 30;
function animate() {
// 4. enableDampingをtrueにした場合は、updateする
control.update();
requestAnimationFrame(animate);
cube.rotation.x = cube.rotation.x + 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
OrbitControlsのポイント
OrbitControlsのポイントを紹介します。
もしThree.jsの基本的な操作の一連の流れを知らない場合は、Three.js入門|回転する立方体をViteで表示する最小チュートリアルがとても短くまとめた記事なので、先に目を通してみてください。
インポートする
// 1. 読み込み
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
OrbitControlsはThree.js本体(three)には含まれておらず、アドオンとして別パスからimportします。
現在のThree.js公式ドキュメントでは、次のthree/addons/のパスが推奨されています(r148以降で使用可能。上のthree/examples/jsm/も引き続き動きます)。
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
CDNから読み込む場合は、importmapでthree/addons/のパスをhttps://unpkg.com/three@バージョン/examples/jsm/に対応させる必要があります。
「Failed to resolve module specifier」のようなエラーが出るときは、このパスの対応づけができていないことがほとんどです。
インスタンス化
// 2. インスタンス化
// カメラ、キャンバスのDOMエレメント
const control = new OrbitControls(camera, renderer.domElement);
OrbitControlsは、第一引数にカメラ、第二引数にレンダラーのDOM要素(canvas)をとります。
第二引数を省略したりdocument.bodyを渡したりすると、canvasの外のクリックまで拾ってしまい、他のUIと干渉することがあります。
オプション:慣性や回転を入れたい場合
// 3. もし慣性が必要ならenableDamping、もしくはautoRotateをtrueにする
control.enableDamping = true;
control.autoRotate = true;
マウスで操作したときにゆっくりととまってほしい場合(慣性)は、enableDampingをtrueにします。
自動で回転して欲しい場合は、autoRotateをtrueにします。
これらのどちらかでもtrueにした場合は、animate関数の中でupdate()してあげる必要があります。
function animate() {
// 4. enableDampingをtrueにした場合は、updateする
control.update();
...
}
これで正常にOrbitControlsが作動します。
動かないときの確認ポイント
- enableDampingやautoRotateをtrueにしたのに動きが固い・回らない場合は、animate関数の中で
control.update()を呼んでいるかを確認します。 - マウス操作がまったく効かない場合は、canvasの上に別の要素(オーバーレイやdiv)が重なっていないか、
renderer.domElementを正しく渡しているかを確認します。 - カメラの向きが変わらないと感じる場合は、
control.target.set(x, y, z)で注視点を変えた後にupdate()を呼びます。OrbitControlsはtargetを中心に回転します。 - ズームや平行移動を止めたい場合は、
control.enableZoom = false、control.enablePan = falseを設定します。
まとめ
- OrbitControlsをthree/examples/jsm/controls/OrbitControls からインポートします。
- OrbitControlsのインスタンスを作成し、カメラとレンダラーのDOMエレメントを引数として渡します。
- 慣性効果が必要な場合は enableDamping を true に設定します。
- 自動回転が必要な場合は autoRotate を true に設定します。
- OrbitControls が enableDamping または autoRotate を使用している場合、control.update() を呼び出して更新します。
視点を動かせるようになったら、次はオブジェクト側の見た目を整えていきます。
Three.js Materialの種類と使い方でマテリアルを変え、Three.jsライトの使い方でライトを当てると、回転させたときの立体感がぐっと増します。
パラメータを画面上で調整しながら試したい場合は、lil-guiとstats.jsを使う方法も合わせてどうぞ。