Styling feature with CanvasGradient or CanvasPattern

This example uses OpenLayers v4.0.1. The latest is v.

#### Styling feature with CanvasGradient or CanvasPattern

Example showing the countries vector layer styled with patterns and gradients.

First this example creates a reusable `CanvasPattern` and a `CanvasGradient`. The countries are loaded from a GeoJSON file. A style function determines for each country whether to use a fill with the pregenerated CanvasGradient (rainbow colors) or a CanvasPattern (repeating stacked circles).

Related API documentation:

- ol.Map
,
- ol.View
,
- ol.extent
,
- ol.format.GeoJSON
,
- ol.has
,
- ol.layer.Vector
,
- ol.proj
,
- ol.source.Vector
,
- ol.style.Fill
,
- ol.style.Stroke
,
- ol.style.Style

Copy Edit
Styling feature with CanvasGradient or CanvasPattern Example showing the countries vector layer styled with patterns and gradients. var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); // Gradient and pattern are in canvas pixel space, so we adjust for the // renderer's pixel ratio var pixelRatio = ol.has.DEVICE_PIXEL_RATIO; // Generate a rainbow gradient function gradient(feature, resolution) { var extent = feature.getGeometry().getExtent(); // Gradient starts on the left edge of each feature, and ends on the right. // Coordinate origin is the top-left corner of the extent of the geometry, so // we just divide the geometry's extent width by resolution and multiply with // pixelRatio to match the renderer's pixel coordinate system. var grad = context.createLinearGradient(0, 0, ol.extent.getWidth(extent) / resolution * pixelRatio, 0); grad.addColorStop(0, 'red'); grad.addColorStop(1 / 6, 'orange'); grad.addColorStop(2 / 6, 'yellow'); grad.addColorStop(3 / 6, 'green'); grad.addColorStop(4 / 6, 'aqua'); grad.addColorStop(5 / 6, 'blue'); grad.addColorStop(1, 'purple'); return grad; } // Generate a canvasPattern with two circles on white background var pattern = (function() { canvas.width = 11 * pixelRatio; canvas.height = 11 * pixelRatio; // white background context.fillStyle = 'white'; context.fillRect(0, 0, canvas.width, canvas.height); // outer circle context.fillStyle = 'rgba(102, 0, 102, 0.5)'; context.beginPath(); context.arc(5 * pixelRatio, 5 * pixelRatio, 4 * pixelRatio, 0, 2 * Math.PI); context.fill(); // inner circle context.fillStyle = 'rgb(55, 0, 170)'; context.beginPath(); context.arc(5 * pixelRatio, 5 * pixelRatio, 2 * pixelRatio, 0, 2 * Math.PI); context.fill(); return context.createPattern(canvas, 'repeat'); }()); // Generate style for gradient or pattern fill var fill = new ol.style.Fill(); var style = new ol.style.Style({ fill: fill, stroke: new ol.style.Stroke({ color: '#333', width: 2 }) }); /** * The styling function for the vector layer, will return an array of styles * which either contains the aboove gradient or pattern. * * @param {ol.Feature} feature The feature to style. * @param {number} resolution Resolution. * @return {ol.style.Style} The style to use for the feature. */ var getStackedStyle = function(feature, resolution) { var id = feature.getId(); fill.setColor(id > 'J' ? gradient(feature, resolution) : pattern); return style; }; // Create a vector layer that makes use of the style function above… var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ url: 'https://openlayers.org/en/v4.0.1/examples/data/geojson/countries.geojson', format: new ol.format.GeoJSON() }), style: getStackedStyle }); // … finally create a map with that layer. var map = new ol.Map({ layers: [ vectorLayer ], target: 'map', view: new ol.View({ center: ol.proj.fromLonLat([7, 52]), zoom: 3 }) }); #map { /* Image craeted by tatyana, from https://sftextures.com/2014/10/22/blue-sky-with-blurred-white-clouds-seamless-textures/ */ background-image: url(data:image/jpeg;base64,[encoded data, 28474 characters]==); background-repeat: repeat; } <div id="map" class="map"></div>

    <!DOCTYPE html>
    <html>
      <head>
        <title>Styling feature with CanvasGradient or CanvasPattern</title>
        <link rel="stylesheet" href="https://openlayers.org/en/v4.0.1/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.0.1/build/ol.js"></script>
        <style>
          #map {
            /* Image craeted by tatyana, from https://sftextures.com/2014/10/22/blue-sky-with-blurred-white-clouds-seamless-textures/ */
            background-image: url(data:image/jpeg;base64,[encoded data, 28474 characters]==);
            background-repeat: repeat;
          }
        </style>
      </head>
      <body>
        <div id="map" class="map"></div>
        <script>
          var canvas = document.createElement('canvas');
          var context = canvas.getContext('2d');

          // Gradient and pattern are in canvas pixel space, so we adjust for the
          // renderer's pixel ratio
          var pixelRatio = ol.has.DEVICE_PIXEL_RATIO;

          // Generate a rainbow gradient
          function gradient(feature, resolution) {
            var extent = feature.getGeometry().getExtent();
            // Gradient starts on the left edge of each feature, and ends on the right.
            // Coordinate origin is the top-left corner of the extent of the geometry, so
            // we just divide the geometry's extent width by resolution and multiply with
            // pixelRatio to match the renderer's pixel coordinate system.
            var grad = context.createLinearGradient(0, 0,
                ol.extent.getWidth(extent) / resolution * pixelRatio, 0);
            grad.addColorStop(0, 'red');
            grad.addColorStop(1 / 6, 'orange');
            grad.addColorStop(2 / 6, 'yellow');
            grad.addColorStop(3 / 6, 'green');
            grad.addColorStop(4 / 6, 'aqua');
            grad.addColorStop(5 / 6, 'blue');
            grad.addColorStop(1, 'purple');
            return grad;
          }

          // Generate a canvasPattern with two circles on white background
          var pattern = (function() {
            canvas.width = 11 * pixelRatio;
            canvas.height = 11 * pixelRatio;
            // white background
            context.fillStyle = 'white';
            context.fillRect(0, 0, canvas.width, canvas.height);
            // outer circle
            context.fillStyle = 'rgba(102, 0, 102, 0.5)';
            context.beginPath();
            context.arc(5 * pixelRatio, 5 * pixelRatio, 4 * pixelRatio, 0, 2 * Math.PI);
            context.fill();
            // inner circle
            context.fillStyle = 'rgb(55, 0, 170)';
            context.beginPath();
            context.arc(5 * pixelRatio, 5 * pixelRatio, 2 * pixelRatio, 0, 2 * Math.PI);
            context.fill();
            return context.createPattern(canvas, 'repeat');
          }());

          // Generate style for gradient or pattern fill
          var fill = new ol.style.Fill();
          var style = new ol.style.Style({
            fill: fill,
            stroke: new ol.style.Stroke({
              color: '#333',
              width: 2
            })
          });

          /**
           * The styling function for the vector layer, will return an array of styles
           * which either contains the aboove gradient or pattern.
           *
           * @param {ol.Feature} feature The feature to style.
           * @param {number} resolution Resolution.
           * @return {ol.style.Style} The style to use for the feature.
           */
          var getStackedStyle = function(feature, resolution) {
            var id = feature.getId();
            fill.setColor(id > 'J' ? gradient(feature, resolution) : pattern);
            return style;
          };

          // Create a vector layer that makes use of the style function above…
          var vectorLayer = new ol.layer.Vector({
            source: new ol.source.Vector({
              url: 'https://openlayers.org/en/v4.0.1/examples/data/geojson/countries.geojson',
              format: new ol.format.GeoJSON()
            }),
            style: getStackedStyle
          });

          // … finally create a map with that layer.
          var map = new ol.Map({
            layers: [
              vectorLayer
            ],
            target: 'map',
            view: new ol.View({
              center: ol.proj.fromLonLat([7, 52]),
              zoom: 3
            })
          });
        </script>
      </body>
    </html>