在 Mapbox GL JS 中悬停(符号层)时更改图标不透明度
Change icon opacity when hover(symbol layer), in Mapbox GL JS
我在文档中看到 icon-opacity 支持功能状态,
https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-symbol-icon-opacity
因此我使用此代码在用户将鼠标悬停在图标上时更改不透明度:
map.addLayer({
type: 'symbol',
layout: {
'icon-image': 'point',
...
},
paint: {
'icon-opacity':
['case', ['boolean', ['feature-state','hover'], false], 1, 0.3]
}
});
问题是它采用了原始的不透明度(0.3),但在悬停时不会改变。
有什么想法吗?
谢谢。
您发布的代码是正确的,但这只是解决方案的一半。
您已经为任何功能实现了图层绘制行为的定义(如您所说,默认为 0.3),第二部分是将鼠标悬停时的 feature-state 悬停更改为 true。
符号层中 'hover' 上的特征状态不会自动更改,您需要在 map.on('mousemove', 'youLayerId'...
方法中将其更改为 true,并在 map.on('mouseout', 'youLayerId'...
.
查看我在 how to change opacity of an icon 上为您创建的 fiddle。
相关代码如下
mapboxgl.accessToken = 'PUT HERE YOUR TOKEN';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11'
});
let fHover = null;
map.on('load', function() {
map.loadImage(
'https://upload.wikimedia.org/wikipedia/commons/7/7c/201408_cat.png',
function(error, image) {
if (error) throw error;
map.addImage('cat', image);
map.addSource('point', {
'type': 'geojson',
'generateId': true,
'data': {
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [0, 0]
}
}]
}
});
map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'point',
'layout': {
'icon-image': 'cat',
'icon-size': 0.25,
},
'paint': {
'icon-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1,
0.3
]
}
});
}
);
map.on('mousemove', 'points', function(e) {
if (e.features[0]) {
mouseover(e.features[0]);
} else {
mouseout();
}
});
map.on('mouseout', 'points', function(e) {
mouseout();
});
function mouseover(feature) {
fHover = feature;
map.getCanvasContainer().style.cursor = 'pointer';
map.setFeatureState({
source: 'point',
id: fHover.id
}, {
hover: true
});
}
function mouseout() {
if (!fHover) return;
map.getCanvasContainer().style.cursor = 'default';
map.setFeatureState({
source: 'point',
id: fHover.id
}, {
hover: false
});
fHover = null;
}
});
重要的是,要更改功能状态,每个功能都必须在源中有一个 id,所以我强烈建议在 addSource
方法中始终设置 'generateId': true
。
PS.- 如果这个答案解决了您的问题,请将其标记为已接受答案,这样也可以帮助其他用户知道这是正确的解决方案。
我在文档中看到 icon-opacity 支持功能状态, https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-symbol-icon-opacity
因此我使用此代码在用户将鼠标悬停在图标上时更改不透明度:
map.addLayer({
type: 'symbol',
layout: {
'icon-image': 'point',
...
},
paint: {
'icon-opacity':
['case', ['boolean', ['feature-state','hover'], false], 1, 0.3]
}
});
问题是它采用了原始的不透明度(0.3),但在悬停时不会改变。
有什么想法吗?
谢谢。
您发布的代码是正确的,但这只是解决方案的一半。
您已经为任何功能实现了图层绘制行为的定义(如您所说,默认为 0.3),第二部分是将鼠标悬停时的 feature-state 悬停更改为 true。
符号层中 'hover' 上的特征状态不会自动更改,您需要在 map.on('mousemove', 'youLayerId'...
方法中将其更改为 true,并在 map.on('mouseout', 'youLayerId'...
.
查看我在 how to change opacity of an icon 上为您创建的 fiddle。
相关代码如下
mapboxgl.accessToken = 'PUT HERE YOUR TOKEN';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11'
});
let fHover = null;
map.on('load', function() {
map.loadImage(
'https://upload.wikimedia.org/wikipedia/commons/7/7c/201408_cat.png',
function(error, image) {
if (error) throw error;
map.addImage('cat', image);
map.addSource('point', {
'type': 'geojson',
'generateId': true,
'data': {
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [0, 0]
}
}]
}
});
map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'point',
'layout': {
'icon-image': 'cat',
'icon-size': 0.25,
},
'paint': {
'icon-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1,
0.3
]
}
});
}
);
map.on('mousemove', 'points', function(e) {
if (e.features[0]) {
mouseover(e.features[0]);
} else {
mouseout();
}
});
map.on('mouseout', 'points', function(e) {
mouseout();
});
function mouseover(feature) {
fHover = feature;
map.getCanvasContainer().style.cursor = 'pointer';
map.setFeatureState({
source: 'point',
id: fHover.id
}, {
hover: true
});
}
function mouseout() {
if (!fHover) return;
map.getCanvasContainer().style.cursor = 'default';
map.setFeatureState({
source: 'point',
id: fHover.id
}, {
hover: false
});
fHover = null;
}
});
重要的是,要更改功能状态,每个功能都必须在源中有一个 id,所以我强烈建议在 addSource
方法中始终设置 'generateId': true
。
PS.- 如果这个答案解决了您的问题,请将其标记为已接受答案,这样也可以帮助其他用户知道这是正确的解决方案。