Orbit controls

The camera rig where dragging spins the view around a fixed target, scrolling zooms, and right-drag pans. The 3D-model-viewer feel.

drag to spin the modelthe turntable cameraorbitcontrolsorbit cameramouse rotate around an objectspin and zoom the 3d viewerproduct viewer camera controlsscroll keeps zooming instead of scrolling the page

See it

Live demo coming soon

What it is

Orbit controls don't move your model, they move the camera along an invisible sphere around a fixed target point. Drag rotates, scroll dollies in and out, right-drag (or two-finger drag) slides the target itself. Three.js ships it as OrbitControls, and it is the default feel of every product configurator, Sketchfab embed, and 'spin the sneaker' hero on the web.

Reach for it when the object is the subject and the user just needs to inspect it. The knobs that actually matter are target (orbit around the model's center, not the world origin), enableDamping with a damping factor around 0.05 for that weighty glide, min/max distance so people can't fly inside the mesh, and a max polar angle so they can't swing under the floor. Its cousin, TrackballControls, allows roll and free tumbling; orbit controls keep 'up' locked, which is why it feels tidy and why it can't do a barrel roll.

Gotcha: zoom eats the page scroll. Drop a full-page canvas behind your content with controls enabled and the wheel stops scrolling the document, which is a real accessibility problem. Scope the canvas to a bounded section and capture the wheel only while the viewer is focused or a modifier key is held, so zoom stays part of the interaction and the page still scrolls the rest of the time. Turning zoom off entirely is the last resort, not the first move, since scroll-to-zoom is half of what people expect from this rig. Also remember to call update() every frame once damping is on, otherwise the motion just stops dead.

Ask AI for it

Add three.js OrbitControls to this scene: set the target to the loaded model's bounding-box center, enable damping (dampingFactor 0.05) and call controls.update() in the render loop. Clamp minDistance and maxDistance to roughly 1.5x and 4x the model radius, set maxPolarAngle to just under Math.PI / 2 so the camera never goes below the ground plane, and disable panning. Keep enableZoom on, since scroll-to-zoom is half of what people expect here, but put the canvas in a bounded section and only capture the wheel while that viewer has focus (or while a modifier key is held), letting the page scroll otherwise. Add a slow autoRotate that stops on first user interaction.

You might have meant

camera projection matrixtransforms coordinate spacespicking via ray castingscene graph

Go deeper