news 2026/7/2 18:12:30

MapLibre GL JS第70课:创建悬停效果

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MapLibre GL JS第70课:创建悬停效果

📌 学习目标

  • 掌握创建悬停效果的实现方法
  • 理解相关API的使用
  • 能够独立完成类似功能开发

MapLibre GL JS 从入门到精通 - 130+实战案例

🎯 核心概念

创建悬停效果以突出显示要素。

💻 完 整 代 码

代码示例

constmap=newmaplibregl.Map({container:'map',style:'https://demotiles.maplibre.org/style.json',center:[-100.486052,37.830348],zoom:2});lethoveredStateId=null;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.length>0){if(hoveredStateId){map.setFeatureState({source:'states',id:hoveredStateId},{hover:false});}hoveredStateId=e.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});}hoveredStateId=null;});});

代码示例

<!DOCTYPEhtml><htmllang="en"><head><title>Create a hover effect</title><metaproperty="og:description"content="使用事件和要素状态创建每个要素的悬停效果。"/><metaproperty="og:created"content="2006-06-25"/><metacharset='utf-8'><metaname="viewport"content="width=device-width, initial-scale=1"><linkrel='stylesheet'href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css'/><scriptsrc='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script><style>body{margin:0;padding:0;}html, body, #map{height:100%;}</style></head><body><divid="map"></div><script>constmap=newmaplibregl.Map({container:'map',style:'https://demotiles.maplibre.org/style.json',center:[-100.486052,37.830348],zoom:2});lethoveredStateId=null;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.length>0){if(hoveredStateId){map.setFeatureState({source:'states',id:hoveredStateId},{hover:false});}hoveredStateId=e.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});}hoveredStateId=null;});});</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数据源ID
idnumber/string要素ID
stateobject要设置的键值对状态

🎨 效果说明

运行代码后,地图显示美国各州区域。鼠标悬停在某个州上时,该州会高亮显示(透明度从0.5变为1),移开后恢复原状。通过这种方式可以清晰区分当前悬停的州。

💡 常 见 问 题

Q1: 悬停效果不生效?
A:检查以下几点:

  1. 确认数据源包含id字段(要素需要唯一ID)
  2. 检查paint表达式中是否正确使用了feature-state
  3. 确认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]

📝 练习任务

  1. 基础练习:修改悬停时的颜色和高亮效果
  2. 进阶挑战:添加边框高亮效果
  3. 拓展思考:如何实现点击选中效果?
  4. 综合实践:创建一个可交互的州信息展示系统

🌟 最佳实践

  1. 状态追踪: 使用变量追踪当前悬停的要素ID
  2. 性能优化: 使用feature-state避免频繁重绘
  3. 清理状态: 鼠标离开时重置状态,避免状态残留
  4. 视觉效果: 透明度变化是最简单的悬停反馈
  5. 组合效果: 结合颜色、边框、阴影等多重效果

🔗 延伸阅读

  • Map API文档

  • MapLibre GL JS 官方文档

  • [下一课预告]:将继续学习地图图层的基础知识


本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 8:27:25

Java SpringBoot+Vue3+MyBatis 科研管理系统系统源码|前后端分离+MySQL数据库

博主介绍&#xff1a;&#x1f393; 东南大学计算机科学与技术专业在读研究生 | CSDN博客专家 | Java技术爱好者 在校期间积极参与实验室项目研发&#xff0c;现为CSDN特邀作者、掘金优质创作者。专注于Java开发、Spring Boot框架、前后端分离技术及常见毕设项目实现。 &#x…

作者头像 李华
网站建设 2026/7/1 4:35:35

【课程设计/毕业设计】基于 SpringBoot 的棋牌室日常营业监管系统的设计与实现 基于 SpringBoot 的休闲棋牌服务管理系统【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/1 4:30:07

AI Agent开发实战:从零构建具备工具调用与记忆能力的智能体

如果你最近在关注大模型和AI Agent&#xff0c;可能会发现一个现象&#xff1a;很多教程都在讲“Agent是什么”、“Agent框架有哪些”&#xff0c;但当你真正想动手开发一个能解决实际问题的Agent时&#xff0c;却感觉无从下手。要么是环境配置卡住&#xff0c;要么是代码跑不通…

作者头像 李华
网站建设 2026/7/1 4:28:43

Python爬虫经典案例012:爬虫日志与监控系统——构建健壮的爬虫运维体系

一、引言 在前面的文章中,我们学习了使用requests、BeautifulSoup、Selenium、Playwright、asyncio、Scrapy、代理IP、Cookie和验证码识别等工具来爬取网页。但是,当爬虫规模变大、运行时间变长时,我们需要一个完善的日志和监控系统来确保爬虫的稳定运行。 日志和监控系统…

作者头像 李华
网站建设 2026/7/1 4:28:42

5步掌握pk3DS:打造属于你的宝可梦3DS游戏随机化体验

5步掌握pk3DS&#xff1a;打造属于你的宝可梦3DS游戏随机化体验 【免费下载链接】pk3DS Pokmon (3DS) ROM Editor & Randomizer 项目地址: https://gitcode.com/gh_mirrors/pk/pk3DS 厌倦了千篇一律的宝可梦3DS游戏流程&#xff1f;想要为《宝可梦X/Y》、《太阳/月亮…

作者头像 李华