Three.js: Drag + Trackball controls

Created on 20 Nov 2020  路  4Comments  路  Source: mrdoob/three.js

Describe the bug

Hi there!

While setting up a scene with both Trackball and Drag controls active I noticed it has stopped working since version 0.120.0.

I've created an example here which demonstrates the issue: https://codepen.io/vasturiano/pen/GRqazYq

As you can see, no drag pointer events are triggered if Trackball controls is enabled on the element.

After diving in a bit, I believe the change was introduced in this particular commit: https://github.com/mrdoob/three.js/commit/f86fcc092aa8459e7b78b3244e02df923f2d4753

The core of the issue is that this pointerdown preventDefault call has a different behavior than when it was applied to the prior mousedown events. As documented here:

If the pointerdown event isn't canceled through a call to preventDefault(), most user agents will fire a mousedown event, so that sites not using pointer events will work.

So, this preventDefault call is essentially stopping the mousedown events from being triggered in the DragControls (because that module is still using mouse events, not pointer events).

Perhaps the solution is as simple as removing the preventDefault statement, since I think that is a no-op for mousedown events, so it would be in line with the previous behavior.

Or migrate DragControls to use pointer events, that would in theory also solve it.

Btw, I believe OrbitControls has the same effect, since it had a similar change applied.

Just for comparison, here's a fork of the same example but importing v0.119.1 of TrackballControls instead. You'll notice that both work simultaneously and can coexist reasonably well.
For a seamless experience TrackballControls is disabled dynamically during a drag, so the interactions don't interfere with each other.

To Reproduce

  1. Go to https://codepen.io/vasturiano/pen/GRqazYq
  2. Try to drag one of the nodes (it won't work)
  3. Disable Trackball
  4. Drag successful

Code

Relevant portion of the code:

// trackball controls
const tbControls = new THREE.TrackballControls(camera, renderer.domElement);

// drag controls
const dragControls = new THREE.DragControls(objs, camera, renderer.domElement);
dragControls.addEventListener('dragstart', () => tbControls.enabled = false); // Disable trackball controls while dragging
dragControls.addEventListener('dragend', () => tbControls.enabled = true); // Re-enable trackball controls

Live example

Not-working (TrackballControls latest version):
https://codepen.io/vasturiano/pen/GRqazYq

Working (v0.119.1):
https://codepen.io/vasturiano/pen/oNLRVjj

Expected behavior

Like in versions <0.120.0, be able to have both Drag and Trackball controls active simultaneously.

Most helpful comment

I've made a PR that introduces Pointer Events in DragControls so it's easier to see the changes and verify them. The PR indeed fixes your codepen.

All 4 comments

Or migrate DragControls to use pointer events, that would in theory also solve it.

I guess we should try this first. @mrdoob What do you think?

I've made a PR that introduces Pointer Events in DragControls so it's easier to see the changes and verify them. The PR indeed fixes your codepen.

That's awesome, thanks @Mugen87 for the quick fix!

I confirm the example works properly with pointer events on drag controls. 馃憤

I suppose this will go out with the r123 release?

I suppose this will go out with the r123 release?

Correct!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

donmccurdy picture donmccurdy  路  3Comments

zsitro picture zsitro  路  3Comments

Horray picture Horray  路  3Comments

konijn picture konijn  路  3Comments

boyravikumar picture boyravikumar  路  3Comments