Canvas是HTML5標準中推出的一個很是受歡迎的功能元素,這個元素負責在頁面中設定一個區域,而後就能夠JS動態地在這個區域中繪製圖形了。而且它仍是跨平臺動畫和遊戲的標準方案。javascript
要使用canvas元素必須先設置其width和height屬性,指定繪圖區域的大小。html
若是瀏覽器不支持該功能,那麼將會顯示你在canvas標籤中鍵入的文本內容。前端
<!-- 寬度爲400,高度爲400的canvas -->
<canvas id="myCvs" width="400" height="400"> Your browser does not support canvas. </canvas>
複製代碼
在使用canvas元素以前,必須保證要有一個2d的繪圖環境。java
if(myCvs.getContext) {
var context = myCvs.getContext('2d');
}else {
console.log('Your browser does not support canvas.');
}
複製代碼
使用2d繪圖環境提供的方法,能夠繪製簡單的2d圖形,好比矩形、弧線和路徑。git
它的座標原點(0, 0)在canvas元素的左上角。 github
在學習2d繪圖方法以前,咱們試着看一下canvas的一個簡單例子:畫一個綠色矩形。canvas
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Canvas</title>
<style>
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<!-- 寬度爲400,高度爲400的canvas -->
<canvas id="myCvs" width="400" height="400">
Your browser does not support canvas.
</canvas>
<script>
var myCvs = document.getElementById('myCvs');
// 檢測是否支持2d上下文
if(myCvs.getContext) {
var context = myCvs.getContext('2d');
}else {
console.log('Your browser does not support canvas.');
}
function load() {
context.fillStyle = '#0f0'; // 填充顏色爲綠色
context.fillRect(50,25,300,150); // 填充矩形 (起點x座標, 起點y座標, 寬度, 高度)
}
window.onload = function() {
load();
}
</script>
</body>
</html>
複製代碼
canvas在2d上下文環境中提供了一些可供畫圖的屬性和方法,接下來具體看一下。數組
描邊,就是隻在圖形的邊緣畫線;瀏覽器
填充,就是用指定的樣式(顏色、漸變或圖像)填充圖像。ide
var myCvs = document.getElementById('myCvs');
if(myCvs.getContext) {
var context = myCvs.getContext('2d');
context.strokeStyle = 'red'; // 描邊
context.fillStyle = 'green'; // 填充
}
複製代碼
矩形是惟一一種能夠直接在2d上下文中繪製的形狀。
與矩形有關的方法包括fillRect()、strokeRect()和clearRect()。
它們接收4個參數:矩形的x座標,矩形的y座標,矩形寬度和矩形高度。單位都是像素。
// 繪製紅色矩形
context.fillStyle = 'red'; // 指定填充顏色爲紅色
context.fillRect(10,10,50,50); // 指定填充矩形的4個參數
複製代碼
// 繪製綠色描邊矩形
context.strokeStyle = 'green'; // 指定描邊顏色
context.strokeRect(70,10,50,50); // 指定描邊矩形的4個參數
複製代碼
// 清除畫布矩形區域
context.clearRect(0,0,400,400);
複製代碼
經過路徑能夠創造出複雜的形狀和線條。
在繪製路徑以前,必須調用beginPath()方法,表示要開始繪製新的路徑了。
在建立了新的路徑以後,若是想要繪製一條鏈接到路徑起點的線條,那麼就調用closePath()方法;
若是路徑已經完成,想要填充它那麼就調用fill()方法,想要描邊就調用stroke()方法。
// 畫線組成矩形
context.beginPath(); // 指定新路徑
context.moveTo(10,70); // 畫筆移動至(10,70)
context.lineTo(10,120); // 第一點座標
context.lineTo(60,120); // 第二點座標
context.lineTo(60,70); // 第三點座標
context.closePath(); // 閉合路徑
context.strokeStyle = 'blue'; // 指定描邊顏色
context.stroke(); // 描邊
複製代碼
// 畫圓弧
context.beginPath();
context.arc(95,95,25,0,2*Math.PI,true); // 圓心(95,95) 起始角度0弧度 結束角度2PI弧度 逆時針方向計算
context.closePath();
context.stroke();
複製代碼
// 三角形
context.beginPath();
context.moveTo(150, 70); // 第一點座標
context.lineTo(125, 120); // 第二點座標
context.lineTo(175, 120); // 第三點座標
context.closePath();
context.fillStyle = 'yellow' // 指定填充顏色
context.fill(); // 填充
複製代碼
// 二次貝塞爾曲線(1個控制點)
context.beginPath();
context.moveTo(10, 155); // 畫筆移動到(10,155)
context.quadraticCurveTo(60, 200, 300, 155); // 控制點座標(60,200) 結束點座標(300,155)
context.stroke();
// 三次貝塞爾曲線(2個控制點)
context.beginPath();
context.moveTo(10, 355); // 畫筆移動到(10,355)
context.bezierCurveTo(90, 200, 150, 300, 350, 350); // 控制點座標(90,200)和(150,300) 結束點座標(350,350)
context.strokeStyle = 'green';
context.stroke();
複製代碼
案例結果如圖所示:
在Canvas的2d上下文中還支持各類基本的繪製變換。
這裏介紹平移、旋轉、縮放三種變換在Canvas中的實現。
在瞭解各類變換以前,咱們先想一個這樣的問題:在用canvas畫圖時,若是咱們頻繁使用幾個默認值的設定,是否能夠重置爲默認值而沒必要重複定義呢?
這時就要用到2d上下文提供的保存和恢復的方法了,即save()和restore()方法,它們是以堆棧**(先進後出)的形式保存繪圖上下文的設置和變換**。
這裏看個例子,依次保存而後依次恢復讀取設置的顏色。
var myCvs = document.getElementById('myCvs');
var ctx = myCvs.getContext('2d');
ctx.strokeStyle = '#f00';
ctx.save(); // 保存指定顏色-紅色
ctx.strokeStyle = '#0f0';
ctx.save(); // 保存指定顏色-綠色
ctx.strokeStyle = '#00f';
ctx.save(); // 保存指定顏色-藍色
ctx.restore(); // 恢復指定顏色-藍色
ctx.strokeRect(10, 10, 50, 50);
ctx.restore(); // 恢復指定顏色-綠色
ctx.strokeRect(70, 10, 50, 50);
ctx.restore(); // 恢復指定顏色-紅色
ctx.strokeRect(130, 10, 50, 50);
複製代碼
translate(x, y):將座標原點移動到(x, y)。
這裏用translate()方法配合保存和恢復方法實現顏色漸變。
// 顏色漸變正方形
ctx.translate(10, 80);
for(var i = 1; i < 9; i++) {
ctx.save(); // 保存上一步(平移原點)的操做
ctx.translate(30*i, 0); // 將原點沿着x方向平移30*i的距離 到達新的座標原點(30*i, 0)
ctx.fillStyle = "rgb(" + (30*i) + "," + (255-30*i) + ",255)"; // 指定顏色
ctx.fillRect(0,0,30,30); // 在(30*i, 0)處按照指定顏色填充矩形
ctx.restore(); // 讀取上一次保存的操做 從新回到(10, 80)
}
複製代碼
rotate(angle):圍繞原點旋轉圖像的angle弧度。
這裏利用rotate()方法配合保存和恢復方法實現形狀的變換。
// 旋轉正方形
ctx.translate(180, 140); // 將原點平移到(180,140)
for(var i = 1; i < 9; i++) {
ctx.save(); // 保存上一步(平移原點)的操做
ctx.rotate(Math.PI * (1/2 + i/4)); // 每次循環將圖形繞着原點旋轉PI/4弧度 總共旋轉8次
ctx.translate(0, -50); // 旋轉完成後,將原點移動到(0, -50)
ctx.fillStyle = "rgb(" + (30 * i) + "," + (255 - 30*i) + ",255)"; // 指定顏色
ctx.fillRect(-30, -30, 30, 30); // 在(0, -50)處按照指定顏色填充矩形
ctx.restore(); // 讀取上一次保存的操做 從新回到(180, 140)
}
複製代碼
scale(scaleX, scaleY):縮放圖像,在x方向乘以scaleX,在y方向乘以scaleY。默認值爲1。
這裏綜合上述幾個方法,繪製一幅海螺圖形。
// 海螺圖形
ctx.translate(200, 80);
for(var i = 1; i < 80; i++) {
ctx.translate(30, 30);
ctx.scale(0.95, 0.95); // 設置縮放比例
ctx.rotate(Math.PI/12);
ctx.beginPath();
ctx.fillStyle = '#f00';
ctx.globalAlpha = '0.3'; // 設置圖形透明度
ctx.arc(0,0,50,0,Math.PI*2,true);
ctx.fill();
}
複製代碼
文本和圖形是如影隨形的,2d繪圖上下文提供了繪製圖像和文本的方法。
這裏介紹一下繪製圖像的基本操做。
2d繪圖上下文內置了對圖像的支持,提供了drawImage()方法,它有三種不一樣的參數組合。
接下來,依次看看不一樣的參數組合。
最簡單的參數組合是:傳入一個HTML圖像元素,以及繪製該圖像的起點的x和y座標。
let myCvs = document.getElementById('myCvs');
let context = myCvs.getContext('2d');
let img = new Image();
img.src = './img/canvas.png'; // 我愛前端的一張圖片
img.onload = () => {
context.drawImage(img, 50, 50); // 1. 正常繪製
}
複製代碼
除了上面傳的參數(要繪製的圖像、源圖像x座標、源圖像y座標),還能夠再傳兩個參數,分別表示目標寬度和目標高度。
這裏繪製的圖像大小爲100x100像素。
context.drawImage(img, 50, 50, 100, 100); // 2. 目標寬高均爲100
複製代碼
除了上述兩種方式,還能夠選擇把圖像中的某個區域繪製到上下文中。
這時候要傳入9個參數:要繪製的圖像、源圖像的x座標、源圖像的y座標、源圖像的寬度、源圖像的高度、目標圖像的x座標、目標圖像的y座標、目標圖像的寬度、目標圖像的高度。
簡單來講就是,第2至第5個參數告訴咱們圖像上怎麼截取一部分,第6至第9個參數告訴咱們怎麼在canvas上畫出圖像。
context.drawImage(img, 50, 50, 200, 200, 150, 100, 100, 300); // 3. 截取源圖像的(50,50)處200x200像素的區域範圍內的圖像,並把圖像在canvas上的(150,100)處以100x300像素的方式繪製出來。
複製代碼
除了繪製圖像,2d上下文還提供了繪製文本的方法。
繪製文本主要有兩個方法:fillText()和strokeText()
這兩個方法都接收4個參數:要繪製的文本字符串、x座標、y座標和可選的最大像素寬度。
// 實心文字
let myCvs = document.getElementById('myCvs');
let context = myCvs.getContext('2d');
let text = '我愛前端FrontEnd1314!'; // 定義一個字符串做爲文本
context.fillStyle = '#f00'; // 指定填充顏色
context.fillText(text, 30, 60); // 指定文本字符串及x座標y座標
複製代碼
// 空心文字
context.strokeStyle = '#0f0'; // 指定描邊顏色
context.strokeText(text, 30, 120); // 指定文本字符串及x座標y座標
複製代碼
另外,繪製文本還有若干文本屬性能夠設置。
// 字體樣式
context.font = 'bold 30px 黑體';
複製代碼
文本的對齊方式有:start、end、left、right、center
// 對齊方式(start end left right center)
context.textAlign = 'start'; // 從左往右顯示文本
// context.textAlign = 'end'; // 從右往左顯示文本
複製代碼
文本的文字基線有:alphabetic、top、bottom、middle、hanging、ideographic
// 文本基線(alphabetic top bottom middle hanging ideographic)
context.textBaseline = 'middle';
複製代碼
// 測量字符串寬度
let width = context.measureText(text).width/2; // 獲取到文本字符串寬度的一半
context.strokeText(text, 30, 200);
context.strokeStyle = '#00f';
context.strokeText(text, 30-width, 200); // 檢驗可得 就是一半的長度
複製代碼
想要練習JS的小夥伴,進入JS練習羣 637059122 一塊兒進步~