Reputation: 811
I'm trying to implement a single-layer in mapbox-GL that shows icons which change when clicked. So far I've attempted the following:
Use a property (after pre-loading the images as active and inactive):
'icon-image': ["case",["boolean", ["feature-state", "clicked"], false],
"inactive",
"active"
],
And various versions of map.updateImage() to dynamically change the image that is displayed for each point:
map.updateImage(`point1`, map.loadImage('/img/pin_active.png'))
map.updateImage(`point1`, 'active')) //with the image being loaded beforehand as 'active'
map.updateImage(`point1`, map.loadImage('/img/pin_active.png', function(error, image) {
if (error) throw error;
map.addImage(point1, image);
}))
The only solution that does work is using SDF (mapbox gl change icon color) - but this does not work for my icons, which are multi-color (and they get pretty ugly since the SDF format seems to scale badly).
Any ideas on how to approach this?
Upvotes: 1
Views: 2526
Reputation: 811
Ok, so after a bit of extra fiddling around I found a working solution. Just leaving this here for whoever finds it later.
If we load the images beforehand as strings active and inactive:
map.loadImage('/img/pin_blue.png', function(error, image) {
if (error) throw error;
map.addImage('inactive', image);
})
map.loadImage('/img/pin_red.png', function(error, image) {
if (error) throw error;
map.addImage('active', image);
})
we can do the following:
let data = {} // object that stores the geojson data
let points = map.queryRenderedFeatures(e.point, {
layers: ['projects-point']
})
if (points.length) {
data.map(function(item, index) {
if (item.id === points[0].id) {
data[index].properties.image = 'active'
}
else
data[index].properties.image = 'inactive'
})
map.getSource('projects').setData(this.dataObj.data)
}
Upvotes: 2