Edit

Image Load Events

image6 events2 loading6

Example using image load events.

Image sources fire events related to image loading. You can listen for imageloadstart, imageloadend, and imageloaderror type events to monitor image loading progress. This example registers listeners for these events and renders an image loading progress bar at the bottom of the map.

main.js
import 'ol/ol.css';
import ImageLayer from 'ol/layer/Image';
import ImageWMS from 'ol/source/ImageWMS';
import Map from 'ol/Map';
import View from 'ol/View';

/**
 * Renders a progress bar.
 * @param {HTMLElement} el The target element.
 * @class
 */
function Progress(el) {
  this.el = el;
  this.loading = 0;
  this.loaded = 0;
}

/**
 * Increment the count of loading tiles.
 */
Progress.prototype.addLoading = function () {
  if (this.loading === 0) {
    this.show();
  }
  ++this.loading;
  this.update();
};

/**
 * Increment the count of loaded tiles.
 */
Progress.prototype.addLoaded = function () {
  const this_ = this;
  setTimeout(function () {
    ++this_.loaded;
    this_.update();
  }, 100);
};

/**
 * Update the progress bar.
 */
Progress.prototype.update = function () {
  const width = ((this.loaded / this.loading) * 100).toFixed(1) + '%';
  this.el.style.width = width;
  if (this.loading === this.loaded) {
    this.loading = 0;
    this.loaded = 0;
    const this_ = this;
    setTimeout(function () {
      this_.hide();
    }, 500);
  }
};

/**
 * Show the progress bar.
 */
Progress.prototype.show = function () {
  this.el.style.visibility = 'visible';
};

/**
 * Hide the progress bar.
 */
Progress.prototype.hide = function () {
  if (this.loading === this.loaded) {
    this.el.style.visibility = 'hidden';
    this.el.style.width = 0;
  }
};

const progress = new Progress(document.getElementById('progress'));

const source = new ImageWMS({
  url: 'https://ahocevar.com/geoserver/wms',
  params: {'LAYERS': 'topp:states'},
  serverType: 'geoserver',
});

source.on('imageloadstart', function () {
  progress.addLoading();
});

source.on('imageloadend', function () {
  progress.addLoaded();
});
source.on('imageloaderror', function () {
  progress.addLoaded();
});

const map = new Map({
  layers: [new ImageLayer({source: source})],
  target: 'map',
  view: new View({
    center: [-10997148, 4569099],
    zoom: 4,
  }),
});
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Image Load Events</title>
    <!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
    <script src="https://unpkg.com/elm-pep"></script>
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL,TextDecoder,Number.isInteger"></script>
    <style>
      .map {
        width: 100%;
        height:400px;
      }
      .map {
        background: #E0ECED;
      }
      .wrapper {
        position: relative;
      }
      #progress {
        position: absolute;
        bottom: 0;
        left: 0;
        height: 2px;
        background: rgba(0, 60, 136, 0.4);
        width: 0;
        transition: width 250ms;
      }    </style>
  </head>
  <body>
    <div class="wrapper">
      <div id="map" class="map"></div>
      <div id="progress"></div>
    </div>
    <script src="main.js"></script>
  </body>
</html>
package.json
{
  "name": "image-load-events",
  "dependencies": {
    "ol": "6.6.1"
  },
  "devDependencies": {
    "parcel": "^2.0.0-beta.1"
  },
  "scripts": {
    "start": "parcel index.html",
    "build": "parcel build --public-url . index.html"
  }
}