Navigate

Search topics across all sections

GitHub
Controls

OrbitControls

OrbitControls is the simplest way to let users explore a 3D scene. Drop it in, and people can drag to rotate, scroll to zoom, and right-click to pan. It is the default choice for almost every R3F project.

You add OrbitControls to your scene and everything works great. Then you add TransformControls to let users move an object. Now when you drag the gizmo, the entire camera spins at the same time. Both controls fight for the mouse, and the scene becomes unusable.

terminal
Camera orbits while TransformControls gizmo is being dragged. Both controls respond to the same mouse events simultaneously.

Real-world

Picture a globe on a desk stand. You grab the globe and spin it to see different continents. You scroll the stand up and down to zoom in on a country. You slide the whole stand left or right to re-center your view.

That is exactly what OrbitControls does. Your 3D object is the globe, and the camera orbits around it on an invisible stand. Left-drag to spin, scroll to zoom, right-drag to slide. The object stays put while you move around it.

How OrbitControls Works

Every mouse action maps to a camera movement around a fixed target point.

Left Drag

Orbit (rotate around target)

Scroll Wheel

Dolly (zoom in/out)

Right Drag

Pan (shift target sideways)

Camera Moves

Object stays still

Guided Walkthrough

Let us go from zero to a polished orbit setup in three steps.

Step 1 — Drop in OrbitControls

Experience.tsxTSX
import { OrbitControls } from '@react-three/drei'

function Experience() {
  return (
    <>
      <OrbitControls makeDefault />
      <mesh>
        <boxGeometry />
        <meshStandardMaterial color="royalblue" />
      </mesh>
      <ambientLight intensity={0.5} />
      <directionalLight position={[5, 5, 5]} />
    </>
  )
}

One line and you get full orbit, zoom, and pan. The makeDefault prop tells R3F "these are my controls" so everything stays in sync.

Step 2 — Constrain the movement

ConstrainedOrbit.tsxTSX
<OrbitControls
  makeDefault
  minPolarAngle={Math.PI / 6}    // can't look from above
  maxPolarAngle={Math.PI / 2}    // can't go underground
  minDistance={2}                  // closest zoom
  maxDistance={10}                 // farthest zoom
/>

Polar angles control the vertical range. Distance limits prevent users from zooming through the object or losing it in the distance. Essential for product viewers.

Step 3 — Add damping and auto-rotate

SmoothOrbit.tsxTSX
<OrbitControls
  makeDefault
  enableDamping
  dampingFactor={0.05}
  autoRotate
  autoRotateSpeed={2}
/>

Damping adds smooth momentum so the camera glides after you release the mouse. Auto-rotate slowly spins the scene, which looks great on landing pages and product showcases.

What you just learned

OrbitControls gives you orbit, zoom, and pan with a single component

makeDefault registers the controls so R3F and other drei components stay in sync

Polar angles and distance limits constrain the camera to a comfortable range

Damping adds smooth momentum, auto-rotate keeps the scene spinning

Question

OrbitControls always rotates the camera around a target point. But what if you need the camera to fly smoothly from one spot to another, like clicking on a part of a car to zoom into it? Can OrbitControls do that? (Hint: check out CameraControls.)

Think about it...

You set maxPolarAngle to Math.PI / 2 on your OrbitControls. What happens when a user tries to drag the camera below the ground plane?

Try These Challenges

Put what you learned into practice. Try each challenge in the demo above using the Leva controls, then check the solution.

Try This!

Beginner

Enable autoRotate and set autoRotateSpeed to 10 -- dizzy cam!

Try This!

Beginner

Enable the constrained polar angle -- can you look underneath?

Try This!

Beginner

Toggle damping off -- feels snappy!

These are the patterns that trip up developers most often. Switch between Wrong and Fixed to compare the code side by side.

1
Not using makeDefault
Camera state gets out of sync with controls
Don't do this
Experience.tsxTSX
<OrbitControls />
<TransformControls>
  <mesh />
</TransformControls>
// TransformControls can't disable OrbitControls
// because it doesn't know they exist
The makeDefault prop registers OrbitControls in R3F's internal state store. Without it, other drei components like TransformControls or GizmoHelper cannot disable orbit when they need exclusive camera control. It also keeps the camera state synchronized with R3F's event system. Always add makeDefault unless you have a specific reason not to.
2
Scene freezes with demand rendering
Damping animation stops mid-deceleration
Don't do this
DemandMode.tsxTSX
<Canvas frameloop="demand">
  <OrbitControls enableDamping dampingFactor={0.05} />
  {/* Scene freezes mid-deceleration when you
      release the mouse — no one calls invalidate() */}
</Canvas>
In demand mode, the canvas only renders when told to. Damping needs extra frames after you release the mouse because the camera is still decelerating. Without invalidation, the scene freezes mid-motion. Using makeDefault handles this automatically.
3
Controls on the wrong camera
Custom camera is ignored, default camera moves instead
Don't do this
CustomCamera.tsxTSX
<perspectiveCamera ref={camRef} position={[5, 5, 5]} />
<OrbitControls />
// Attaches to the DEFAULT camera, not yours!
OrbitControls attaches to whatever camera is in R3F's state — the Canvas default camera. If you create a separate <perspectiveCamera>, OrbitControls will not use it. Configure the camera through the Canvas camera prop and let OrbitControls pick it up via makeDefault.

Best Practices

Always use makeDefault

It costs nothing and prevents hard-to-debug conflicts with other drei components like TransformControls and GizmoHelper.

Enable damping

Always enable enableDamping for a polished feel. The default dampingFactor of 0.05 works well for most scenes.

Constrain for UX

Set maxPolarAngle to prevent going underground and minDistance/maxDistance to keep the object in a comfortable zoom range.

Switch to CameraControls for animation

If you need smooth programmatic camera transitions like click-to-focus or guided tours, CameraControls is the right tool for the job.