1. 程式人生 > >高德地圖和canvas畫圖結合應用的一些感想(一)

高德地圖和canvas畫圖結合應用的一些感想(一)

記錄 src function lose poi pan 高德 工程師 根據地

  之前朋友委托有個創業項目,想讓我幫忙,正好那段時間有點閑,半推半就中就答應下來了。

  入了團隊才發現,該項目前後端分離,後端工程師已就位主要實現接口,IOS端工程師也已就位,還差一個web前端工程師。背脊一涼,我之前雖然寫過一些js和css,雖有點功底但是離前端工程師還是有距離的啊。在和朋友說明情況後,朋友也是膽大,讓我試試,主要他實在找不到人了(也有可能目前前端工程師報價都太貴了,創業嘛,能節約就節約,能理解。。。),沒辦法,走一步算一步吧。

  其他管理頁面都還好,主要Dashboard需要在地圖上根據經緯度,半徑,角度等畫出噴灌機的實時位置和噴灌機灑水的扇形區域。

  由於之前沒有用過高德地圖,也沒畫過圖,剛拿到這個項目的時候,真的是一臉懵逼,沒辦法,只能埋頭研究高德地圖的api,發現裏面有畫圓、畫折線、多邊形等等一些api,很快,根據高德地圖提供的官方demo,很快寫了如下代碼:

技術分享
 1 //開始綁定
 2                 for (var m = 0; m < deviceList.length; m++) {
 3                     var device = deviceList[m];
 4                     var point = new AMap.LngLat(device.longitude, device.latitude);// 圓心位置;
 5 
 6                     var circle = new AMap.Circle({
 7                         center: point,//
圓心位置 8 radius: device.radius, //半徑 9 strokeColor: "white", //線顏色 10 strokeOpacity: 1, //線透明度 11 strokeWeight: 1, //線粗細度 12 fillColor: "#6e97ce", //填充顏色 13 fillOpacity: 0.9//
填充透明度 14 }); 15 16 17 circle.setMap(map); 18 19 var marker = new AMap.Marker({ 20 map: map, 21 position: [device.longitude, device.latitude], 22 }); 23 24 //註冊點擊事件 25 addClickHandler(circle, device); 26 27 }
View Code

  實現了如下的圖形。但是我發現畫折線和扇形,地圖上的api沒辦法很完美的實現,出來的扇形總是有點變形。跟我想要的效果還是有點距離的。

技術分享

  沒辦法,繼續啃高德的api...

  在圖層裏面看到了圖片圖層,貌似可以實現我的需求,但是我是純js啊,想要動態生成一個圖片再綁定到地圖,貌似有點太復雜了。。。也有可能我前端太菜了。

  好吧,放棄,繼續研究ing...

  發現自定義圖層裏面使用canvas做的(http://lbs.amap.com/api/javascript-api/example/layers/custom-layer),眼前一亮,那我可以用canvas畫好圖再貼到地圖上嘛,有點小激動。。。

  可轉念一想,canvas我沒有用過啊,沒辦法,繼續啃吧...

  找了好多學習資料,發現有個圖跟我有點像啊,就是大神們用canvas畫的時鐘,居然還能動,感覺被打開了一扇新大門。。。

  參考了一堆大神的代碼(本來想把鏈接一一都放出來的,但是都忘了收藏,導致現在都找不到鏈接了),在不斷的摸索中(短短幾個字,我可是啃了好幾個晚上),終於算把圖形畫出來了。。。

  不廢話,先上代碼:

技術分享
  1  <div>
  2         <canvas id="pie" width="300px" height="300px"></canvas>
  3     </div>
  4     <script>
  5         var dom = document.getElementById("pie");
  6         var ctx = dom.getContext("2d");
  7         var width = ctx.canvas.width;
  8         var height = ctx.canvas.height;
  9         var r = width / 2;
 10         var rem = width / 200;
 11 
 12 
 13         function drawBackground() {
 14             ctx.save();
 15             ctx.translate(r, r);//重新定義圓點到中心
 16             ctx.beginPath();
 17             ctx.lineWidth = rem;
 18             ctx.fillStyle = "#00AEE8";
 19             ctx.strokeStyle = "#fff";
 20             ctx.arc(0, 0, r, 0, Math.PI * 2, false);//圓點坐標,起始角0,結束角2π,順時針
 21             ctx.stroke();
 22             ctx.fill();
 23         }
 24 
 25         function drawsector(sDeg,eDeg) {
 26             //畫扇形
 27             ctx.beginPath();
 28             //定義起點
 29             ctx.moveTo(0, 0);
 30             ctx.fillStyle = "#0A73B1";
 31             //以起點為圓心,畫一個半徑為100的圓弧
 32             ctx.arc(0, 0, r, sDeg * Math.PI / 180, eDeg * Math.PI / 180);
 33             ctx.closePath();
 34             //ctx.stroke();
 35             ctx.fill();
 36 
 37         }
 38 
 39         function drawtext(PDeg) {
 40             //寫文字
 41             ctx.font = "18px Arial";
 42             ctx.textAlign = "center";
 43             ctx.textBaseline = "middle";
 44             ctx.strokeStyle = "black";
 45             ctx.fillStyle = "black";
 46             var rad = 90 * Math.PI / 180;//弧度
 47             var x = (r - 30 * rem) * Math.cos(rad);
 48             var y = (r - 30 * rem) * Math.sin(rad);
 49             ctx.rotate((PDeg-90) * Math.PI / 180);
 50             ctx.strokeText("<", x, y);
 51             ctx.fillText("<", x, y);
 52 
 53         }
 54 
 55         function drawStart(rDeg) {//起始位置
 56             ctx.save();
 57             ctx.beginPath();
 58             var rad = rDeg * Math.PI / 180;//弧度
 59             var x = (r) * Math.cos(rad);
 60             var y = (r) * Math.sin(rad);
 61 
 62             ctx.strokeStyle = "black";
 63             ctx.lineWidth = 2*rem;
 64             ctx.moveTo(0, 0);
 65             ctx.lineTo(x, y);
 66             ctx.lineCap = "round";
 67             ctx.stroke();
 68             ctx.restore();
 69         }
 70         function drawPosition(PDeg) {//實時位置
 71             ctx.save();
 72             ctx.beginPath();
 73             var rad = PDeg * Math.PI / 180 ;
 74             //ctx.rotate(rad);
 75             var x = (r) * Math.cos(rad);
 76             var y = (r) * Math.sin(rad);
 77 
 78             ctx.strokeStyle = "#fff";
 79 
 80             ctx.lineWidth = 3 * rem;
 81             ctx.moveTo(0, 0);
 82             ctx.lineTo(x, y);
 83             ctx.lineCap = "round";
 84             ctx.stroke();
 85 
 86             ctx.restore();
 87         }
 88 
 89         function drawPause() {//暫停
 90             ctx.save();
 91             ctx.beginPath();
 92             var rad = 120 * Math.PI / 180;
 93             //ctx.rotate(rad);
 94             var x = (r) * Math.cos(rad);
 95             var y = (r) * Math.sin(rad);
 96 
 97             ctx.strokeStyle = "#fff";
 98 
 99             ctx.lineWidth = 10 * rem;
100             ctx.moveTo(x+30, -y+80);
101             ctx.lineTo(x+30, y-80);
102             ctx.lineCap = "round";
103             ctx.stroke();
104 
105             ctx.restore();
106             
107             
108             ctx.save();
109             ctx.beginPath();
110             var rad = 60 * Math.PI / 180;
111            
112             var x2 = (r) * Math.cos(rad);
113             var y2 = (r) * Math.sin(rad);
114 
115             ctx.strokeStyle = "#fff";
116 
117             ctx.lineWidth = 10 * rem;
118             ctx.moveTo(x2-30, -y2+80);
119             ctx.lineTo(x2-30, y2-80);
120             ctx.lineCap = "round";
121             ctx.stroke();
122 
123             ctx.restore();
124         }
125         function draw() {
126             ctx.clearRect(0, 0, width, height);
127             drawBackground();//背景
128             drawsector(50, 180);
129             
130             //drawPause();
131             
132             drawStart(50);
133             drawPosition(100);
134             drawtext(110);
135             ctx.restore();
136         }
137        
138 
139         draw();
140     </script>
View Code

  圖形如下:

技術分享

  值得註意的是,這個圖裏面我覺得比較費事的是這個帶方向的黑色小箭頭,用到了rotate,經過反復測試,我發現從0-360度,他都會沿著圓心去旋轉,下圖黑色箭頭80°方向旋轉了,那其實這個位置和+90°後我要的放心是一致的(即紅色箭頭),抓住這個特性我即完成了箭頭沿著圓的方向旋轉這個問題。

技術分享

  整個圖完成後,我感覺幾何圖形又復習了一邊...果然學好數理化,走遍天下都不怕,哈哈。

  既然canvas圖已經基本完成,那怎麽集成到高德地圖上來,並根據地圖的等比縮放,就成了我下一個需要攻克的難題...

                  華麗的分割線

  好了,第一次寫博客,有點像流水賬,(-__-)b,只為了記錄我的一些想法和遇到的難點,希望以後對別人也能有所幫助。

  下一篇我會著重寫怎麽集成到高德地圖上,以及遇到的一些通點。

高德地圖和canvas畫圖結合應用的一些感想(一)