具體步驟如下:
1. 首先做出繪圖區,作為坦克的戰場
<canvas id="floor" width="800px" height="500px"></canvas>
我們給一個黑色的背景色,並且讓它居中(如果對居中的各種奇淫技巧感興趣,歡迎訪問我的第一篇博客——“CSS垂直居中的11種實現方式”,點擊這里進行傳送
http://www.cnblogs.com/zhouhuan/p/vertical_center.html)。
#floor { background:#000; position: absolute; top: 50%; left:50%; transform:translate(-50%, -50%); }
結果如下:
這里要說明一下,對於canvas畫布,寫在樣式里的寬高和寫在屬性里的寬高是不等價的,寫在樣式里的寬高是實際顯示在頁面里的像素寬高,而寫在屬性里的寬高是context的環境寬高(有些小伙伴可能暫時對context還沒有概念,沒關系,這里如果不能理解可以暫時先這樣做,跟着筆者的思路走,待會講了context之后再回來自己試一下便會有所體會),這二者的默認值都是300px 150px,如果將樣式的寬高改為800px 500px,那么其實是相當於將context環境內的300px 150px畫在了現實中的800px 500px,會導致畫的東西變得模糊,並且可能出現變形,所以一般要保持樣式寬高與屬性寬高的一致,其實一般做的話設置個屬性寬高確定一下畫布的大小就可以了。
2. 接下來就要在畫布上繪制圖形了
canvas元素自身是沒有繪圖能力的,所有的繪制工作必須通過JavaScript來完成。
① 這里我們先給出一個畫直線的demo,然后做以解釋:
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.moveTo(50,50); cxt.lineTo(50,200); cxt.strokeStyle = '#fff'; cxt.stroke();
結果如下:

第一步,var myCanvas = document.getElementById('floor'); 這個大家應該都明白,拿到canvas元素,拿到canvas元素是因為第二步里需要使用到它。
第二步,var cxt = myCanvas.getContext('2d'); 這一步的作用是創建一個在繪圖區作圖的環境(我一般形象地理解為在當前畫布上創建一個畫筆),文檔里的定義是:getContext()方法返回一個用於在畫布上繪圖的環境。我們來看看文檔里進一步的解釋:該方法里的參數指定了想要在畫布上繪制的類型,當前唯一的合法值是 "2d",它指定了二維繪圖,並且導致這個方法返回一個環境對象,該對象導出一個二維繪圖 API,在未來,如果 <canvas> 標簽擴展到支持 3D 繪圖,getContext() 方法可能允許傳遞一個 "3d" 字符串參數。getContext()方法返回的是一個 CanvasRenderingContext2D 對象,使用它可以繪制圖形到 Canvas 元素中。
第三步,cxt.moveTo(50,50); 這一步就已經開始在畫直線了,moveTo()方法用於設置當前位置(50,50)並開始一條新的子路徑。
第四步,cxt.lineTo(50,200); 為當前的子路徑添加一條直線線段。這里的解釋可能有點繞,大家看單詞的字面意思可能會更清楚些:moveTo就是將子路徑的起點移到某個位置,lineTo就是子路徑要一直達到某個位置那當然就是終點咯。
第五步,cxt.strokeStyle = '#fff'; 設置畫筆的顏色為白色,這里沒有多余要解釋的地方。
第六步,cxt.stroke(); 按照前幾步的設置來繪制一條直線,這一步也比較好理解。
OK,那到這一步,我們的第一條直線便繪制成功了!撒花撒花!
② 接下來,我們再看一個畫三角形的例子,仍然是先給出代碼和結果,再來給大家解釋:
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.beginPath(); cxt.moveTo(50,50); cxt.lineTo(50,200); cxt.lineTo(200,200); cxt.closePath(); cxt.strokeStyle = '#fff'; cxt.stroke();
結果如下:

這里只有beginPath()和closePath()前面沒有用到過。
beginPath()方法:丟棄任何當前定義的路徑並且開始一條新的路徑;
closePath()方法:如果畫布的子路徑是打開的,那么closePath()方法通過添加一條線段連接當前點和子路徑起始點來關閉它,但如果子路徑已經閉合,該方法便不做任何事情。一旦子路徑閉合,就不能再為其添加更多的直線或曲線了。
上面的代碼也可以修改成這樣:
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.beginPath(); cxt.moveTo(50,50); cxt.lineTo(50,200); cxt.lineTo(200,200); cxt.closePath(); cxt.fillStyle = '#fff'; cxt.fill();
結果便是:

fillStyle屬性類似於前面用到過的strokeStyle,用來修改填充的顏色,這兩者的默認值都是黑色;
fill()方法用來填充當前路徑的內部,也非常好理解,因為fill就是填充的意思。
③ 第三個例子是畫矩形
這里當然也可以像我們之前畫三角形一樣,自己一步一步地設置路徑,設置好之后再畫或者進行填充,但這種方法比較麻煩,也容易出錯,不建議使用。CanvasRenderingContext2D對象有一個直接用來畫矩形的方法,fillRect()和strokeRect():
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.strokeStyle = "#fff"; cxt.strokeRect(20,20,50,100); cxt.fillStyle = "#fff"; cxt.fillRect(80,20,50,100);

這兩個方法都有四個參數(x, y, width, height),前兩個是矩形左上角點的坐標,后兩個是矩形的寬和高。
④ 畫圓
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.fillStyle = "orange"; //第一個半圓 cxt.beginPath(); cxt.arc(100,100,50,0,Math.PI,true); cxt.closePath(); cxt.fill(); //圓 cxt.beginPath(); cxt.arc(210,100,50,0,2*Math.PI,false); cxt.closePath(); cxt.fill(); //第二個半圓 cxt.strokeStyle = "red"; cxt.beginPath(); cxt.arc(320,100,50,0,Math.PI,false); cxt.closePath(); cxt.stroke();
結果如下:

arc()方法使用一個中心點和半徑,為當前子路徑添加一條弧,該方法傳六個參數(x, y, radius, startAngle, endAngle, counterclockwise),分別表示圓心的x坐標,圓心的y坐標,圓的半徑,開始的角度,結束的角度,順時針還是逆時針。其中,兩個角度采用弧度來衡量,最后一個參數true表示逆時針,false表示順時針。
這里給大家一個建議,在arc()方法之前加上beginPath(0開始路徑,方法之后加上closePath()結束路徑,否則可能會出現和其他圖形互相影響的情況。畫其它圖形的時候也是,要注意這一點,只有矩形不用。
關於角度的參數有幾點說明:默認X軸正半軸的角度為0,沿着逆時針方向角度增加。上面使用到的Math.PI表示的就是數學當中的π,Math對象是ECMAScript為保存數學公式和信息提供的一個對象,該對象還有其它很多屬性用起來也非常方便,比如Math.E表示自然對數的底數,也就是常量e的值。
⑤ 在畫布上寫字
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.fillStyle = "#F21C9D"; cxt.font = "50px simhei"; cxt.fillText("聖誕快樂!",30,100);
結果:

fillText()方法用來在畫布上寫字,第一個參數傳一個字符串,后兩個參數便是左上角點的坐標;
cxt.fillStyle用來給字體設置顏色;
cxt.font用來設置大小和字體,大小的值和字體的值之間用空格隔開,二者只寫一個時無效。
⑥ 畫圖片
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); var myImg = new Image(); myImg.src = "images/soldier.png"; myImg.onload = function(){ cxt.drawImage(myImg,60,20,680,454); };
結果如下:

畫圖片有幾個步驟:
var myImg = new Image(); 創建image對象;
myImg.src = "images/soldier.png"; 指定圖片的路徑;
myImg.onload = function(){
cxt.drawImage(myImg,60,20,680,454);
};
加載完圖片之后,使用drawImage()方法進行繪制,該方法傳四個參數(x, y, width, height),分別為圖片左上角的X坐標,Y坐標,圖片的寬,圖片的高,寬和高也可以不指定,不指定的話就會顯示為圖片的原始尺寸。
3. 掌握了這些方法之后,我們就可以輕而易舉地畫出一個簡單的坦克了,我們來以湖人隊的主色畫一個坦克:
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.fillStyle = "#542174"; cxt.fillRect(350,400,20,65); //坦克左邊的履帶 cxt.fillRect(420,400,20,65); //右邊的履帶 cxt.fillRect(373,410,44,50); //中間的主體 cxt.fillStyle = "#FCB827"; cxt.beginPath(); cxt.arc(395,435,16,0,2*Math.PI,false); //主體上的圓蓋 cxt.closePath(); cxt.fill(); cxt.strokeStyle = "#FCB827"; cxt.lineWidth = "8.0"; cxt.moveTo(395,435); //炮筒起點 cxt.lineTo(395,375); //炮筒終點 cxt.stroke(); //畫炮筒
結果如下:
lineWidth屬性用來設置畫筆畫出的線條寬度,默認值是1.0,設置的值必須大於0,較寬的線條在路徑上居中,每邊占線條寬度的一半。
這里說明一下為什么不畫一張坦克的圖片上去,而要這樣費盡周折結果還畫了一個巨丑的坦克,這是因為如果直接使用圖片的話會很耗CPU,性能不高,坦克跑起來的時候甚至可能會出現卡頓,但如果是自己畫的坦克就不會有這樣的問題。
(注:暫未考慮對低版本IE及其它非主流瀏覽器的兼容)
