Hide old tiles while loading new ones when zooming in Openlayers

I think there is no way to hide single tiles yet. But you can hide the complete layer while loading using this code:

// hides layer on zoom and shows it again if all tiles are loaded
function setTileHidingWhileLoadingFor(tileLayer){
    // need source to listen to tile load events
    let source = tileLayer.getSource();
    // keep track of tiles
    let tilesToHandleCount = 0;

    // handle layer source events
    source.on("tileloadstart", function(){
        tilesToHandleCount += 1;
        // make layer invisible
        tileLayer.setVisible(false);
    });

    // inner function that is used on tile load success & fail
    function decreaseTilesToHandleAndMakeLayerVisible(){
        tilesToHandleCount -= 1;
        if(tilesToHandleCount == 0){
            // make layer visible again
            tileLayer.setVisible(true);
        }
    }

    source.on("tileloadend", function(){
        decreaseTilesToHandleAndMakeLayerVisible();
    });

    source.on("tileloaderror", function(){
        decreaseTilesToHandleAndMakeLayerVisible();
    });
}

At least it is working with a simple OSM tile layer.


ol.source.[TYPE].refresh() is the closest native OL4 answer to the problem if hooked into the change:resolution event of the view and if the source is unset from the layer based on all zoom interpreted actions.

var map;
baseSource = new ol.source.OSM();
baseLayer = new ol.layer.Tile({
  name: "OSM Basemap",
  source: baseSource
});

var view = new ol.View({
  center: [0, 0],
  zoom: 2
});

map = new ol.Map({
  target: "map",
  layers: [ baseLayer],
  view: view,
  controls: [new ol.control.Zoom()]
});

$("#map .ol-zoom-in").on('click',function() {
    baseLayer.unset('source');
});
$("#map .ol-zoom-out").on('click',function() {
    baseLayer.unset('source');
});
$("#map").on('dblclick',function(){
        baseLayer.unset('source');
});
$("#map").on('wheel',function(){
        baseLayer.unset('source');
});

view.on("change:resolution", function(e) {
  if (Number.isInteger(e.target.getZoom())) {
    baseSource.refresh();
    baseLayer.setSource(baseSource);
  }
});

document.getElementById('zoom').addEventListener(
'change',
function() {view.setZoom(this.value);},
false);

This will first unset the layer source when a zoom user event is triggered - may cause false positives for now but demonstration works. Once a change of the resolution is triggered - usually through a zoom event completing - the canvas refreshes and draws with the tiles from the new zoom level.

Click here for the fiddle

While the example uses a tile layer and OSM source I can't see any reason why this wouldn't work with other layer and source types. All layers require a source to be specified (providing the "unset" and "setSource" functions) and all Sources provide the "refresh" function.