This is possible, but there is no out-of-the-box solution. You have to create your own plugin, which combines leaflet-tilelayer-mask
and Leaflet.TileLayer.ColorFilter
plugins.
New plugin, let's name it L.TileLayer.ColorFilterMask
, is created by extending L.TileLayer.ColorFilter
instead of L.TileLayer
when creating new mask plugin.
Code in leaflet-tilelayer-mask.js
has to be modified in three places. First initial definition line:
L.TileLayer.ColorFilterMask = L.TileLayer.ColorFilter.extend({
Then we insert color filter at the end of _initContainer
method:
_initContainer: function() {
.
.
.
this._container.style.filter = this.colorFilter();
},
Then at the end layer creation function is modified:
L.tileLayer.colorFilterMask = function(url, options) {
return new L.TileLayer.ColorFilterMask(url, options);
};
When linking plugin modules, first leaflet-tilelayer-colorfilter.js
has to be linked and then newly created leaflet-tilelayer-mask.js
.
Colored mask layer is then created simply by:
let sampleFilter = [
'bright:85%',
'hue:83deg',
'saturate:97%'
];
let coloredMask = L.tileLayer.colorFilterMask('https://{s}.tile.thunderforest.com/pioneer/{z}/{x}/{y}.png?apikey=xxxxxxxxxxxxxxxx', {
maskSize: 512,
filter: sampleFilter,
maxZoom: 18,
maxNativeZoom: 17
}).addTo(map);
Here is working JSFiddle: https://jsfiddle.net/TomazicM/w0z1t8L6/
EDIT: After some more testing this solution seems to be working only in Firefox. Reason for this is that mask plugin does not create it's masked layer in <div>
element but in <svg>
element that contains <image>
links to layer tiles. Color filter is then applied to this layer through style
attribute, for example style="filter: brightness(85%) hue-rotate(83deg) saturate(97%);"
. This kind of filter works for <svg>
with embedded images only in Firefox. I tried also with -webkit-filter
, but it didn't help.
This problem can be solved with a little dirty trick of creating separate map pane for masked layer and then instead of applying color filter through combined mask and color filter plugin, just using mask plugin and then applying color filter through map pane style.
So there is no need to use color filter plugin, just mask plugin and setting color filter on map pane element style:
let myPane = map.createPane('my-pane');
myPane.style.filter = 'brightness(85%) hue-rotate(83deg) saturate(97%)';
let mask = L.tileLayer.mask('https://{s}.tile.thunderforest.com/pioneer/{z}/{x}/{y}.png?apikey=xxxxxxxxxxxxxxxx', {
maskSize: 512,
maxZoom: 18,
maxNativeZoom: 17,
pane: 'my-pane'
}).addTo(map);
filter
option, where you specify your color filter.