I have a Google Maps map inserted in a css-scaled container. Due to project specifics this cannot be avoided. I need to track clicks coords on this map, but being scaled map set
Ok, figured out how to correct fix (this is when transformation center is 0,0)
function point2LatLng(point, transformScale, map) {
var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
var scale = Math.pow(2, map.getZoom());
var worldPoint = new google.maps.Point(point.x / transformScale / scale + bottomLeft.x, point.y / transformScale / scale + topRight.y);
return map.getProjection().fromPointToLatLng(worldPoint);
}
gmaps.event.addListener(this.map, 'click', (event)=> {
let transformMatrix = window.getComputedStyle(this.$el.closest('.container')).transform.match(/^matrix\((.+)\)$/)[1].split(', ');
let transformScale = parseFloat(transformMatrix[0]);
var marker = new gmaps.Marker({
position: point2LatLng(event.pixel, transformScale, this.map),
map: this.map
});
});
This answer works, but being scaled map works very bad, many coordinate-related functions don't wok correctly. But there is a workaround: place the map in a virtual iframe:
const iframe = this.$el.querySelector('iframe');
iframe.contentWindow.document.open();
iframe.contentWindow.document.write('<div id="map" style="width: 100%; height: 100%"></div>');
iframe.contentWindow.document.close();
const mapContainer = iframe.contentWindow.document.querySelector('#map');
const map = new gmaps.Map(mapContainer, {
center: {lat: 48.7, lng: 31},
zoom: 6
});
There are no x-origin restrictions and you can manipulate with iframe content how you want. And with it, even if parent container is scaled, everything works fine
I also had this issue and the above solutions didn't work for me because:
However I did find a way to do it: I put the map div inside a container which I effectively un-scaled with this JS, loaded after all other JS:
//Function: Unscale the map Container
function unscaleMap(scale){
var unscale = Math.round(10000/(scale * 1))/10000,
rescale = Math.round(10000 * (100 / unscale))/10000;
document.getElementById("fs_mapContainer").style.transform = "scale("+unscale+")";
document.getElementById("fs_mapContainer").style.width = rescale + "%";
document.getElementById("fs_mapContainer").style.height = 80 * scale + "vh";
}
And CSS:
.map_container {position: relative; transform-origin: 0 0; box-sizing: border-box;}
#map {width: 100%; height: 100%}