deck.gl icon indicating copy to clipboard operation
deck.gl copied to clipboard

GoogleMapsOverlay does not fire onDrag events even though onHover onClick and Highlight work

Open Fabioni opened this issue 1 year ago • 5 comments

Description

Using GoogleMapsOverlay from Deck.gl for Google Map JS API in overlaid mode should enable objects being picked or dragged. However this does not work.

Flavors

  • [ ] Script tag
  • [ ] React
  • [ ] Python/Jupyter notebook
  • [ ] MapboxOverlay
  • [X] GoogleMapsOverlay
  • [ ] CartoLayer
  • [ ] ArcGIS

Expected Behavior

After setting pickable=true, dragging the object should fire the respective events.

Steps to Reproduce

https://stackblitz.com/edit/vitejs-vite-rxes87?file=main.js

You can see that highlighting works, but onDrag / onDragStart / onDragEnd does not.

Environment

  • Framework version: 9.0.17
  • Browser: Chrome 125
  • OS: Sonoma 14.5

Logs

none

Fabioni avatar Jun 09 '24 09:06 Fabioni

@Pessimistress since you changed 'bug' to 'feature', would you mind letting me know, why this is not a bug? The way I understand the docs, this should already work.

Fabioni avatar Jun 13 '24 08:06 Fabioni

@Fabioni It's listed as a limitation of the interleaved integration mode. I also initially missed this in the docs, and ended up switching to a reverse controlled integration. Maybe the same thing will work for your use case.

croy618 avatar Jun 14 '24 14:06 croy618

@croy618 I'm using the 'overlayed' mode. I feel like it should work there.

Fabioni avatar Jun 15 '24 15:06 Fabioni

@Fabioni the documentation linked is about the limitation of GoogleMapsOverlay, regardless of integration mode.

I feel like it should work there.

You want to know why it is not a bug, and it's been pointed out that this is a known limitation. The long explanation is that Google Maps does not allow a control to directly attach DOM event listeners, so the input handling of standalone Deck is disabled. Hover and click work by delegating Google Maps's own events. Drag can still be implemented, but it will take work.

Pessimistress avatar Jun 15 '24 15:06 Pessimistress

Could we implement something like what they did in that Maplibre example: https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-point/

Meaning catching the mouse move events on the google maps api, use preventDefault and handle the dragging manually.

        // When the cursor enters a feature in the point layer, prepare for dragging.
        map.on('mouseenter', 'point', () => {
            map.setPaintProperty('point', 'circle-color', '#3bb2d0');
            canvas.style.cursor = 'move';
        });

        map.on('mouseleave', 'point', () => {
            map.setPaintProperty('point', 'circle-color', '#3887be');
            canvas.style.cursor = '';
        });

        map.on('mousedown', 'point', (e) => {
            // Prevent the default map drag behavior.
            e.preventDefault();

            canvas.style.cursor = 'grab';

            map.on('mousemove', onMove);
            map.once('mouseup', onUp);
        });

        map.on('touchstart', 'point', (e) => {
            if (e.points.length !== 1) return;

            // Prevent the default map drag behavior.
            e.preventDefault();

            map.on('touchmove', onMove);
            map.once('touchend', onUp);
        });

so something like

googlemapsmap.addListener('mousemove', (event) => {
    if (isDragging) {
        const latLng = event.latLng;
        deckglmarker.setPosition(latLng);
        event.preventDefault();
    }
});

Fabioni avatar Jun 20 '24 09:06 Fabioni