之前帮朋友做了一个很常见的地图区域拾取,然后突显地图上某个行政单位的功能。该功能主要是用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 = ''; }}
总体来说,非常简单,谢谢阅读。