-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSS transform issue #7701
Comments
Per the Mozilla documentation, looks like |
@peterqliu The browsers compatibility table shows that |
MDN doesn't list it as experimental because of browser support but because the spec for
That being said, |
@jingsam when using Using your suggestion, this is also related to related to #6079 where using scale has the same effect and jumps all over the place depending on the element the mouse if over. I think this solution needs to consider how the panning interactions work on the map. However, since this only affects CSS transforms I'm wondering if the rest of the codebase and methods should altered. Perhaps there's a way to pass in some transform arguments to factor in the transforms in the mouse even |
So I've been trying to get my head around figuring out the best way to approach this. As an overview, I think we can stay out of DOM.mousePos, but ultimately we need to know the scale and rotation of the initial event called during // drag_pan.js
_start(e: MouseEvent | TouchEvent) {
...
const pos = DOM.mousePos(this._el, e);
const rect = this._el.getBoundingClientRect();
this._initialScale = (e.target.offsetWidth / rect.width);
this._applyScaleToPos(pos);
...
}
_applyScaleToPos(pos) {
if (this._initialScale && this._initialScale !== 1) {
// @mapbox/point-geomerty has built-in transformations methods
// including the ability to rotate
pos.mult(this._initialScale);
}
}
_onMove(e: MouseEvent | TouchEvent) {
e.preventDefault();
const pos = DOM.mousePos(this._el, e);
this._applyScaleToPos(pos);
if (this._lastPos.equals(pos) || (this._state === 'pending' && pos.dist(this._mouseDownPos) < this._clickTolerance)) {
return;
}
...
} This is just an example, but just to illustrate where the fix can be applied. This also works with zooming when also applied in |
Been thinking a little more about this. There are two ways we can offset a css transform: either as an option or calculating the relevant transforms within I'd normally avoid adding another option, but even if we calculate the scale within If adding another option seems better then perhaps something like this: new Map({
cssTransformScale: 0.58,
cssTransformRotate: 45 // degrees
});
// or
new Map({
cssTransform: {
scale: 0.58,
rotate: 45
}
}); If someone could guide me in the right direction I'm happy to work on a PR |
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! |
DOM.mousePos = function (el , e )
}; |
A partial fix for this was introduced with #10096 |
When emit click, zoom, touch event on map, we calculate the mouse position in map as follows:
https://github.com/mapbox/mapbox-gl-js/blob/master/src/util/dom.js#L104-L111
This process is simple like this:
The calculation is correct on most cases, except the case that we add css transform property on .mapboxgl-canvas-container. For example, we add
rotate(10deg)
If we scale or skew or even transform3d the canvas container, we also can not get the right position from
mousePos()
. The zoom, pan, touch, click behaviour will be affected:https://jsfiddle.net/jingsam/3wh5grko/25/
Try to click somewhere on the map.
This issue is also related to the same problem.
Solution
What we want from
mousePos
is the position is map space, not the viewport space or other space. Luckily, we have offsetX offsetY. CSSOM says:offsetX and offsetY are just we want. so
mousePos
should changed as follows:The text was updated successfully, but these errors were encountered: