以前幫朋友作了一個很常見的地圖區域拾取,而後突顯地圖上某個行政單位的功能。該功能主要是用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 = ''; } }
整體來講,很是簡單,謝謝閱讀。