3

(pretty new to Mapbox and JS, so I'm in a bit over my head) I'm working on a page where the user needs to adjust the size of map container. It needs to be able to get accurate bounds and center point of the resized map (via map.getBounds and map.getCenter).

When I use JS to adjust the size of the container div, the center and bounds are not adjusted. Fiddle: http://jsfiddle.net/xcow63sm/3/

Panning/zooming results in updated center and bounds. Browser window resize (if you have width or height set to 100%) works too. I would expect changing the container dimensions would adjust center and bounds.

However, if you use the form fields to adjust the height/width of the container div, the center and bounds do not. I've tried (with increasing desperation):

function resize (){
var inputwidth = document.getElementsByName("mapwidth")[0].value;
var inputheight = document.getElementsByName("mapheight")[0].value;
var mapDiv = document.getElementById('map');
var mapcenter = map.getCenter();
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
map.updateSize();
map.update();
map.resize();
map.invalidateSize();
document.getElementById("mapcenter").value = mapcenter;

Edit: this seems to apply but I can't make sense of it: Resizing a leaflet map on container resize

Awright
  • 33
  • 1
  • 5
  • Here's a variant fiddle:http://jsfiddle.net/4t9pe3mj/ - You can see there's a recalc link which calls the map.resize function. This fills in missing tiles but recenters the map on the ORIGINAL centerpoint rather than the new centerpoint in the larger/smaller div. – Awright Jul 12 '18 at 22:47

1 Answers1

5

If I understand you, you have two issues: you don't like how the map is positioned after its size changes, and you're getting white space.

Map positioning after resize

There are at least three valid options for how a map should update if, say, its width and height are suddenly doubled:

  1. keep the same northern and western bound, extend the eastern and southern bounds. (Expanding the viewing area right and down)
  2. move all four bounds outwards (keeping the centre of the map in the same place)
  3. leave all four bounds where they are are, but change the zoom, so the same geographic area is displayed, but in more detail.

I think your issue is that Mapbox is choosing option 1, but you want one of the other two options. The solution, as I think you've discovered, is simply to do your own maths and set the bounds how you want them.

Map failing to repaint correctly

Your second issue is that when you resize, calling map.resize() isn't updating the internal size of the map properly, and you're left with white space. The reason for this is you're using animated CSS properties. So when you do this:

mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
map.resize();

This doesn't work because the map's size hasn't actually transitioned to the new size yet. You can work around it like this:

mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
window.setTimeout(()=>map.resize(), 500);

There's probably a better event you can listen to, to keep updating as the map area expands.

Updated fiddle here: http://jsfiddle.net/xcow63sm/11/

Btw you should consult the documentation here. I'm not sure where you got map.updateSize() from but that's not Mapbox-GL-JS :)

Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
  • Yeah I don't know where I got that map.updateSize(), either. I was googling and throwing a lot of stuff at the wall, so to speak. Your solution is REALLY helpful-- thank you! I still don't quite grok how to reset the center point. With your fiddle, when I resize, the map jumps a bit the re-center the old center point versus getting a new center point based on the new dimensions, but I can live with that. – Awright Jul 13 '18 at 05:13
  • I'm still not clear on what behaviour you actually want? – Steve Bennett Jul 13 '18 at 05:15