以前帮朋友作了一个很常见的地图区域拾取,而后突显地图上某个行政单位的功能。该功能主要是用canvas来实现,先看效果图:javascript
上图是没有hover的效果图,hover某个区域后效果以下:html
黄色区域突显出来,一旦咱们拿到整个地图上的某个区域,就能够作 弹窗,详细信息显示 等功能了。java
简要说一下,若是是经过svg来实现须要先把地图区域转换为具体的坐标(经过AI绘制,而后导出),而后生成一个又一个的polygon或者path便可。web
言归正传,这里仍是说说canvas实现的全过程canvas
firstBlood,图片处理。安全
用canvas处理,天然会用到像素拾取,因此为了保证准确性每一个子区域用不一样的rgb值,这个值必须不同。dom
secondBlood,dom结构。svg
<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会大一些。url
thirdBlood, js代码code
先说一个小坑,最开始我是把每一个区域的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 = ''; } }
整体来讲,很是简单,谢谢阅读。