地图区域操做

以前帮朋友作了一个很常见的地图区域拾取,而后突显地图上某个行政单位的功能。该功能主要是用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 = '';
	}
}

整体来讲,很是简单,谢谢阅读。

相关文章
相关标签/搜索