canvas元素是HTML5中新新增的一個元素,該元素是HTML5中的一個亮點。Canvas元素就像一塊畫布,通過該元素自帶的API結合JavaScript程式碼可以繪製各種圖形和影象以及動畫效果。
1.1 瀏覽器不相容問題
- ie9以上才支援canvas, 其他chrome、firefox、蘋果瀏覽器等都支援
- 只要瀏覽器相容canvas,那麼就會支援絕大部分api(個別最新api除外)
- 移動端的相容情況非常理想,基本上隨便使用
- 2d的支援的都非常好,3d(webgl)ie11才支援,其他都支援
- 如果瀏覽器不相容,最好進行友好提示,提示內容只有在瀏覽器不支援時才顯示。
//例如: <canvas id="cavsElem"> 你的瀏覽器不支援canvas,請升級瀏覽器 </canvas>
瀏覽器不相容,也可以使用flash等手段進行優雅降級
1.2 建立畫布
在頁面中建立canvas元素與建立其他元素一樣,只需要新增一個<canvas>標記即可。該元素預設的寬高為300*15,可以通過元素的width屬性和height屬性改變預設的寬高。
注意:
- 不能使用CSS樣式控制canvas元素的寬高,否則會導致繪製的圖形拉伸。
- 重新設定canvas標籤的寬高屬性會導致畫布擦除所有的內容。
- 可以給canvas畫布設定背景色
1.3 canvas座標系
在開始繪製任何影象之前,我們先講一下canvas的座標系。canvas座標系是以左上角0,0處為座標原點,水平方向為x軸,向右為正;垂直方向為y軸,向下為正。如下圖所示:
1.4 繪製線徑
- 獲取上下文物件(CanvasRenderingContext2D)
首先,獲取canvas元素,然後呼叫元素的getContext(“2d”)方法,該方法返回一個CanvasRenderingContext2D物件,使用該物件就可以在畫布上繪圖了。
var mcanvas = document.getElementById("mcanvas");
var mcontext = mcanvas.getContext("2d");
2.設定繪製起點(moveTo)
//語法:
ctx.moveTo(x, y);
* 解釋:設定上下文繪製路徑的起點。相當於移動畫筆到某個位置。
* 引數:x,y 都是相對於 canvas座標系的原點(左上角)。
* 注意: 繪製線段前必須先設定起點,不然繪製無效。如果不進行設定,就會使用lineTo的座標當作moveTo
3.繪製直線(lineTo)
//語法:
ctx.lineTo(x, y);
* 解釋:從上一步設定的繪製起點繪製一條直線到(x, y)點。
* 引數:x,y 目標點座標。
4.路徑的開始和閉合
//開始路徑:
ctx.beginPath();
//閉合路徑:
ctx.closePath();
* 解釋:如果繪製路徑比較複雜,必須使用路徑開始和結束。閉合路徑會自動把最後的線頭和開始的線頭連在一起。
* beginPath: 核心的作用是將不同繪製的形狀進行隔離,每次執行此方法,表示重新繪製一個路徑,跟之前的繪製的墨跡可以進行分開樣式設定和管理。
5.繪製圖形(stroke)
//語法:
ctx.stroke();
* 解釋:根據路徑繪製線。路徑只是草稿,真正繪製線必須執行stroke
在繪製之前,還可以對畫筆的顏色和粗細進行設定進行設定,方法如下:
//語法:
ctx.strokeStyle = “#ff0000”;
ctx.lineWidth = 4; //值為不帶單位的數字,並且大於0
6.填充圖形(fill)
//語法:
ctx.fill();
* 解釋:對已經畫好的圖形進行填充顏色。
在填充之前,同樣可以對所填充的顏色進行設定,方法如下:
//語法:
ctx.fileStyle = “#0000ff”;
7.canvas繪製的基本步驟:
第一步:獲得上下文 =>canvasElem.getContext('2d');
第二步:開始路徑規劃 =>ctx.beginPath()
第三步:移動起始點 =>ctx.moveTo(x, y)
第四步:繪製線(線條、矩形、圓形、圖片...) =>ctx.lineTo(x, y)
第五步:閉合路徑 =>ctx.closePath();
第六步:繪製描邊 =>ctx.stroke();
案例:通過上面所學的方法繪製一個三角形。
<canvas id="mcanvas">你的瀏覽器不支援canvas,請升級瀏覽器</canvas> <script> var mcanvas = document.getElementById("mcanvas"); //獲得畫布 var mcontext = mcanvas.getContext("2d"); //獲得上下文 mcanvas.width = 900; //重新設定標籤的屬性寬高 mcanvas.height = 600; //千萬不要用 canvas.style.height mcanvas.style.border = "1px solid #000"; //設定canvas的邊 //繪製三角形 mcontext.beginPath(); //開始路徑 mcontext.moveTo(100,100); //三角形,左頂點 mcontext.lineTo(300, 100); //右頂點 mcontext.lineTo(300, 300); //底部的點 mcontext.closePath(); //結束路徑 mcontext.stroke(); //描邊路徑 </script>
案例:理解canvas基於狀態的繪圖
<canvas id="mcanvas">你的瀏覽器不支援canvas,請升級瀏覽器</canvas> <script> var mcanvas = document.getElementById("mcanvas"); //獲得畫布 var mcontext = mcanvas.getContext("2d"); //獲得上下文
mcanvas.width = 900; //重新設定標籤的屬性寬高
mcanvas.height = 600; //千萬不要用 canvas.style.height
mcanvas.style.border = "1px solid #000"; //設定canvas的邊
mcontext.strokeStyle = "#ff0000"; //設定畫筆的顏色
mcontext.lineWidth = 2; //設定畫筆的粗細
mcontext.fillStyle = "#00ff00"; //設定填充圖形的顏色
//繪製三角形
mcontext.beginPath(); //開始路徑
mcontext.moveTo(100,100); //三角形,左頂點
mcontext.lineTo(300, 100); //右頂點
mcontext.lineTo(300, 300); //底部的點
mcontext.closePath(); //結束路徑
mcontext.stroke(); //描邊路徑
//mcontext.fill(); //填充圖形
//繪製矩形
mcontext.beginPath(); //開啟了一個新狀態(新線徑),
//新狀態可以繼承之前狀態的樣式,
//但是當前狀態設定的所有樣式只能用於當前狀態。
//mcontext.strokeStyle = "#00ff00";//為當前狀態設定的樣式
mcontext.moveTo(500,100); //起始點
mcontext.lineTo(800,100); //上邊
mcontext.lineTo(800,300); //右邊
mcontext.lineTo(500,300); //下邊
mcontext.closePath();
mcontext.stroke();
1.5 繪製矩形
- 快速建立矩形rect()方法
語法:ctx.rect(x, y, width, height);
* 解釋:x, y是矩形左上角座標, width和height都是以畫素計
* rect方法只是規劃了矩形的路徑,並沒有填充和描邊。
2.建立描邊矩形
語法:ctx.strokeRect(x, y, width, height);
引數跟rect(x, y, width, height)相同,注意此方法繪製完路徑後立即進行stroke繪製。
3.建立填充矩形
語法:ctx.fillRect(x, y, width, height);
引數跟rect(x, y, width, height)相同, 此方法執行完成後,立即對當前矩形進行fill填充。
4.清除矩形(clearReact)
語法:ctx.clearRect(x, y, width, hegiht);
* 解釋:清除某個矩形內的繪製的內容,相當於橡皮擦。
<canvas id="mcanvas">你的瀏覽器不支援canvas,請升級瀏覽器</canvas> <script> var mcanvas = document.getElementById("mcanvas"); //獲得畫布 var mcontext = mcanvas.getContext("2d"); //獲得上下文 mcanvas.width = 900; //重新設定標籤的屬性寬高 mcanvas.height = 600; //千萬不要用 canvas.style.height //rect方法只是規劃了矩形的路徑,並沒有填充和描邊,需要單獨描邊或填充。 mcontext.rect(20,20,300,200); mcontext.stroke(); //快速建立一個描邊的矩形 mcontext.strokeRect(400,20,300,200); //快速建立一個填充的矩形 mcontext.fillRect(20,300,300,200); //在畫布上建立一個矩形區域,該矩形區域中的圖形都會被清除 mcontext.clearRect(120,350,100,100); </script>
1.6 繪製圓形
arc() 方法用於建立弧線(用於建立圓或部分圓)。
語法:ctx.arc(x, y, r, startAngle, endAngle, counterclockwise);
解釋:
x,y:圓心座標。
r:半徑大小。
sAngle:繪製開始的角度。 圓心到最右邊點是0度,順時針方向弧度增大。
eAngel:結束的角度,注意是弧度。
counterclockwise:是否是逆時針,預設是false。true是逆時針,false:順時針
注意:弧度和角度的轉換公式: rad = deg*Math.PI/180;
繪製圓形和餅圖
<canvas id="mcanvas">你的瀏覽器不支援canvas,請升級瀏覽器</canvas> <script> var mcanvas = document.getElementById("mcanvas"); //獲得畫布 var mcontext = mcanvas.getContext("2d"); //獲得上下文 mcanvas.width = 900; mcanvas.height = 600; //繪製圓形 mcontext.beginPath(); mcontext.arc(200,200,100,0,360*Math.PI/180); mcontext.closePath(); mcontext.stroke(); // 通過資料進行繪製餅圖 var data = [{ "value": .2, "color": "red", "title": "應屆生" },{ "value": .3, "color": "blue", "title": "社會招生" },{ "value": .4, "color": "green", "title": "老學員推薦" },{ "value": .1, "color": "#ccc", "title": "公開課" }]; var tempAngle = -90; var x0 = 600, y0 = 300; var raduis = 200; for(var i = 0; i < data.length; i++) { mcontext.beginPath(); mcontext.moveTo(x0, y0); var angle = data[i].value * 360; var startAngle = tempAngle*Math.PI/180; var endAngle = (tempAngle+angle)*Math.PI/180; mcontext.fillStyle = data[i].color; mcontext.arc(x0, y0, raduis, startAngle, endAngle); mcontext.closePath(); mcontext.fill(); tempAngle += angle; } </script>
三角函式的補充:
Math.sin(弧度); //夾角對面的邊 和 斜邊的比值
Math.cos(弧度); //夾角側邊與斜邊的比值
圓形上面的點的座標的計算公式
x =x0 + Math.cos(rad) * R;//x0和y0是圓心點座標
y =y0 + Math.sin(rad) * R;//注意都是弧度
1.7 繪製文字
canvas 提供了兩種方法來渲染文字:
fillText(text, x, y [, maxWidth])
在指定的(x,y)位置填充指定的文字,繪製的最大寬度是可選的.
strokeText(text, x, y [, maxWidth])
在指定的(x,y)位置繪製文字邊框,繪製的最大寬度是可選的.
示例1
文字用當前的填充方式被填充:
var ctx = document.getElementById('canvas').getContext('2d');
ctx.font = "48px serif";
ctx.fillText("Hello world", 10, 50);
示例2
文字用當前的邊框樣式被繪製:
var ctx = document.getElementById('canvas').getContext('2d');
ctx.font = "48px serif";
ctx.strokeText("Hello world", 10, 50);
文字樣式
font = value: 當前我們用來繪製文字的樣式. 這個字串使用和 CSS font 屬性相同的語法. 預設的字型是 10px sans-serif。
textAlign = value: 文字對齊選項. 可選的值包括:start, end, left, right or center. 預設值是 start。
textBaseline = value: 基線對齊選項. 可選的值包括:top, hanging, middle, alphabetic, ideographic, bottom。預設值是 alphabetic。
程式碼示例:
<canvas id="mcanvas">你的瀏覽器不支援canvas,請升級瀏覽器</canvas> <script> var mcanvas = document.getElementById("mcanvas"); //獲得畫布 var mcontext = mcanvas.getContext("2d"); //獲得上下文 mcanvas.width = 900; mcanvas.height = 600; mcontext.fillStyle = "#0000ff"; mcontext.font = "italic 30px 微軟雅黑"; mcontext.textAlign = "start"; mcontext.textBaseline = "top"; mcontext.fillText("你好", 200, 0, 100); mcontext.font = "italic 30px 微軟雅黑"; mcontext.textAlign = "left"; mcontext.textBaseline = "top"; mcontext.fillText("你好", 200, 50, 100); mcontext.font = "bold 30px 黑體"; mcontext.textAlign = "center"; mcontext.textBaseline = "top"; mcontext.strokeText("你好", 200, 100, 100); mcontext.font = "bold 30px 黑體"; mcontext.textAlign = "right"; mcontext.textBaseline = "top"; mcontext.strokeText("你好", 200, 150, 100); mcontext.font = "bold 30px 黑體"; mcontext.textAlign = "end"; mcontext.textBaseline = "top"; mcontext.strokeText("你好", 200, 200, 100); </script>
1.8繪製影象
1.基本繪製圖片的方式
context.drawImage(img,x,y);
引數說明: x,y 繪製圖片左上角的座標, img是繪製圖片的dom物件。
2.在畫布上繪製影象,並規定影象的寬度和高度
context.drawImage(img,x,y,width,height);
引數說明:width 繪製圖片的寬度, height:繪製圖片的高度
如果指定寬高,最好成比例,不然圖片會被拉伸
設定高 = 原高度 * 設定寬/ 原寬度;
3.圖片裁剪,並在畫布上定位被裁剪的部分
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
引數說明:
sx,sy 裁剪的左上角座標,
swidth:裁剪圖片的高度。 sheight:裁剪的高度
其他同上
4.用javascript建立img物件
上面提供的3個方法,都需要一個Image物件作為引數,下面介紹了幾種建立Image物件的方式。需要注意的是,為Image的src屬性賦值後,Image物件會去裝載指定圖片,但這種裝載是非同步的,如果圖片太大或則圖片來自網路,且網路傳輸速度慢,Image物件裝載圖片就會需要:一定的時間開銷。為了保證圖片裝載完成後才去繪製圖片,可以監聽Image物件的onload回撥事件,然後在事件處理函式中繪製圖片,如下所示:
第一種方式:
var img = document.getElementById("imgId");
img.onload = function(){ //圖片載入完成後,執行此方法
mcontext.drawImage(img, 10, 10);
}
第二種方式:
var img = document.createElement("img");
img.src = "img/a.jpg";
img.alt = "誰笑誰是小狗";
img.onload = function(){ //圖片載入完成後,執行此方法
mcontext.drawImage(img, 10, 10);
}
第三種方式:
var img = new Image();//這個就是 img標籤的dom物件
img.src = "imgs/arc.gif";
img.alt = "誰笑誰是小狗";
img.onload = function() { //圖片載入完成後,執行此方法
}