最轻量静态热区用+(IE9+兼容),但仅适固定图与静态坐标;动态需求须用Leaflet/高德/百度等地图库或Canvas自绘。

不依赖地图 SDK 就能做静态热区,用 <map></map> + <area shape="poly"> 最轻量、兼容性最好(IE9+),但只适合固定图片 + 静态坐标;真要拖拽画、实时判断点是否在内、缩放适配,必须上地图库(Leaflet / 高德 / 百度等)。
用 <map></map> 和 <area> 做静态多边形热区
这是最原始也最稳的方案:一张 PNG/JPG 图片,配上几个 coords 坐标,就能让不规则区域可点击。关键不是“怎么写标签”,而是坐标准不准、怎么取、怎么验。
-
coords必须是偶数个整数,按顺时针或逆时针顺序列出所有顶点x,y,首尾**不必重合**(浏览器会自动闭合,强行重复反而可能出错) - 坐标原点是图片左上角(0,0),单位是像素 —— 所以图片尺寸变了、缩放了,
coords就全废,不能响应式 - 用 PS 或在线工具(如 Image Map Generator)点选顶点导出坐标,别手算;UI 给的标注图务必确认是“按原始尺寸截图”
- 每个
<area>只能绑定一个href或用 JS 监听click,想做 hover 效果得靠 CSS +title或额外加一层透明 canvas 覆盖
Leaflet 动态绘制多边形(无地图 SDK 也能跑)
Leaflet 不强制联网加载底图,纯前端即可完成坐标录入、拖拽编辑、点面判断。适合内部系统、离线场景或仅需几何逻辑的业务。
- 初始化时传空
center和极小zoom,或用L.map(...).setView(...)后立刻map.removeLayer(map._layers[...])清掉瓦片层,只留矢量层 - 用
L.polygon([[lat1,lng1], [lat2,lng2], ...])创建,.addTo(map)即显;启用编辑:polygon.editing.enable() - 获取顶点:
polygon.getLatLngs()返回L.LatLng[],转数组用.map(ll => [ll.lat, ll.lng]) - 判断点是否在内:
L.Polygon.prototype.contains不暴露,得自己调leaflet-pip插件,或用更轻的point-in-polygon库(传 [[x,y],...] 和 [x,y] 即可)
高德/百度/腾讯地图 API 的坑点直说
这些 SDK 看似封装好,但实际集成时卡住的往往不是“怎么画”,而是权限、坐标系、生命周期和事件时机。
立即学习“前端免费学习笔记(深入)”;
- 高德
AMap.Driving或DrawingManager默认用 GCJ-02 坐标,若你后端存的是 WGS84(GPS 原始坐标),直接画出来会偏移几百米 —— 必须用AMap.convertFrom(..., 'gps')转 - 百度地图的
DrawingManager在overlaycomplete回调里拿e.overlay.getPath(),返回的是BMap.Point[],要转成数组得.map(p => [p.lat, p.lng]),注意顺序是lat,lng(反直觉) - 腾讯地图
qq.maps.Polygon的path参数接受qq.maps.LatLng[],但qq.maps.LatLng构造函数是new qq.maps.LatLng(lat, lng),参数顺序又是lat,lng—— 和 Leaflet 的[lat,lng]一致,但和 GeoJSON 的[lng,lat]相反 - 所有地图库在
map.on('load', ...)之前绑定绘制工具,大概率失效;高德必须等map.getZoom() > 0才能添加图层
Canvas 手动画多边形(完全自控,但无地理语义)
如果只是 UI 上示意“一块区域”,不需要经纬度、不对接 GIS 数据,<canvas></canvas> 是最自由的选择:坐标任意定、样式随心改、性能扛得住上千个区域。
- 用
ctx.beginPath()→ctx.moveTo(x,y)→ 多个ctx.lineTo(x,y)→ctx.closePath()→ctx.fill() - 监听
canvas的mousemove+isPointInPath()实现 hover 高亮,但注意:该方法只对**当前路径**有效,每次绘制新图形前要ctx.beginPath(),否则所有区域混在一起判断 - 保存坐标用数组推入
{x, y}对象,后续要做缩放适配,就得把所有x,y乘上缩放比;想支持拖拽,就得自己实现 hit-test 和 translate 逻辑 - 没有内置的“点是否在多边形内”API,得引入
robust-point-in-polygon或手写射线法 —— 别信网上抄来的简版,边界点、共线、凹多边形容易判错
真正麻烦的从来不是“怎么画出来”,而是坐标系对齐、缩放同步、事件穿透、无障碍支持(比如 screen reader 怎么读多边形区域)、以及——当 UI 突然说“这个热区要跟着地图一起旋转”时,你才发现 <map></map> 根本不支持 transform。



















