Image Load Events

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.

<!DOCTYPE html>
<html>
  <head>
    <title>Image Load Events</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v4.6.4/css/ol.css" type="text/css">
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://openlayers.org/en/v4.6.4/build/ol.js"></script>
    <style>
      .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>
      /**
       * Renders a progress bar.
       * @param {Element} el The target element.
       * @constructor
       */
      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() {
        var this_ = this;
        setTimeout(function() {
          ++this_.loaded;
          this_.update();
        }, 100);
      };


      /**
       * Update the progress bar.
       */
      Progress.prototype.update = function() {
        var width = (this.loaded / this.loading * 100).toFixed(1) + '%';
        this.el.style.width = width;
        if (this.loading === this.loaded) {
          this.loading = 0;
          this.loaded = 0;
          var 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;
        }
      };

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

      var source = new ol.source.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();
      });

      var map = new ol.Map({
        logo: false,
        layers: [
          new ol.layer.Image({source: source})
        ],
        target: 'map',
        view: new ol.View({
          center: [-10997148, 4569099],
          zoom: 4
        })
      });
    </script>
  </body>
</html>