学习目标掌握创建悬停效果的实现方法理解相关API的使用能够独立完成类似功能开发MapLibre GL JS 从入门到精通 - 130实战案例 核心概念创建悬停效果以突出显示要素。 完 整 代 码代码示例constmapnewmaplibregl.Map({container:map,style:https://demotiles.maplibre.org/style.json,center:[-100.486052,37.830348],zoom:2});lethoveredStateIdnull;map.on(load,(){map.addSource(states,{type:geojson,data:https://maplibre.org/maplibre-gl-js/docs/assets/us_states.geojson});// 依赖要素状态的填充透明度表达式将在悬停状态设置为true时渲染悬停效果。map.addLayer({id:state-fills,type:fill,source:states,layout:{},paint:{fill-color:#627BC1,fill-opacity:[case,[boolean,[feature-state,hover],false],1,0.5]}});map.addLayer({id:state-borders,type:line,source:states,layout:{},paint:{line-color:#627BC1,line-width:2}});// 当用户将鼠标移到state-fill图层上方时我们将更新// 鼠标下方要素的要素状态。map.on(mousemove,state-fills,(e){if(e.features.length0){if(hoveredStateId){map.setFeatureState({source:states,id:hoveredStateId},{hover:false});}hoveredStateIde.features[0].id;map.setFeatureState({source:states,id:hoveredStateId},{hover:true});}});// 当鼠标离开state-fill图层时更新之前悬停要素的要素状态。map.on(mouseleave,state-fills,(){if(hoveredStateId){map.setFeatureState({source:states,id:hoveredStateId},{hover:false});}hoveredStateIdnull;});});代码示例!DOCTYPEhtmlhtmllangenheadtitleCreate a hover effect/titlemetapropertyog:descriptioncontent使用事件和要素状态创建每个要素的悬停效果。/metapropertyog:createdcontent2006-06-25/metacharsetutf-8metanameviewportcontentwidthdevice-width, initial-scale1linkrelstylesheethrefhttps://unpkg.com/maplibre-gl5.24.0/dist/maplibre-gl.css/scriptsrchttps://unpkg.com/maplibre-gl5.24.0/dist/maplibre-gl.js/scriptstylebody{margin:0;padding:0;}html, body, #map{height:100%;}/style/headbodydividmap/divscriptconstmapnewmaplibregl.Map({container:map,style:https://demotiles.maplibre.org/style.json,center:[-100.486052,37.830348],zoom:2});lethoveredStateIdnull;map.on(load,(){map.addSource(states,{type:geojson,data:https://maplibre.org/maplibre-gl-js/docs/assets/us_states.geojson});// 依赖要素状态的fill-opacity表达式将在要素的// 悬停状态设置为true时呈现悬停效果。map.addLayer({id:state-fills,type:fill,source:states,layout:{},paint:{fill-color:#627BC1,fill-opacity:[case,[boolean,[feature-state,hover],false],1,0.5]}});map.addLayer({id:state-borders,type:line,source:states,layout:{},paint:{line-color:#627BC1,line-width:2}});// 当用户将鼠标移动到state-fill图层上时我们将更新// 鼠标下要素的要素状态。map.on(mousemove,state-fills,(e){if(e.features.length0){if(hoveredStateId){map.setFeatureState({source:states,id:hoveredStateId},{hover:false});}hoveredStateIde.features[0].id;map.setFeatureState({source:states,id:hoveredStateId},{hover:true});}});// 当鼠标离开state-fill图层时更新之前悬停要素的要素状态。map.on(mouseleave,state-fills,(){if(hoveredStateId){map.setFeatureState({source:states,id:hoveredStateId},{hover:false});}hoveredStateIdnull;});});/script/body/html 代码解析1. 初始化地图使用new maplibregl.Map()创建地图实例配置美国区域作为初始视图。2. 关键配置项map.addSource(): 添加GeoJSON数据源feature-state: 使用要素状态控制样式map.setFeatureState(): 设置要素状态hover状态: 通过feature-state实现悬停效果3. 核心机制使用要素状态feature-state实现悬停效果通过paint属性中的表达式根据状态设置透明度鼠标进入时设置hover:true透明度变为1鼠标离开时设置hover:false透明度变为0.5⚙️ 参数说明参数类型必填说明sourcestring是数据源IDidnumber/string是要素IDstateobject是要设置的键值对状态 效果说明运行代码后地图显示美国各州区域。鼠标悬停在某个州上时该州会高亮显示透明度从0.5变为1移开后恢复原状。通过这种方式可以清晰区分当前悬停的州。 常 见 问 题Q1: 悬停效果不生效A:检查以下几点确认数据源包含id字段要素需要唯一ID检查paint表达式中是否正确使用了feature-state确认hoveredStateId变量正确更新Q2: 为什么使用feature-state而不是直接修改样式A:feature-state是MapLibre优化的状态管理机制可以高效更新单个要素样式而不触发整个图层的重绘。Q3: 如何添加更丰富的悬停效果A:可以同时修改多个paint属性fill-color:[case,[boolean,[feature-state,hover],false],#ff0000,// 高亮色#627BC1// 默认色],fill-opacity:[case,[boolean,[feature-state,hover],false],1,0.5] 练习任务基础练习修改悬停时的颜色和高亮效果进阶挑战添加边框高亮效果拓展思考如何实现点击选中效果综合实践创建一个可交互的州信息展示系统 最佳实践状态追踪: 使用变量追踪当前悬停的要素ID性能优化: 使用feature-state避免频繁重绘清理状态: 鼠标离开时重置状态避免状态残留视觉效果: 透明度变化是最简单的悬停反馈组合效果: 结合颜色、边框、阴影等多重效果 延伸阅读Map API文档MapLibre GL JS 官方文档[下一课预告]将继续学习地图图层的基础知识本文是MapLibre GL JS实践课程系列的一部分欢迎关注收藏