visgl / deck.gl

WebGL2 powered visualization framework
https://deck.gl
MIT License
12.19k stars 2.09k forks source link

Overlay viewports do not block picking world coordinate projection #6261

Open mcost45 opened 3 years ago

mcost45 commented 3 years ago

Target Use case

My use case involves a view for static overlay/interface, and another view for dynamic panning/zooming. Both the overlay view and the dynamic view fill the screen, with the overlay view being on top. The overlay view has controller: false and all contained layers with pickable: false. I am also using event callbacks.

On hover, etc, unless a layer from the dynamic view gets picked, picking will use the static overlay viewport - this means that the generated world coordinate values are projected from the static viewport, instead of the below dynamic viewport, despite having no pickable layers or controller.

Proposed feature

Prevent 'overlay' viewports from being selected when picking.

This feature could possibly (?) be implemented in several ways:

  1. A boolean prop for overlay views (overlay: true) preventing viewport use in picking
  2. Views with controller: false not used for picking

To Do List

Pessimistress commented 3 years ago

Can you try ^8.6.0-alpha?

mcost45 commented 3 years ago

@Pessimistress Yep I just tried - top-level Deck hover events are still getting the overlay viewport, but click/drag events are getting the dynamic viewport.

Pessimistress commented 3 years ago

Can you create a Codepen that reproduces this issue?

mcost45 commented 3 years ago

Yes - I'll be able to try that in a week

mcost45 commented 3 years ago

@Pessimistress Tested again with the latest non-alpha version, and I'm still getting the same result. Here is a codepen as well: https://codepen.io/mttrx/pen/LYjNepJ.

On Deck events the viewportId is logged - hover will use 'overlayViewport'

Pessimistress commented 3 years ago

When nothing is picked, deck just chooses an arbitrary view under the pointer as the "picked" viewport. Even if we introduce a new flag on the View instance, there will still be a chance for ambiguity depending on the user's configuration.

The hover vs click/drag discrepancy should be a bug.

You can override the unprojection logic like this:


function getPointerCoordinate(pickingInfo) {
  if (!info.object) {
    // nothing is picked, override the internal logic
   const viewports = deck.getViewports();
   const myViewport = viewports.find(v => v.id === 'dynamicView');
   return myViewport.unproject([info.x, info.y]);
  }
  return info.coordinate;
}
Pessimistress commented 2 years ago

Bug fix (pickInfo.viewport populated with different viewports in onClick and onHover if nothing is picked) published in v8.6.3.

mcost45 commented 2 years ago

Just checked out the new version in the same codepen. Definitely a nice improvement to have the consistency with all events using the overlay viewport. However it could still be quite nice to have something built in so no overrides are necessary, if it can be done without ambiguity.

Instead of my previous ideas, possibly there could be an additional view prop - named along the lines of 'redirectPickTo'. This prop could take another viewId, which any events on said view would be redirected to, allowing multi-view projection to easily be implemented as desired. Would this work better/remove the chance for ambiguity? @Pessimistress