Add loadstart and loadend map events
This commit is contained in:
@@ -26,8 +26,22 @@ export default {
|
||||
* @api
|
||||
*/
|
||||
MOVEEND: 'moveend',
|
||||
|
||||
/**
|
||||
* Triggered when loading of additional map data (tiles, images, features) starts.
|
||||
* @event module:ol/render/Event~RenderEvent#loadstart
|
||||
* @api
|
||||
*/
|
||||
LOADSTART: 'loadstart',
|
||||
|
||||
/**
|
||||
* Triggered when loading of additional map data has completed.
|
||||
* @event module:ol/render/Event~RenderEvent#loadend
|
||||
* @api
|
||||
*/
|
||||
LOADEND: 'loadend',
|
||||
};
|
||||
|
||||
/***
|
||||
* @typedef {'postrender'|'movestart'|'moveend'} Types
|
||||
* @typedef {'postrender'|'movestart'|'moveend'|'loadstart'|'loadend'} Types
|
||||
*/
|
||||
|
||||
@@ -211,10 +211,16 @@ class PluggableMap extends BaseObject {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.renderComplete_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.loaded_ = true;
|
||||
|
||||
/** @private */
|
||||
this.boundHandleBrowserEvent_ = this.handleBrowserEvent.bind(this);
|
||||
|
||||
@@ -1187,17 +1193,26 @@ class PluggableMap extends BaseObject {
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
frameState &&
|
||||
this.renderer_ &&
|
||||
this.hasListener(RenderEventType.RENDERCOMPLETE) &&
|
||||
!frameState.animate &&
|
||||
this.renderComplete_
|
||||
) {
|
||||
this.renderer_.dispatchRenderEvent(
|
||||
RenderEventType.RENDERCOMPLETE,
|
||||
frameState
|
||||
);
|
||||
if (frameState && this.renderer_ && !frameState.animate) {
|
||||
if (this.renderComplete_ === true) {
|
||||
if (this.hasListener(RenderEventType.RENDERCOMPLETE)) {
|
||||
this.renderer_.dispatchRenderEvent(
|
||||
RenderEventType.RENDERCOMPLETE,
|
||||
frameState
|
||||
);
|
||||
}
|
||||
if (this.loaded_ === false) {
|
||||
this.loaded_ = true;
|
||||
this.dispatchEvent(
|
||||
new MapEvent(MapEventType.LOADEND, this, frameState)
|
||||
);
|
||||
}
|
||||
} else if (this.loaded_ === true) {
|
||||
this.loaded_ = false;
|
||||
this.dispatchEvent(
|
||||
new MapEvent(MapEventType.LOADSTART, this, frameState)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const postRenderFunctions = this.postRenderFunctions_;
|
||||
@@ -1573,9 +1588,13 @@ class PluggableMap extends BaseObject {
|
||||
this.dispatchEvent(new MapEvent(MapEventType.POSTRENDER, this, frameState));
|
||||
|
||||
this.renderComplete_ =
|
||||
!this.tileQueue_.getTilesLoading() &&
|
||||
!this.tileQueue_.getCount() &&
|
||||
!this.getLoadingOrNotReady();
|
||||
this.hasListener(MapEventType.LOADSTART) ||
|
||||
this.hasListener(MapEventType.LOADEND) ||
|
||||
this.hasListener(RenderEventType.RENDERCOMPLETE)
|
||||
? !this.tileQueue_.getTilesLoading() &&
|
||||
!this.tileQueue_.getCount() &&
|
||||
!this.getLoadingOrNotReady()
|
||||
: undefined;
|
||||
|
||||
if (!this.postRenderTimeoutHandle_) {
|
||||
this.postRenderTimeoutHandle_ = setTimeout(() => {
|
||||
|
||||
@@ -505,6 +505,97 @@ describe('ol/Map', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadstart/loadend event sequence', function () {
|
||||
let map;
|
||||
beforeEach(function () {
|
||||
const target = document.createElement('div');
|
||||
target.style.width = '100px';
|
||||
target.style.height = '100px';
|
||||
document.body.appendChild(target);
|
||||
map = new Map({
|
||||
target: target,
|
||||
layers: [
|
||||
new TileLayer({
|
||||
opacity: 0.5,
|
||||
source: new XYZ({
|
||||
url: 'spec/ol/data/osm-{z}-{x}-{y}.png',
|
||||
}),
|
||||
}),
|
||||
new ImageLayer({
|
||||
source: new ImageStatic({
|
||||
url: 'spec/ol/data/osm-0-0-0.png',
|
||||
imageExtent: getProjection('EPSG:3857').getExtent(),
|
||||
projection: 'EPSG:3857',
|
||||
}),
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: 'spec/ol/data/point.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: 'spec/ol/data/point.json',
|
||||
format: new GeoJSON(),
|
||||
strategy: tileStrategy(createXYZ()),
|
||||
}),
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [new Feature(new Point([0, 0]))],
|
||||
}),
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: new VectorSource({
|
||||
loader: function (extent, resolution, projection) {
|
||||
this.addFeature(new Feature(new Point([0, 0])));
|
||||
},
|
||||
}),
|
||||
}),
|
||||
new WebGLPointsLayer({
|
||||
source: new VectorSource({
|
||||
features: [new Feature(new Point([0, 0]))],
|
||||
}),
|
||||
style: {
|
||||
symbol: {
|
||||
color: 'red',
|
||||
symbolType: 'circle',
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
document.body.removeChild(map.getTargetElement());
|
||||
map.setTarget(null);
|
||||
map.dispose();
|
||||
map.getLayers().forEach((layer) => layer.dispose());
|
||||
});
|
||||
|
||||
it('is a reliable start-end sequence', function (done) {
|
||||
const layers = map.getLayers().getArray();
|
||||
expect(layers[6].getRenderer().ready).to.be(false);
|
||||
let loading = 0;
|
||||
map.on('loadstart', () => {
|
||||
map.getView().setZoom(0.1);
|
||||
loading++;
|
||||
});
|
||||
map.on('loadend', () => {
|
||||
expect(loading).to.be(1);
|
||||
done();
|
||||
});
|
||||
map.setView(
|
||||
new View({
|
||||
center: [0, 0],
|
||||
zoom: 0,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getFeaturesAtPixel', function () {
|
||||
let target, map, layer;
|
||||
beforeEach(function () {
|
||||
|
||||
Reference in New Issue
Block a user