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.