threejs-syntax-controls について
Three.js 開発者向けに、カメラとオブジェクトの操作方法をまとめたリファレンススキルです。各種コントロールの選択、初期化、更新、破棄、連携時の注意点を解説します。
主な機能
- 01操作方法に応じたコントロール選択
- 02オービット・マップ・フライト操作
- 03一人称視点とポインターロック操作
- 04オブジェクト変換とドラッグ用ギズモ
- 05ライフサイクルと連携のガイダンス
活用シーン
- 01モデルビューアーへの回転・ズーム追加
- 02一人称カメラ操作の構築
- 03ギズモによるオブジェクト変換の編集
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ impertio-studio/ three.js-claude-skill-package --skill threejs-syntax-controlsインストール後、Claude Code で/threejs-syntax-controlsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitkeepreferences/anti-patterns.mdexamples.mdmethods.md詳細
threejs-syntax-controls
クイックリファレンス
コントロール選択の決定木
| ユースケース | コントロール | 理由 |
|---|---|---|
| 3Dモデルをあらゆる角度から確認する | OrbitControls | 対象点を中心に回転/パン/ズームできます |
| 上面図の地図や2D風のナビゲーション | MapControls | 左ドラッグでパン、右ドラッグで回転します |
| 自由飛行するエディターや宇宙空間のシーン | FlyControls | 6自由度で、WASDキーとマウスを使用します |
| ポインターロックを使う一人称視点のゲーム | PointerLockControls | カーソルを非表示にし、マウスの動きを捕捉します |
| ポインターロックを使わない一人称視点 | FirstPersonControls | ブラウザーのロックAPIを使わずにマウスで視点を操作します |
| ギズモを使ってオブジェクトを移動/回転/拡縮する | TransformControls | 移動/回転/拡縮用のハンドルを操作できます |
| 平面に沿ってオブジェクトをドラッグする | DragControls | オブジェクトをクリックしてドラッグし、位置を変更できます |
| 拘束のない回転(ジンバルロックなし) | ArcballControls | アニメーション付きの全方向回転ができます |
| 拘束のない回転(よりシンプル) | TrackballControls | OrbitControlsに似ていますが、極方向の制約がありません |
インポートパス(Three.js r160以降)
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { MapControls } from 'three/addons/controls/MapControls.js';
import { FlyControls } from 'three/addons/controls/FlyControls.js';
import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
import { TransformControls } from 'three/addons/controls/TransformControls.js';
import { TrackballControls } from 'three/addons/controls/TrackballControls.js';
import { ArcballControls } from 'three/addons/controls/ArcballControls.js';
import { DragControls } from 'three/addons/controls/DragControls.js';
r160以降では、必ず 'three/addons/controls/...' を使用してください。旧パスの 'three/examples/jsm/controls/...' も引き続き動作しますが、非推奨です。
重要な警告
enableDamping または autoRotate が true の場合は、アニメーションループ内で必ず controls.update() を呼び出してください。呼び出さないと、ユーザーの操作終了後にカメラが停止します。
コントロールを削除する際は、必ず controls.dispose() を呼び出してください。呼び出さないと、DOMイベントリスナー(pointermove、wheel、keydown)がリークし、メモリリークやゴースト操作が発生します。
無効化せずに、同じカメラに2つのカメラコントロールクラスを絶対に同時にアタッチしないでください。同じカメラにOrbitControlsとFlyControlsをアタッチすると、動きが不規則になります。
TransformControlsがドラッグ中の間は、必ずOrbitControlsを無効にしてください。dragging-changedイベントを監視し、orbitControls.enabled を切り替えます。
PointerLockControls.lock() はユーザーのジェスチャー(クリックハンドラー)から必ず呼び出してください。ユーザー操作がない場合、ブラウザーはポインターロックの要求を拒否します。
FlyControls.update(delta) には、必ず delta 時間を渡してください。引数を渡さない場合や経過時間を渡す場合、速度がフレームレートに依存します。
コントロールのライフサイクル
すべてのコントロールは、同じライフサイクルパターンに従います。
construct --> configure --> attach to loop --> dispose on cleanup
ステップ1:生成
const controls = new OrbitControls(camera, renderer.domElement);
2番目の引数には、必ず renderer.domElement を渡してください。document や document.body を渡すと、コントロールがイベントをグローバルに捕捉し、UIオーバーレイが正常に動作しなくなります。
ステップ2:設定
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.minDistance = 2;
controls.maxDistance = 50;
controls.target.set(0, 1, 0);
ステップ3:レンダーループ内で更新
function animate() {
requestAnimationFrame(animate);
controls.update(); // REQUIRED when enableDamping or autoRotate is true
renderer.render(scene, camera);
}
animate();
ステップ4:クリーンアップ時に破棄
controls.dispose();
OrbitControls
最もよく使われるコントロールです。対象点を中心に回転、パン、ズームします。
コンストラクター
new OrbitControls(camera: THREE.Camera, domElement: HTMLElement)
主なプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
enabled | boolean | true | すべての操作を有効/無効にします |
target | Vector3 | (0,0,0) | オービットの注視点 |
enableDamping | boolean | false | 慣性のあるスムーズな移動を有効にします |
dampingFactor | number | 0.05 | 慣性の強さ(0~1) |
autoRotate | boolean | false | 注視点を中心に自動回転します |
autoRotateSpeed | number | 2.0 | 60fps 時の角速度(度/秒) |
enablePan | boolean | true | パン操作を有効にします |
enableRotate | boolean | true | 回転操作を有効にします |
enableZoom | boolean | true | ズーム操作を有効にします |
minDistance | number | 0 | 最小ズーム距離(PerspectiveCamera) |
maxDistance | number | Infinity | 最大ズーム距離(PerspectiveCamera) |
minZoom | number | 0 | 最小ズーム(OrthographicCamera) |
maxZoom | number | Infinity | 最大ズーム(OrthographicCamera) |
minPolarAngle | number | 0 | 最小垂直角度(ラジアン) |
maxPolarAngle | number | Math.PI | 最大垂直角度(ラジアン) |
minAzimuthAngle | number | -Infinity | 最小水平角度(ラジアン) |
maxAzimuthAngle | number | Infinity | 最大水平角度(ラジアン) |
screenSpacePanning | boolean | true | 画面平面(true)または水平面(false)でパンします |
zoomToCursor | boolean | false | カーソル位置に向かってズームします |
panSpeed | number | 1.0 | パン速度の倍率 |
rotateSpeed | number | 1.0 | 回転速度の倍率 |
zoomSpeed | number | 1.0 | ズーム速度の倍率 |
mouseButtons | object | {LEFT: ROTATE, MIDDLE: DOLLY, RIGHT: PAN} | マウスボタンの割り当て |
touches | object | {ONE: ROTATE, TWO: DOLLY_PAN} | タッチジェスチャーの割り当て |
keys | object | {LEFT, UP, RIGHT, BOTTOM} | パン操作に使用する矢印キーのコード |
メソッド
| メソッド | シグネチャ | 説明 |
|---|---|---|
update(deltaTime?) | (number?) => boolean | コントロールの状態を更新します。減衰/自動回転を使用する場合は、毎フレーム呼び出す必要があります |
dispose() | () => void | すべてのイベントリスナーを削除します |
saveState() | () => void | 現在のカメラ位置/注視点/ズームを保存します |
reset() | () => void | 最後に保存した状態に戻します |
getDistance() | () => number | カメラから注視点までの距離 |
getPolarAngle() | () => number | 垂直角度(ラジアン) |
getAzimuthalAngle() | () => number | 水平角度(ラジアン) |
listenToKeyEvents(el) | (HTMLElement) => void | キーボードによるパン操作を有効にします |
stopListenToKeyEvents() | () => void | キーボードによるパン操作を無効にします |
イベント
| イベント | 発生条件 |
|---|---|
change | カメラ位置または注視点が変更されたとき |
start | ユーザー操作が始まったとき(pointerdown) |
end | ユーザー操作が終了したとき(pointerup) |
MapControls
上から見下ろすマップナビゲーションに最適化された OrbitControls のサブクラスです。
| ボタン | OrbitControls | MapControls |
|---|---|---|
| 左マウスボタン | 回転 | パン |
| 中マウスボタン | ドリー | ドリー |
| 右マウスボタン | パン | 回転 |
プロパティ、メソッド、イベントはすべて OrbitControls と同じです。異なるのはデフォルトの mouseButtons の割り当てと、screenSpacePanning のデフォルト値が true である点だけです。
FlyControls
6自由度のフライトカメラです。移動には WASD、ロールには QE、上下移動には RF を使用します。
主なプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
movementSpeed | number | 1.0 | 平行移動速度 |
rollSpeed | number | 0.005 | ロール回転速度 |
dragToLook | boolean | false | 回転するにはマウスのドラッグが必要です(常にマウスに追従するのではなく) |
autoForward | boolean | false | 自動的に前進します |
メソッド
update(delta)-- クロックから取得したdelta時間を必ず渡してください。この引数を省略しないでください。dispose()-- イベントリスナーを削除します。
PointerLockControls
Pointer Lock API を使用する一人称視点カメラです。マウスカーソルを非表示にして捕捉します。
主なプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
isLocked | boolean | 読み取り専用 | ポインターが現在ロックされているかどうか |
maxPolarAngle | number | Math.PI | 垂直方向の最大視角 |
minPolarAngle | number | 0 | 垂直方向の最小視角 |
pointerSpeed | number | 1.0 | マウス感度の倍率 |
メソッド
| メソッド | 説明 |
|---|---|
lock() | ポインターロックを要求します(ユーザー操作から呼び出す必要があります) |
unlock() | ポインターロックを解除します |
connect() | イベントリスナーを登録します |
disconnect() | イベントリスナーを削除します |
dispose() | 完全にクリーンアップします(disconnect を呼び出します) |
getObject() | 操作対象のカメラを返します |
getDirection(target) | 視線の方向を target の Vector3 に書き込みます |
moveForward(distance) | カメラを前方に移動します |
moveRight(distance) | カメラを横方向に移動します |
イベント
| イベント | 発生条件 |
|---|---|
change | カメラの向きが変化したとき |
lock | ポインターロックを取得したとき |
unlock | ポインターロックを解除したとき |
アニメーションループ内では、必ず独自の WASD 移動処理を実装してください。PointerLockControls が処理するのは視線の方向だけであり、位置は処理しません。
TransformControls
シーン内のオブジェクトを移動、回転、拡大縮小するためのインタラクティブなギズモです。
主なプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
mode | string | 'translate' | 'translate'、'rotate'、または 'scale' |
space | string | 'world' | 'world' または 'local' 座標空間 |
showX | boolean | true | X 軸のハンドルを表示します |
showY | boolean | true | Y 軸のハンドルを表示します |
showZ | boolean | true | Z 軸のハンドルを表示します |
size | number | 1 | ギズモの表示スケール |
translationSnap | `number | null` | null |
rotationSnap | `number | null` | null |
scaleSnap | `number | null` | null |
dragging | boolean | 読み取り専用 | ユーザーが現在ドラッグしているかどうか |
メソッド
| メソッド | 説明 |
|---|---|
attach(object) | ギズモをシーン内のオブジェクトに取り付けます |
detach() | 現在のオブジェクトからギズモを取り外します |
setMode(mode) | 変換モードを設定します |
setSpace(space) | 座標空間を設定します |
setSize(size) | ギズモのスケールを設定します |
setTranslationSnap(snap) | 位置のスナップを設定します |
setRotationSnap(snap) | 回転のスナップを設定します |
setScaleSnap(snap) | スケールのスナップを設定します |
getRaycaster() | 内部のレイキャスターにアクセスします |
dispose() | クリーンアップします |
イベント
| イベント | 発生条件 |
|---|---|
change | ギズモの表示が変化したとき |
dragging-changed | ドラッグ開始時は event.value が true、終了時は false になります |
objectChange | 取り付けたオブジェクトの変換が変更されたとき |
mouseDown | ギズモ上でポインターを押したとき |
mouseUp | ギズモからポインターを離したとき |
重要な統合パターン
ギズモのドラッグ中は、必ずカメラコントロールを無効にしてください。
transformControls.addEventListener('dragging-changed', (event) => {
orbitControls.enabled = !event.value;
});
TransformControls は必ずシーンに追加してください:scene.add(transformControls.getHelper()) または scene.add(transformControls)。
概要:その他のコントロール
ArcballControls
アニメーション状態を備えた、制約のない回転機能です。極角の制限がないため、カメラは全方向に自由に回転します。CAD スタイルのモデル確認に最適です。
TrackballControls
極角の制約がない OrbitControls のようなコントロールです。カメラは極を越えて回転できます。プロパティ:rotateSpeed、zoomSpeed、panSpeed、staticMoving、dynamicDampingFactor。
DragControls
平面に沿ってシーン内のオブジェクトをドラッグします。コンストラクター:new DragControls(objects, camera, domElement)。イベント:dragstart、drag、dragend、hoveron、hoveroff。
FirstPersonControls
ポインターロックを使用しないマウス視点操作のカメラです。プロパティ:movementSpeed、lookSpeed、activeLook、constrainVertical、verticalMin、verticalMax。
参考リンク
- references/methods.md -- すべてのコントロールの完全な API シグネチャ
- references/examples.md -- 各コントロールタイプの動作するコード例
- references/anti-patterns.md -- やってはいけないこと
公式ソース
- https://threejs.org/docs/#examples/en/controls/OrbitControls
- https://threejs.org/docs/#examples/en/controls/MapControls
- https://threejs.org/docs/#examples/en/controls/FlyControls
- https://threejs.org/docs/#examples/en/controls/PointerLockControls
- https://threejs.org/docs/#examples/en/controls/TransformControls