CSS缩放Google Maps导致InfoWindow位置异常问题求助
Hey there! Let's dig into why your InfoWindow is misbehaving when using CSS zoom:2 to simulate 20+ level scaling in Google Maps, and how to fix it.
The Root Cause
When you apply zoom:2 to the map container, you're visually scaling the entire map element—but Google Maps API still calculates all positions (like your InfoWindow's placement) based on the original, un-scaled map dimensions. This mismatch between the visual scale and the API's coordinate system causes the InfoWindow to appear in the wrong spot.
Step-by-Step Fix
We'll adjust both the click event handling and InfoWindow rendering to account for the CSS zoom factor:
1. Track the Current Zoom Factor
First, add a variable to keep track of whether we're using CSS zoom, and update your wheel event to prevent conflicting map actions:
let zoomFactor = 1; // Tracks if we're using CSS zoom (1 = normal, 2 = scaled) window.addEventListener('wheel', function (event) { const mapContainer = $('#map > div').eq(0); if (event.deltaY < 0) { // Zoom in: switch to CSS zoom at max map zoom level (20) if (map.getZoom() === 20 && zoomFactor === 1) { event.preventDefault(); // Stop default map zoom to avoid conflicts mapContainer.addClass("zoom"); zoomFactor = 2; // Reset map center to avoid visual shift map.setCenter(map.getCenter()); } } else if (event.deltaY > 0) { // Zoom out: revert from CSS zoom first if (zoomFactor === 2) { event.preventDefault(); // Stop default map zoom mapContainer.removeClass("zoom"); zoomFactor = 1; map.setCenter(map.getCenter()); } // Allow normal map zoom when not using CSS scaling } });
2. Correct InfoWindow Position
Modify your click event to adjust the coordinates based on the zoom factor, then fix the InfoWindow's visual scale:
google.maps.event.addListener(map, "click", function (mapsMouseEvent) { let position = mapsMouseEvent.latLng; const projection = map.getProjection(); // Adjust coordinates if using CSS zoom if (zoomFactor === 2) { // Convert latLng to pixel coordinates relative to the map const pixel = projection.fromLatLngToDivPixel(position); // Reverse the CSS zoom effect to get the correct original pixel position const adjustedPixel = new google.maps.Point(pixel.x / zoomFactor, pixel.y / zoomFactor); // Convert back to latLng for accurate InfoWindow placement position = projection.fromDivPixelToLatLng(adjustedPixel); } infowindow.setPosition(position); infowindow.setContent("test"); infowindow.open(map); // Fix InfoWindow's visual scale (it gets scaled by CSS zoom too!) google.maps.event.addListenerOnce(infowindow, 'domready', function () { const infoWindowWrapper = $('.gm-style-iw').parent().parent(); if (zoomFactor === 2) { infoWindowWrapper.css({ 'transform': 'scale(0.5)', 'transform-origin': 'top left' }); } else { infoWindowWrapper.css('transform', 'none'); } }); });
3. Keep Your Existing CSS
Your original CSS stays the same:
.zoom { zoom: 2; }
How This Works
- We track when we're using CSS zoom to avoid conflicting with Google Maps' native zoom behavior.
- When clicking the map, we convert the clicked coordinates to pixels, reverse the CSS zoom effect, then convert back to geographic coordinates—so the InfoWindow targets the exact spot the user clicked.
- We also adjust the InfoWindow's scale with
transform: scale(0.5)to counteract the CSS zoom, ensuring it doesn't look oversized.
内容的提问来源于stack exchange,提问作者Safa Tunç

