0

I've added an image overlay to a non-geographical map using Leaflet.js and CRS.Simple for positioning. When I call map.fitToBounds(bounds) the image overlay is initially displayed mostly off screen, but if the browser window is resized (presumably triggering a reflow) it pops into the expected position.

What I Did

The relevant lines of code used to generate the map:

let map = L.map('floorplan', { crs: L.CRS.Simple });
const imageUrl = floorplanUrl;
const imageBounds = [[0, 0], [1000, 1000]];
L.imageOverlay(imageUrl, imageBounds).addTo(map);
map.fitBounds(imageBounds);

Expected:

The whole floorplan image is displayed on the screen and fills the map area.

Actual:

Most of the floorplan image initially appears off screen, but moves into the expected position if the browser window is resized. (Tried in both Firefox and Chrome).

Image overlay displayed off screen:

Image overlay off screen

Image overlay after resizing browser window:

enter image description here

I can work around this by manually dispatching a resize event on the window object:

const event = new Event('resize');
window.dispatchEvent(event);

But I suspect I'm doing something wrong, either misunderstanding the coordinate system, or maybe there's some interference with some other CSS on the page.

I've noticed that the difference between the first state and the second state is that in the second state a 3D CSS transform is added to the div with classes leaflet-pane and leaflet-map-pane:

transform: translate3d(530px, 248px, 0px);

What am I doing wrong?

benfrancis
  • 391
  • 2
  • 4
  • Without the complete code it's guesswork, but one of the possible issues is that the code is invoked too soon. The leaflet code has to be called afgter the document is fully loaded. Make sure to check if that's the case. I'm also assuming this code runs inside a good old static page. – svrbst Mar 08 '23 at 11:23
  • Likely a duplicate of https://stackoverflow.com/a/20402399/4768502 – IvanSanchez Mar 08 '23 at 12:00
  • I think you were both right svrbst and IvanSanchez, the size of the map was being set before content had fully loaded. A more isolated workaround from stackoverflow.com/a/20402399/4768502 : ``` map.whenReady(() => { setTimeout(() => { map.invalidateSize(); }, 0); }); ``` This is a bit of a hack but unfortunately waiting for `DOMContentLoaded` or `load` events does not seem to work. – benfrancis Mar 08 '23 at 16:02

1 Answers1

1

Thanks to @svrbst and @IvanSanchez.

The size of the map was being set before content had fully loaded.

A more isolated workaround from stackoverflow.com/a/20402399/4768502 :

    map.whenReady(() => {
        setTimeout(() => {
            map.invalidateSize();
        }, 0);
    });

This is a bit of a hack but unfortunately waiting for DOMContentLoaded or load events does not seem to work.

benfrancis
  • 391
  • 2
  • 4