侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130555 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

地图区域操作

2024-05-09 星期四 / 0 评论 / 0 点赞 / 6 阅读 / 3766 字

之前帮朋友做了一个很常见的地图区域拾取,然后突显地图上某个行政单位的功能。该功能主要是用canvas来实现,先看效果图: 上图是没有hover的效果图,hover某个区域后效果如下: 黄色区域突显

之前帮朋友做了一个很常见的地图区域拾取,然后突显地图上某个行政单位的功能。该功能主要是用canvas来实现,先看效果图:

上图是没有hover的效果图,hover某个区域后效果如下:

黄色区域突显出来,一旦我们拿到整个地图上的某个区域,就可以做 弹窗,详细信息显示 等功能了。

简要说一下,如果是通过svg来实现需要先把地图区域转换为具体的坐标(通过AI绘制,然后导出),然后生成一个又一个的polygon或者path即可。

言归正传,这里还是说说canvas实现的全过程

firstBlood,图片处理。

用canvas处理,自然会用到像素拾取,所以为了保证准确性每个子区域用不同的rgb值,这个值必须不一样。

secondBlood,dom结构。

<div class="map-wrap" id="map-wrap-id">   <!-- 用于绘制整个地图 -->   <canvas id="canvas" width="550" height="420"></canvas>   <!-- 遮罩div -->   <div class="shade-wrap"></div>   <!-- 用于绘制行政区域 -->   <canvas class="big-canvas" id="bigCanvas" width="750" height="520"></canvas></div>

map-wrap里面的3个子dom都是重叠排放。很显然,我们会将整个区域背景绘制在第一个canvas里面,考虑到放大效果,顶层的big-canvas会大一些。

thirdBlood, js代码

先说一个小坑,最开始我是把每个区域的rgb值单独取出来放到一个对象里面的,然后通过像素拾取后的rgb值进行取放。然后我就S B了,忽略了 web 安全色这一重要知识。在不同的显示器上显示出来的色彩是不一样的!所以我的思路是 当整个地图渲染完毕后,根据事先配置好的坐标点对每个区域进行采样,然后以采样后的颜色值作为标准来判断 用户当前的鼠标操作。

和谐代码如下:

var curMapInfo;//底层区域canvas mousemove处理.canvas.onmousemove = function(event){	var event = event || window.event,		x = event.clientX, y = event.clientY, curInfo;		var pixel = ctx.getImageData(x - box.left, y - box.top, 1, 1).data;	//透明度为0表示没有颜色,跳过	if(0 == pixel[3]) return;          //将rgb值转换为key 	curInfo = tempMapInfo[pixel.slice(0, 3).join('')];        //地图边缘,重复判定	if(!curInfo || curInfo == curMapInfo) return;		curMapInfo = curInfo;		var img = document.createElement('img');	img.src = curInfo.url;        //一定是在load里面执行。	img.onload = function(){        		bigCtx.clearRect(0, 0, 750, 520);                //将鼠标hover的区域小地图绘制在顶层的canvas里面。		bigCtx.drawImage(img, 0, 0, curInfo.width, curInfo.height, curInfo.x, curInfo.y, curInfo.width, curInfo.height);		setTimeout(function(){			mapWrap.className = 'map-wrap show-big';		}, 300)	}}

同样的,顶层canvas也做像素拾取判定,没有像素的时候就隐藏掉

bigCanvas.onmousemove = function(event){	var event = event || window.event,		x = event.clientX, y = event.clientY;		var pixel = bigCtx.getImageData(x - bigBox.left, y - bigBox.top, 1, 1).data;		if(0 == pixel[3]) {		mapWrap.className = 'map-wrap';		curMapInfo = '';	}}

总体来说,非常简单,谢谢阅读。

广告 广告

评论区