canvas標簽一直是html5的亮點,用它可以實現很多東西。我想用它來繪畫像迷宮那樣的地圖。借助到的工具有瓦片地圖編輯器tiled(點擊跳轉到下載鏈接)。
如圖:如果你想要畫像這樣的迷宮地圖,如果不用canvas,可以通過dom操作拼接一個一個div,以達成這個效果。那樣是不是很不合理?首先,頁面上會存在大量的div,並且通過dom操作生成很耗性能,如果地圖大了,會非常不流暢,非常卡。如果用canvas,性能就會大大提高。方法也很簡單,代碼量也非常少。
簡單介紹完了之后開始進入正題。上面提到的那個軟件裝了之后,打開它進行繪圖。說明一下:這只是一個繪圖軟件,繪圖完后會生成數據(保留為js格式或json格式),拿到里面的數據,再通過canvas進行繪畫。實踐操作一下。
①:打開后界面:
②:新建文件
每一塊寬高是40px,總寬高是480px*240px,可以自己設置
③:完了之后創建新圖塊。就是通過圖塊來畫圖。點擊瀏覽隨便拿一張圖片即可
④:然后隨便拎一塊右邊的圖塊就可以在左邊灰色區域畫圖了。我隨便畫了這樣的圖
⑤:保存js文件----文件另存為。這就是我得到的js文件。
(function(name,data){ if(typeof onTileMapLoaded === 'undefined') { if(typeof TileMaps === 'undefined') TileMaps = {}; TileMaps[name] = data; } else { onTileMapLoaded(name,data); }})("map1", { "height":6, "layers":[ { "data":[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,0, 1, 1, 1, 1, 1, 1, 0], "height":6, "name":"\u5757\u5c42 1", "opacity":1, "type":"tilelayer", "visible":true, "width":12, "x":0, "y":0 }], "nextobjectid":1, "orientation":"orthogonal", "properties": { }, "renderorder":"right-down", "tileheight":40, "tilesets":[ { "firstgid":1, "image":"..\/..\/..\/Public\/Pictures\/Sample Pictures\/Penguins.jpg", "imageheight":768, "imagewidth":1024, "margin":0, "name":"Penguins", "properties": { }, "spacing":0, "tilecount":475, "tileheight":40, "tilewidth":40 }], "tilewidth":40, "version":1, "width":12 });
對於以上代碼,其實只有紅色文字代碼對我們這個畫圖時有幫助的,data里面的數據,0表示沒有地圖塊,非0表示地圖塊。可以通過遍歷,將非0畫出來,獲取寬高只要是用來換行之類的。這就是瓦片地圖編輯器的作用。
下面就開始代碼了,代碼簡單易懂,就直接貼了:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas繪制地圖</title>
</head> <body> <canvas id="canvas1" width="480" height="240"></canvas> <!--注意canvas的大小,要聯系地圖大小設置--> <script>
//瓦片地圖編輯器獲取到的數據 var map={ "data":[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0], "height":6, "width":12 } var canvas = document.getElementById("canvas1"); var ctx = canvas.getContext("2d"); var W = 40; //每一塊地圖塊的寬 var H = 40; //每一塊地圖塊的高 var l = 0; var t = 0; for (var i=0; i<map.data.length; i++){ l = i%map.width*W; //繪畫每一塊地圖塊的X坐標 if (i%map.width==0&&i!=0){ //當達到一行是換行,注意第一行是0%0=0;所以應去除第一行換行的情況 t+=H; //繪畫地圖塊的Y坐標 } if (map.data[i]>0){ //當地圖塊的數據不為0時繪畫地圖塊 ctx.fillRect(l, t, W, H); } } </script> </body> </html>
效果如下:
跟上面的是一模一樣的,簡簡單單十幾行JS代碼就可以實現了,哪怕地圖再大,也只是data數據多而已,對性能要求並不高。
另外,如果想要實現將原圖片貼上去的話,也是很簡單的,只是涉及到位置的計算。
canvas可以切割圖片:ctx.drawImage(this, imgL, imgT, W, H, this.l, this.t, W, H);用這段代碼就可以了。
自己的一個練習。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <canvas id="canvas1" width="240" height="240"></canvas> </body> <script type="text/javascript"> var map = { "data":[0, 1, 0, 0, 0, 73, 0, 1, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 62, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "height":6, "width":6, "imgWidth":14 }; var canvas = document.getElementById("canvas1"); var ctx = canvas.getContext("2d"); var W = 40; var H = 40; var l = 0; var t = 0; for (var i=0; i<map.data.length; i++){ l = i%map.width*W; if (i%map.width==0&&i!=0){ t+=H; } if (map.data[i]>0){ var imgObj = new Image(); imgObj.src = "pic.jpg"; imgObj.index = i; imgObj.l = l; imgObj.t = t; imgObj.onload = function (){ var imgL = (map.data[this.index]-1)%map.imgWidth*W; var imgT = Math.floor(map.data[this.index]/map.imgWidth)*H; ctx.drawImage(this, imgL, imgT, W, H, this.l, this.t, W, H); } } } </script> </html>
效果:
思路就是這樣子,就不在=再多說了。原創不容易,如需轉載,請寫明出處吧,謝謝。