OrbitControls touch crashes on Expo mobile app
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 858
- Forks
- 144
- PR merge metrics
- No merged PRs in 30d
Description
threeversion: ^0.166.1@types/threeversion: 0.183.1three-stdlibversion: ^2.35.6
Problem description:
As previously reported by @damistheanswer in the issue https://github.com/mrdoob/three.js/issues/32116, OrbitControls does crash a mobile app on touch devices, such tablets and iPads, when using multi-touches to zoom in/zoom out an object.
I got the same message such as:
TypeError: Cannot read properties of undefined (reading 'x')
Reproduction steps
- Download the sample project or the apk file
- Start a two-finger pinch gesture (pinch-to-zoom)
- Lift one finger mid-gesture while the other finger remains touching
- The error occurs sporadically when the second pointer position becomes undefined
Relevant code:
Same as the issue #32116
In OrbitControls.js, the _getSecondPointerPosition() method returns undefined when a pointer is no longer tracked:
// Line ~1407-1411
_getSecondPointerPosition( event ) {
const pointerId = ( event.pointerId === this._pointers[ 0 ] ) ? this._pointers[ 1 ] : this._pointers[ 0 ];
return this._pointerPositions[ pointerId ]; // Can return undefined!
}
This undefined value is then used without null checking in multiple places:
// Line ~1234-1238 (handleTouchMoveDolly)
const position = this._getSecondPointerPosition( event );
const dx = event.pageX - position.x; // ❌ Crash: position is undefined
const dy = event.pageY - position.y;
Similar crashes occur at:
- Line 1202-1204 (handleTouchStartRotate)
- Line 1221-1223 (handleTouchStartPan)
- Line 1269-1271 (handleTouchMoveRotate)
- Line 1298-1300 (handleTouchMovePan)
- Line 1317-1320 (handleTouchMoveDolly)
Live example
Same as the issue #32116:
- User starts two-finger gesture → both pointers tracked in _pointers array
- User lifts one finger → pointer is removed from _pointers
- Move event fires for remaining finger → tries to get second pointer position
- _pointerPositions[pointerId] returns undefined because pointer was removed
- Code attempts position.x → crash
Screenshots
Attached error on expo app:
Please check this video for demonstration of the bug:
Device
Mobile
OS
Android
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in OrbitControls.js at _getSecondPointerPosition() and the listed touch handlers, then reproduce the two-finger pinch and finger-lift sequence with the linked Expo sample project. Done means the gesture no longer crashes when the second pointer position is undefined, including the listed rotate, pan, and dolly paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, three.js
- Domain
- frontend, mobile-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100
