简体   繁体   中英

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

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 ?

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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM