mapbox/mapbox-gl-js

Mouse events are shifted after a css transform scale on the map container

Closed this issue ยท 9 comments

fxi commented

mapbox-gl-js version: 0.44.0

Steps to Trigger Behavior

  1. Create a map,
  2. Set transform scale(0.9) on map container,
  3. Use map.resize() to update the canvas.

Example : https://jsfiddle.net/fxi/gb5jqssu/

Expected Behavior

All mouse events should match the updated map.

Actual Behavior

All mouse events are slightly shifted.

azei commented

I'm running in to this issue as well. Scaling both shifts zooming in/out as well as making the map hard to pan.

Has anyone found a workaround?

Same here, also struggling with this and the only way around that I can see is to write custom interactions for all scroll and touch events.

Perhaps a scale-offset property could be added to the API?

Just a note, i've posted a possible solution to this issue in #7701 (comment).

So I've just submitted a proposed PR โ˜๏ธ for this issue. The functionality works, but once I've had feedback I'll continue with the implementation and writing tests. Any eyes-on would be appreciated!

Is there any update for this issue?

@rgazelot unfortunately not as the conversation in #8017 means not using css transforms and rather going down the line of using offsetX and offsetY. However I don't believe this is a solid solution until there's a way to prevent panning/dragging when the mouse/cursor leaves the map bounds.

Thanks for the update @adamcbrewer

I have experimented with offsetX and offsetY based solution. While it does work and correctly returns local coordinates of an element inside CSS-transformed tree, it doesn't work for touch devices.

One promising direction to explore would be to use pointer events, like pointerdown. MDN reports this as not supported by Safari, however this simple test https://output.jsbin.com/garuceh worked in both iOS simulator's Safari and desktop Safari. It also worked in Firefox, Chrome for Android and desktop.

I understand that changing input model to pointers events could be a big switch, but hopefully the right one in the long term.

As potential mid-term patch we could experiment with firing a pointerdown event, let the browser do the transformation to local coordinates, and grab it back. I got this proof of concept working here https://output.jsbin.com/sadorac for almost all devices except Chrome for Android, which unlike other browser doesn't perform correct translation of clientX to offsetX on synthetic event.

@anvaka I had managed to implement an offsetX/Y for touch devices by providing a scale value, though only in my fork.

It's been well over a year since I've revisited this issue, but I think you're right in that pointer events could be the solution...if I remember correctly. I'm hoping that Sarafi is actually supported (as you say) ๐Ÿคž