1

I am switching between image overlay layers upon user entry (through a slider).

Every time users get into this loop, a fast blink (with white background) is displaying, meaning that the old layer is removed before the new one finished rendering. I was relying on the "load" event, but it seems not affordable. It looks like the "load" event (fired by the added overlay image) is fired before the load completes.

mymap.addLayer(overlay[newlyr]);
overlay[newlyr].once("load",function() { 
    mymap.removeLayer(overlay[oldlyr]); 
    });

In other applications I have verified that the "load" event is very reliable for tile Layers, but it isn't at all for Image Overlays. I hope I am doing something wrong.

Any tip?

0

2 Answers 2

1

I do not get any blinking.

https://plnkr.co/edit/nIdNwTpDjZNhyiCzGJPC?p=preview

var current = L.imageOverlay(url1, bounds).addTo(map);
var next = L.imageOverlay(url2, bounds);

setTimeout(swapImgs, 1000); // Just to swap without user action.

function swapImgs() {
  console.log('swap! ' + new Date());
  // Workaround for the fact that "load" event fires only the very first time,
  // when the browser has fetched the image from network.
  // After that, the browser serves from its cache and does not fire "load".
  // But the <img> element now has the `complete` property true.
  if (next.getElement() && next.getElement().complete) {
    map.addLayer(next);
    removeCurrent();
  } else {
    next.once('load', function() {
      removeCurrent();
    });
    map.addLayer(next);
  }
}

function removeCurrent() {
  map.removeLayer(current);

  // Just to implement the swapping.
  var swap = current;
  current = next;
  next = swap;
  setTimeout(swapImgs, 1000);
}
6
  • yes. Maybe my user is moving the slider too fast... With a 1 sec timeout it is ok. Nov 16, 2017 at 11:21
  • Looking at your code, I think that the part within if (next.loaded) is never executed... When you ask to swap, next image is not yet loaded. What that check is for? Nov 16, 2017 at 11:30
  • You can decrease the delay between swaps. Even at 100ms I still do not get white blinking? (well, kinda hard to see as the map is blinking between 2 images…)
    – ghybs
    Nov 16, 2017 at 11:41
  • As for the loaded property trick, it is a workaround for the fact that "load" event fires only after the browser fetches the image from the network. Once it is in cache, it no longer fires the event. You could instead check the complete property. See stackoverflow.com/questions/3877027/… or mikefowler.me/journal/2014/04/22/cached-images-load-event for example.
    – ghybs
    Nov 16, 2017 at 11:42
  • 1
    I have edited the above code and live example to use the standard complete property on the <img> element, instead of the custom loaded property.
    – ghybs
    Nov 16, 2017 at 11:50
1

I've got similar problem. When I drag map and then drop it - imageOverlay starts loading only when I add it to map. I ended up with such code (I force loading image before adding it to map):

    let imageLayer = L.imageOverlay(imageUrl, imageBounds)

    imageLayer._initImage()

    imageLayer.once('load', () => {
        that.map.eachLayer(function (layer) {
           that.map.removeLayer(layer);
        });

        imageLayer.addTo(that.map)
     });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.