mcpField
T
threejs-syntax-controls

threejs-syntax-controls

github.com/impertio-studioDevelopment23134 installsUpdated 30w ago
Repository

About threejs-syntax-controls

A Three.js reference skill for selecting and using camera and object controls. It documents control types, setup, updates, cleanup, and integration pitfalls for developers building interactive 3D scenes.

Key features

  1. 01Control selection by interaction pattern
  2. 02Orbit, map, and flight camera controls
  3. 03First-person and pointer-lock controls
  4. 04Object transform and drag gizmos
  5. 05Lifecycle and control integration guidance

Use cases

  1. 01Adding orbiting and zooming to model viewers
  2. 02Building first-person camera interaction
  3. 03Editing object transforms with a gizmo

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/impertio-studio/three.js-claude-skill-package --skill threejs-syntax-controls

After installing, type/threejs-syntax-controlsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

.gitkeep
references/
anti-patterns.md
examples.md
methods.md

Details

From the project README

threejs-syntax-controls

Quick Reference

Control Selection Decision Tree
Use CaseControlWhy
Inspect a 3D model from all anglesOrbitControlsOrbit/pan/zoom around a target point
Top-down map or 2D-style navigationMapControlsLeft-drag pans, right-drag rotates
Free-flight editor or space sceneFlyControlsSix degrees of freedom, WASD + mouse
First-person game with pointer lockPointerLockControlsHides cursor, captures mouse movement
First-person without pointer lockFirstPersonControlsMouse-look without browser lock API
Move/rotate/scale objects via gizmoTransformControlsInteractive translate/rotate/scale handles
Drag objects along a planeDragControlsClick-and-drag object repositioning
Unconstrained rotation (no gimbal lock)ArcballControlsFull spherical rotation with animation
Unconstrained rotation (simpler)TrackballControlsLike OrbitControls but no pole constraint
Import Paths (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';

ALWAYS use 'three/addons/controls/...' for r160+. The legacy path 'three/examples/jsm/controls/...' still works but is deprecated.

Critical Warnings

ALWAYS call controls.update() in the animation loop when enableDamping or autoRotate is true. Failing to do so causes the camera to freeze after user interaction ends.

ALWAYS call controls.dispose() when removing controls. Failing to do so leaks DOM event listeners (pointermove, wheel, keydown) that cause memory leaks and ghost interactions.

NEVER attach two camera-control classes to the same camera simultaneously without disabling one. OrbitControls + FlyControls on the same camera causes erratic movement.

ALWAYS disable OrbitControls while TransformControls is dragging. Listen to the dragging-changed event and toggle orbitControls.enabled.

ALWAYS call PointerLockControls.lock() from a user gesture (click handler). Browsers reject pointer lock requests without user interaction.

ALWAYS pass delta time to FlyControls.update(delta). Passing no argument or passing elapsed time causes speed to depend on frame rate.


Controls Lifecycle

Every control follows the same lifecycle pattern:

construct --> configure --> attach to loop --> dispose on cleanup
Step 1: Construct
const controls = new OrbitControls(camera, renderer.domElement);

ALWAYS pass renderer.domElement as the second argument. Passing document or document.body causes controls to capture events globally, breaking UI overlays.

Step 2: Configure
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.minDistance = 2;
controls.maxDistance = 50;
controls.target.set(0, 1, 0);
Step 3: Update in Render Loop
function animate() {
  requestAnimationFrame(animate);
  controls.update(); // REQUIRED when enableDamping or autoRotate is true
  renderer.render(scene, camera);
}
animate();
Step 4: Dispose on Cleanup
controls.dispose();

OrbitControls

The most commonly used control. Orbits, pans, and zooms around a target point.

Constructor
new OrbitControls(camera: THREE.Camera, domElement: HTMLElement)
Key Properties
PropertyTypeDefaultDescription
enabledbooleantrueEnable/disable all interaction
targetVector3(0,0,0)Orbit focus point
enableDampingbooleanfalseSmooth inertial movement
dampingFactornumber0.05Inertia strength (0-1)
autoRotatebooleanfalseAuto-rotate around target
autoRotateSpeednumber2.0Degrees/sec at 60fps
enablePanbooleantrueAllow panning
enableRotatebooleantrueAllow rotation
enableZoombooleantrueAllow zooming
minDistancenumber0Min zoom distance (PerspectiveCamera)
maxDistancenumberInfinityMax zoom distance (PerspectiveCamera)
minZoomnumber0Min zoom (OrthographicCamera)
maxZoomnumberInfinityMax zoom (OrthographicCamera)
minPolarAnglenumber0Min vertical angle (radians)
maxPolarAnglenumberMath.PIMax vertical angle (radians)
minAzimuthAnglenumber-InfinityMin horizontal angle (radians)
maxAzimuthAnglenumberInfinityMax horizontal angle (radians)
screenSpacePanningbooleantruePan in screen plane (true) or horizontal plane (false)
zoomToCursorbooleanfalseZoom towards cursor position
panSpeednumber1.0Pan speed multiplier
rotateSpeednumber1.0Rotation speed multiplier
zoomSpeednumber1.0Zoom speed multiplier
mouseButtonsobject{LEFT: ROTATE, MIDDLE: DOLLY, RIGHT: PAN}Mouse button mapping
touchesobject{ONE: ROTATE, TWO: DOLLY_PAN}Touch gesture mapping
keysobject{LEFT, UP, RIGHT, BOTTOM}Arrow key codes for panning
Methods
MethodSignatureDescription
update(deltaTime?)(number?) => booleanUpdate controls state. MUST call every frame with damping/autoRotate
dispose()() => voidRemove all event listeners
saveState()() => voidSave current camera position/target/zoom
reset()() => voidRestore to last saved state
getDistance()() => numberDistance from camera to target
getPolarAngle()() => numberVertical angle in radians
getAzimuthalAngle()() => numberHorizontal angle in radians
listenToKeyEvents(el)(HTMLElement) => voidEnable keyboard panning
stopListenToKeyEvents()() => voidDisable keyboard panning
Events
EventTrigger
changeCamera position or target changed
startUser interaction began (pointerdown)
endUser interaction ended (pointerup)

MapControls

Subclass of OrbitControls optimized for top-down map navigation.

ButtonOrbitControlsMapControls
Left mouseRotatePan
Middle mouseDollyDolly
Right mousePanRotate

All properties, methods, and events are identical to OrbitControls. The ONLY differences are the default mouseButtons mapping and screenSpacePanning defaulting to true.


FlyControls

Six-degrees-of-freedom flight camera. WASD for movement, QE for roll, RF for up/down.

Key Properties
PropertyTypeDefaultDescription
movementSpeednumber1.0Translation speed
rollSpeednumber0.005Roll rotation speed
dragToLookbooleanfalseRequire mouse drag to rotate (vs. always follow mouse)
autoForwardbooleanfalseMove forward automatically
Methods
  • update(delta) -- ALWAYS pass delta time from the clock. NEVER omit this argument.
  • dispose() -- Remove event listeners.

PointerLockControls

First-person camera using the Pointer Lock API. Hides and captures the mouse cursor.

Key Properties
PropertyTypeDefaultDescription
isLockedbooleanread-onlyWhether pointer is currently locked
maxPolarAnglenumberMath.PIMax vertical look angle
minPolarAnglenumber0Min vertical look angle
pointerSpeednumber1.0Mouse sensitivity multiplier
Methods
MethodDescription
lock()Request pointer lock (MUST call from user gesture)
unlock()Exit pointer lock
connect()Attach event listeners
disconnect()Remove event listeners
dispose()Full cleanup (calls disconnect)
getObject()Returns the controlled camera
getDirection(target)Write look direction into target Vector3
moveForward(distance)Move camera forward
moveRight(distance)Move camera sideways
Events
EventTrigger
changeCamera orientation changed
lockPointer lock acquired
unlockPointer lock released

ALWAYS implement your own WASD movement in the animation loop. PointerLockControls handles look direction only, NOT position.


TransformControls

Interactive gizmo for moving, rotating, and scaling scene objects.

Key Properties
PropertyTypeDefaultDescription
modestring'translate''translate', 'rotate', or 'scale'
spacestring'world''world' or 'local' coordinate space
showXbooleantrueShow X axis handle
showYbooleantrueShow Y axis handle
showZbooleantrueShow Z axis handle
sizenumber1Gizmo visual scale
translationSnap`numbernull`null
rotationSnap`numbernull`null
scaleSnap`numbernull`null
draggingbooleanread-onlyUser is currently dragging
Methods
MethodDescription
attach(object)Attach gizmo to a scene object
detach()Remove gizmo from current object
setMode(mode)Set transform mode
setSpace(space)Set coordinate space
setSize(size)Set gizmo scale
setTranslationSnap(snap)Set position snap
setRotationSnap(snap)Set rotation snap
setScaleSnap(snap)Set scale snap
getRaycaster()Access internal raycaster
dispose()Cleanup
Events
EventTrigger
changeGizmo visual changed
dragging-changedevent.value is true when dragging starts, false when it ends
objectChangeAttached object's transform was modified
mouseDownPointer pressed on gizmo
mouseUpPointer released from gizmo
Critical Integration Pattern

ALWAYS disable camera controls during gizmo drag:

transformControls.addEventListener('dragging-changed', (event) => {
  orbitControls.enabled = !event.value;
});

ALWAYS add TransformControls to the scene: scene.add(transformControls.getHelper()) or scene.add(transformControls).


Brief Overview: Other Controls

ArcballControls

Unconstrained rotation with animation states. No polar angle limit -- the camera rotates freely in all directions. Best for CAD-style model inspection.

TrackballControls

Like OrbitControls without the polar angle constraint. The camera can rotate past the poles. Properties: rotateSpeed, zoomSpeed, panSpeed, staticMoving, dynamicDampingFactor.

DragControls

Drag scene objects along a plane. Constructor: new DragControls(objects, camera, domElement). Events: dragstart, drag, dragend, hoveron, hoveroff.

FirstPersonControls

Mouse-look camera without pointer lock. Properties: movementSpeed, lookSpeed, activeLook, constrainVertical, verticalMin, verticalMax.


Reference Links

Official Sources

Comments

Markdown supported