Openlayers3: How to add a colored border around a marker icon?

这一生的挚爱 提交于 2019-12-12 05:59:42

问题


OpenLayers 3 renders's its marker icons as images on a canvas. Markers can have transparent background with non regular image icon. Is it possible to add a colored border of specific thickness and color using ol.interaction.Select?


回答1:


So I was able to achieve this by modifying the Icon Pixel Operations example on the OpenLayers website. It is possible to work with the icon image canvas in the styleFunction that ol.interaction.select provides, and first create a colored fill of the same shape as icon, and then write icon back on it, essentially giving a colored border to the icon. Which looks like this:

Non Active State:

Working CodePen.

Here's the modified style function :

style: function(feature) {
    var image = feature.get('style').getImage().getImage();

      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      var activeColor = "red"; //set border color
      var dArr = [-1,-1, 0,-1, 1,-1, -1,0, 1,0, -1,1, 0,1, 1,1], // offset array
          s = 2,  // thickness scale
          i = 0,  // iterator
          x = 2,  // final x position
          y = 2;  // final y position

      //set new canvas dimentions adjusted for border
      canvas.width = image.width + s + s;
      canvas.height = image.height + s + s;

      // draw images at offsets from the array scaled by s
      for(; i < dArr.length; i += 2)
      ctx.drawImage(image, x + dArr[i]*s, y + dArr[i+1]*s);

      // fill with color
      ctx.globalCompositeOperation = "source-in";
      ctx.fillStyle = activeColor;
      ctx.fillRect(0,0,canvas.width, canvas.height);

      // draw original image in normal mode
      ctx.globalCompositeOperation = "source-over";
      ctx.drawImage(image, x, y,image.width, image.height);

      //create new openlayers icon style from canvas
      return new ol.style.Style({
          image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
          crossOrigin: 'anonymous',
          src: undefined,
          img: canvas,
          imgSize: canvas ? [canvas.width, canvas.height] : undefined
        }))
      });

  }

Full Code:

function createStyle(src, img) {
  return new ol.style.Style({
    image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
      crossOrigin: 'anonymous',
      src: src,
      img: img,
      imgSize: img ? [img.width, img.height] : undefined
    }))
  });
}

var iconFeature = new ol.Feature(new ol.geom.Point([0, 0]));
iconFeature.set('style', createStyle('https://openlayers.org/en/v4.2.0/examples/data/icon.png', undefined));

var map = new ol.Map({
  layers: [
     new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    new ol.layer.Vector({
      style: function(feature) {
        return feature.get('style');
      },
      source: new ol.source.Vector({features: [iconFeature]})
    })
  ],
  target: document.getElementById('map'),
  view: new ol.View({
    center: [0, 0],
    zoom: 3
  })
});


var select = new ol.interaction.Select({
  style: function(feature) {
    var image = feature.get('style').getImage().getImage();

      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      var activeColor = "red"; //set border color
      var dArr = [-1,-1, 0,-1, 1,-1, -1,0, 1,0, -1,1, 0,1, 1,1], // offset array
          s = 2,  // thickness scale
          i = 0,  // iterator
          x = 2,  // final x position
          y = 2;  // final y position
      
      //set new canvas dimentions adjusted for border
      canvas.width = image.width + s + s;
      canvas.height = image.height + s + s;
    
      // draw images at offsets from the array scaled by s
      for(; i < dArr.length; i += 2)
      ctx.drawImage(image, x + dArr[i]*s, y + dArr[i+1]*s);
    
      // fill with color
      ctx.globalCompositeOperation = "source-in";
      ctx.fillStyle = activeColor;
      ctx.fillRect(0,0,canvas.width, canvas.height);
    
      // draw original image in normal mode
      ctx.globalCompositeOperation = "source-over";
      ctx.drawImage(image, x, y,image.width, image.height);
    
      //create new openlayers icon style from canvas
      return new ol.style.Style({
          image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
          crossOrigin: 'anonymous',
          src: undefined,
          img: canvas,
          imgSize: canvas ? [canvas.width, canvas.height] : undefined
        }))
      });
    
  }
});
map.addInteraction(select);
<link href="https://openlayers.org/en/v4.2.0/css/ol.css" rel="stylesheet"/>
<script src="https://openlayers.org/en/v4.2.0/build/ol.js"></script>

<div id="map" class="map"></div>


来源:https://stackoverflow.com/questions/44738247/openlayers3-how-to-add-a-colored-border-around-a-marker-icon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!