Search code examples
javascriptopenlayers

Apply an openlayers filter and have it persist when I save the map as an image


I have made an openlayers map with various polylines on it. I am using the default openstreetmap layer, but would like to darken it to make my polylines stand out. I've discovered that I can do this as follows:

map.getLayers().getArray()[0].on('postcompose', function (evt) {
   evt.context.canvas.style.filter="invert(99%)";
});

However, I'd also like to give my users the ability to download this map as a PNG. For that, I am using the following code, triggered from a button click:

map.once('postcompose', function(event) {
   var canvas = event.context.canvas;
   if (navigator.msSaveBlob) {
      navigator.msSaveBlob(canvas.msToBlob(), 'mymap.png');
   } else {
      canvas.toBlob(function(blob) {
         saveAs(blob, 'mymap.png')
      });
   }
});
map.renderSync();

Unfortunately, this does not preserve the amendment I made to adjust the canvas.

Please can someone help me? Thank you for reading.


Solution

  • Setting a style filter on an element will not affect the output of toBlob() or toDataURL(). If you want to change the canvas context instead of how the browser renders the canvas you will need a globalCompositeOperation (from the code you are using I presume you are using OpenLayers 5):

    map.getLayers().getArray()[0].on('postcompose', function (evt) {
      evt.context.globalCompositeOperation = 'difference';
      evt.context.fillStyle = 'white';
      evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
      evt.context.globalCompositeOperation = 'source-over';
    });