This plugin is designed to work with Maplibre GL JS and provides additional functionality for handling SVG images as icons on your map. With this plugin, you can set custom colors for your SVG icons and provide a default image for cases when no image is found.
stroke
, fill
, and color
)fill
and the white channel with stroke
. If the background color is not specified, the plugin will automatically choose white or black based on the luminance of the chosen foreground color.Dealing with icons in Maplibre has always been difficult. Sprites are really nice for loading images, but they don’t support all use cases.
Originally, the use case for this library was to recolor
raster images, since the only supported way to change an icon’s color is by using SDF. SDF files are a pain because they only accept one color, and they significantly reduce the icon quality. This library can recolor raster images. It does this by splitting the image into a black/white image and stroke maps to the white channel and fill maps to the black channel.
This library allows you to use SDFs if you want. I don’t know why you’d want to, but you can. You can also convert SVGs to SDF. One thing to note is that if you have an SDF icon in a layer, all the icons must be SDF, including the default icon, so the library will automatically convert it for you. It’s essential to pay attention to that because icon-color
from the layer paint property will also affect the color of the default icon in these situations. Even in situations where applyStyleToDefaultImage
is set to false.
This library’s primary intent now is to support SVGs in MapLibre. SVGs are vector and scale nicely, and it’s easy to add them to the browser at the current user’s pixel ratio, whatever that might be. SVGs can pick up values from CSS, so you can pass any CSS values to your SVG, including stroke
, fill
, stroke-width
, and any other CSS parameter you can think of. You can also pass color
, which maps to the special color currentColor
inside the SVG.
You can’t assign a color to the icons using the icon-color
paint value unless you’re using SDF. It would be nice if this library could override those fields, but it’s outside of the scope. So the trick is to use very long query strings directly in the icon-image
field. They typically look like this: 'icon-image': {icon}#?fill=red&stroke=blue
. There is a function called MaplibreSVGPlugin.createQueryString
that will build this query string for you, making the code more readable (see the example).
Supported values are any of the fields initial interface:
[pixelRatio
, sdf
, stretchX
, stretchY
, content
, threshold
,customTranformation
], any other values get passed in as CSS. For CSS values, tt will convert camaelCaseCss
to kebab-case-css
but you can use the kebab-case
as well, I just find it harder to read, and many libraries seem to do that converstion. So you can use strokeWidth
or stroke-width
.
You can pass your own function in so when an image is missing, you can add your own custom code. The example shows how to use this function to add a background to an existing SVG through code.
The MaplibreSVGPlugin constructor accepts the following options:
interface MaplibreSVGPluginOptions {
defaultImage: MaplibreImage | string, // Accepts any image that maplibre accepts as well as an SVG string
defaultImageOptions: { // These are all the image options directly from maplibre
pixelRatio: number; // Defaults to the current pixelRatio (via window.devicePixelRatio)
sdf: boolean; // Defaults to false
stretchX?: [number, number][] | undefined;
stretchY?: [number, number][] | undefined;
content?: [number, number, number, number] | undefined;
},
defaultColorOptions: { // This is for dealing with Recolored images only (so, raster)
threshold: number // The luminance threshold to use as the split when converting a color image to black and white, default is 55
},
customTransformations: {} // This where you can create your own functions for any missing image
[key]: {
parameters: string[],
fn: (icon: imageData (same format as defaultImage), options: {values from paramaters}, otherParameters: {all the other values in the string})
}
},
applyStyleToDefaultImage: boolean
}