OrbitControls eventually gets stuck on iOS (webkit)

I have noticed that when using OrbitControl, I start losing interaction over time.

My guess is that when there are dropped frames, the “pointerup” event does not register properly. At first it works as expected: I can use one touch point to rotate, or two to zoom in/out or move the camera.

After some time (often when there’s a slightly noticeable framedrop), something breaks and I cannot use two touch points anymore. Using a single touch point will move the camera instead of rotating. (as if there’s a “ghost” touch point that was not removed and is acting as an anchor).

Later it repeats, and no further interaction is possible. (two “ghost” points I guess?)

Has anyone else reproduced this? I have been also testing Chrome(ChromeOS tablet) and it it’s not reproducible there, only on Safari (iOS).


I just found this, could it be related?

What version of iOS are you using?

Does the issue also happen with the official OrbitControls example? three.js webgl - orbit controls

iOS 15.4.1.

I tried the example for a bit and could not reproduce the bug.

On my demo I have a couple HTML buttons on top of the canvas that I use to reproduce some audio. I’m still to reproduce the issue without using these buttons.

My first guess would be an issue with having these interactive on top of the canvas. I would be impressed if was related to the audio… :confused:

I just reproduce it once without playing any audio, but I interacted with some other HTMLButton that is on top of the canvas. I think that might be the problem.

1 Like

I finally identified and fixed the problem:

On my sample I have a transparent canvas placed on top of a HTMLImageElement that is used as a background.

Doing a long press on the canvas would trigger the context menu for that image. When I did short and long movements it would sometimes count as a long press, and then the touch events would mess up breaking the OrbitControls.

I tried supressing the contextmenu with this line but it did not work: document.addEventListener("contextmenu", (event) => event.preventDefault());

What fixed it for me was adding a pointer-events: none; to the background image.


woah I came just in time for the solution
nice to know, thanks for sharing :rofl:

1 Like