דלג לתוכן הראשי

Web development

3D experiences in the browser: touch controls that work on mobile

Daniel Eliyahu Bellelli··8 min read

Making a first-person Three.js scene usable on a phone: a fixed joystick, drag-to-look, iOS Safari pointer pitfalls and performance.

Many browser 3D demos are built on a desktop with a mouse and pointer lock. Open the same scene on a phone and the control model disappears: no WASD keys, no desktop pointer lock, and gestures the browser interprets as scrolling or zooming. A scene can look impressive in a screenshot while being impossible to explore.

The control model: joystick movement, drag-to-look

Use the familiar mobile FPS model: a fixed virtual joystick at the bottom-left for movement and a one-finger drag anywhere else to rotate the camera. Dividing the screen into left and right halves unnecessarily limits the look area. A brief tap on an object should remain an interaction rather than a drag.

Movement and looking must work together with two separate pointer IDs. Capture each pointer so tracking continues when a finger crosses the HUD. UI controls and open panels must be excluded from camera gestures.

Pitfalls behind an unresponsive camera

  • Set touch-action: none directly on the canvas; a body setting does not inherit into it.
  • Safari may ignore user-scalable=no, so block native gesture events inside the immersive game surface.
  • A pointerdown listener only on the canvas can miss drags beginning over a noninteractive HUD layer.
  • Ignore touches that start on buttons, panels or the joystick.
  • Clear pointer state on pointerup, pointercancel and lostpointercapture.

A particularly confusing failure occurs when an old look pointer remains assigned after a missing release event. Start every valid look gesture by assigning its pointer ID again. Do not require the previous ID to be null, or the camera may appear frozen until the browser clears the abandoned pointer.

Sensitivity and limits

Touch look needs substantially higher sensitivity than mouse look because a thumb has a smaller travel range. A touch factor around 0.013 versus a mouse factor around 0.0026 provides a practical starting point. Clamp vertical pitch to prevent camera inversion and tune on a real device rather than relying solely on desktop emulation.

Performance on mid-range devices

  • Cap devicePixelRatio at 2 where appropriate to reduce rendering cost.
  • Merge static geometry and reduce draw calls.
  • Use sensibly sized, compressed textures rather than unnecessary 4K background assets.
  • Load models as separate assets instead of embedding base64 data in HTML.
  • Pause unnecessary rendering when the page is not visible.

Accessibility and a non-3D alternative

A 3D environment cannot be the only way to reach important information. Provide the same content as accessible text and keep an obvious exit available. Devices without WebGL need a useful fallback rather than a blank screen; respect reduced-motion preferences when presenting the experience.

Conclusion

The difference between a 3D demo and a usable experience is often the mobile input layer. A familiar control model, reliable pointer lifecycle handling and awareness of Safari constraints turn an attractive scene into a place people can actually explore.

More articles