Other Control Types

The add-ons ship eight more controls, all constructed with a camera (or objects) and an element:

The control classes in Three.js 30,815 's add-ons
Control Behavior Good for
MapControls Orbit with pan on left-drag Maps, floor plans, top-down views
TrackballControls Free rotation, no fixed up Molecules, CAD parts
ArcballControls Virtual trackball with gizmos Inspecting models
FlyControls Six degrees of freedom Space and flight scenes
FirstPersonControls Look with the mouse, move with keys Walkthrough previews
PointerLockControls Mouse-look with a locked pointer First-person games
TransformControls Move, rotate or scale gizmo Editors, placing objects
DragControls Drag objects on a plane Arranging books (Dragging Objects in 3D)

Outside the add-ons, camera-controls 2,430 (github.com/yomotsu/camera-controls (https://github.com/yomotsu/camera-controls 2,430 ), MIT, npm 2,036 install camera-controls) adds smooth animated transitions such as fitToBox() and setLookAt(), and drei 9,900 wraps it for React 7,897 (React Three Fiber and drei). Babylon.js 89,603 builds these behaviors into its cameras instead; Babylon.js's ArcRotateCamera is the counterpart of OrbitControls.

TransformControls gizmo on a book next to OrbitControls, with MapControls as an alternativeHTMLLive
<!doctype html>
<style>
  body { margin: 0; background: #f5f1e8; font: 13px system-ui, sans-serif; color: #263238; }
  canvas { display: block; max-width: 100%; }
  .ui { padding: 4px 8px; }
</style>
<script type="importmap">
{ "imports": {
  "three": "https://cdn.jsdelivr.net/npm/three@0.186.1/build/three.module.js",
  "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.186.1/examples/jsm/" } }
</script>
<div class="ui">Gizmo: <button data-mode="translate">translate</button><button data-mode="rotate">rotate</button><button data-mode="scale">scale</button>
  · Camera: <select id="cam"><option>OrbitControls</option><option>MapControls</option></select></div>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { MapControls } from 'three/addons/controls/MapControls.js';
import { TransformControls } from 'three/addons/controls/TransformControls.js';

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
renderer.setSize(600, 300);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color('#fbf8f2');
const camera = new THREE.PerspectiveCamera(40, 2, 0.1, 50);
camera.position.set(1.6, 1.6, 3);
scene.add(new THREE.HemisphereLight('#ffffff', '#8d6e63', 1.2));
const sun = new THREE.DirectionalLight('#ffffff', 2.5);
sun.position.set(2, 3, 4);
scene.add(sun, new THREE.GridHelper(6, 12, '#b0a898', '#d8d0c0'));

const books = ['#1f5f8b', '#e09a10', '#b5452f'].map((color, i) => {
  const book = new THREE.Mesh(new THREE.BoxGeometry(0.42, 0.98, 0.12).translate(0, 0.49, 0),
    new THREE.MeshStandardMaterial({ color }));
  book.position.x = (i - 1) * 0.8;
  scene.add(book);
  return book;
});

let cameraControls = new OrbitControls(camera, renderer.domElement);
// TransformControls: a move / rotate / scale gizmo, the tool of editors
const gizmo = new TransformControls(camera, renderer.domElement);
gizmo.attach(books[1]);
scene.add(gizmo.getHelper());                         // r169+: the helper is what gets drawn
// Don't orbit while a gizmo handle is being dragged
gizmo.addEventListener('dragging-changed', (e) => { cameraControls.enabled = !e.value; });

document.querySelectorAll('[data-mode]').forEach((b) => b.onclick = () => gizmo.setMode(b.dataset.mode));
document.getElementById('cam').addEventListener('change', (e) => {
  cameraControls.dispose();                          // detach the old listeners
  const Controls = e.target.value === 'MapControls' ? MapControls : OrbitControls;
  cameraControls = new Controls(camera, renderer.domElement);   // MapControls: left-drag pans
});

renderer.setAnimationLoop(() => {
  cameraControls.update();
  renderer.render(scene, camera);
});
</script>