CSS transform issue
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
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
```
DOM.mousePos = function (el: HTMLElement, e: any) {
const rect = el.getBoundingClientRect();
e = e.touches ? e.touches[0] : e;
return new Point(
e.clientX - rect.left - el.clientLeft,
e.clientY - rect.top - el.clientTop
);
};
```
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](https://github.com/mapbox/mapbox-gl-js/issues/6079) 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](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX) [offsetY](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX). [CSSOM](https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx) says:
> The offsetX attribute must follow these steps:
> 1. If the event’s dispatch flag is set, return the x-coordinate of the position where the event occurred **relative to the origin of the padding edge of the target node**, ignoring the transforms that apply to the element and its ancestors, and terminate these steps.
> 2. Return the value of the event’s pageX attribute.
offsetX and offsetY are just we want. so `mousePos` should changed as follows:
```
DOM.mousePos = function (el: HTMLElement, e: any) {
e = e.touches ? e.touches[0] : e;
return new Point(
e.offsetX,
e.offsetY
);
};
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/util/dom.js at DOM.mousePos and reproduce the transformed-container behavior using the linked JSFiddle. Check how click, zoom, touch, and pan events obtain map coordinates when CSS transforms are applied. Done means those interactions receive correct map-space positions under rotate, scale, skew, and transform3d cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, typescript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100