I need to implement a multicolor fill in a polygon feature. The fill will be conditionally formatted according to feature properties.
Let's say that I need a polygon with a 3-color pattern like this:
let fillPalette = ['orange', 'green', 'blue'];
How is this possible in Leaflet?
In a simple div
, this could be easily achieved with the following CSS function:
background: repeating-linear-gradient(
-45deg,
orange,
orange 10px,
green 10px,
green 20px,
blue 20px,
blue 30px
);
However, Leaflet uses SVG/Canvas.
I am aware of the following plugins:
Unfortunately, the first doesn't seem to support multi-color patterns and the second supports only images.
Any ideas?
For anyone interested, here is the solution I came up with:
When we create polygon, we set fillColor
value to point to the linear-gradient we define later.
let polygon = L.polygon(coords, {fillColor: 'url(#stripes)', fillOpacity: 1})
The stripes are created using linear-gradient without color blending, like this:
let fillPalette = ['orange', 'green', 'blue'];
let gradientString = `<linearGradient id="stripes" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset=0 stop-color=${fillPalette[0]} />
<stop offset=33% stop-color=${fillPalette[0]} />
<stop offset=33% stop-color=${fillPalette[1]} />
<stop offset=66% stop-color=${fillPalette[1]} />
<stop offset=66% stop-color=${fillPalette[2]} />
<stop offset=100% stop-color=${fillPalette[2]} />
</linearGradient>`
Then we need to define the above linear-gradient inside the SVG. The SVG can be manipulated as following:
let svg = document.getElementsByTagName('svg')[0];
let svgDefs = document.createElementNS("http://www.w3.org/2000/svg", 'defs');
svgDefs.insertAdjacentHTML('afterbegin', gradientString);
svg.appendChild(svgDefs);
Here is a working fiddle: https://jsfiddle.net/oyu60f1t/