本文重點還是要介紹Canvas,但每次提起Canvas,腦海總會想起SVG,因此先做個簡單的對比。

*Canvas 和 SVG 對比
Canvas 和 SVG 都是 html5 中推薦的也是主要的2D圖形繪制技術
- Canvas 提供畫布標簽和繪制API,技術比較新,注重柵格圖像處理。
- SVG是一套獨立的矢量圖形語言,成為W3C標準已經有十幾年,發展緩慢。
- Canvas 基于像素,提供 2D 繪制函數,是一種HTML元素類型,依賴于HTML,只能通過腳本繪制圖案;
- SVG為矢量圖,提供一系列圖形元素(Rect,Path,Circle,Line...);還有完整的動畫,時間機制,本身就能獨立使用,也可以嵌入到HTML中。O
**適用場景
- Canvas 提供功能更原始,動態渲染和大數據量繪制
- 依賴分辨率
- 不支持事件處理器
- 弱的文本渲染能力
- 能夠以.png 或 .jpg 格式保存結果圖像
- 最適合圖像密集型游戲,其中的許多對象會被頻繁的重繪。
- SVG功能更完善,適合靜態圖片展示,高保證文檔查看和打印的應用場景;
- 不依賴分辨率
- 支持事件處理器
- 最適合帶有大型渲染區域的應用程序(比如谷歌地圖)
- 復雜度高會減慢渲染速度(任何過度使用 DOM 的應用都不快)
- 不適合游戲應用
0. 什么是 Canvas
<canvas>是H5新增的組件,就像一塊幕布,一個可以使用腳本(通常為JAVAscript)在其中繪制圖形的HTML元素,他可以用來制作各種圖、表,或者一些動畫。 在沒有<canvas>的年代,繪圖只能借助Flash插件實現,需要使用JavaScript和flash交互,現在我們省去了flash,直接使用javascript完成繪制。
1. 創建一個 <canvas>
一個canvas定義了一個指定的矩形框,在這個范圍內我們可以隨意繪制html代碼
<canvas id="mycanvas" width="200" height="100"></canvas>
一個使用技巧:在<canvas>內部添加一些說明性的<html>代碼,什么作用呢?當瀏覽器支持<canvas>的時候,它將忽略<canvas>內部的內容,如果不支持,它將顯示內部的HTML:html代碼
<canvas id="mycanvas" width="200" height="100">
<p>您的瀏覽器不支持Canvas</p>
</canvas>
通過canvas.getContext屬性獲取canvas內部內容。javascript代碼
window.onload = function () {
var canvas = document.getElementById("mycanvas");
if (canvas.getContext) {
document.write("支持")
}else{
document.write("不支持")
}
}
結果展示

運行結果
2. 獲取canvas
- javascript通過id獲取canvas:
var c = document.getElementById("mycanvas");
- 獲得繪制環境:
一般頁面上繪制的都是2d圖像。所以我們使用的是'2d' 標準。擁有多種繪制路徑,矩形,圓形,字符以及圖像的方法。
var ctx = getContext('2d')
該方法能夠獲取canvasRenderingContext對象,我們所有的操作都需要通過這個對象來完成。注:如果想要繪制3d圖像,請使用WebGL規范,即
var gl = getContext('webgl');
我們已經獲取了canvasRenderingContext2D對象,接下來我們可以在該對象上開始繪制圖形了
3. canvas坐標
我們可以再canvas上繪制各種形狀,在此之前,我們先了解一下坐標系統。

canvas坐標以我們定義的canvas畫布的左上角為起點,水平向右為x軸,豎直向下為Y軸,以像素為單位,所以每個點都是非負整數。
4. 繪制圖形 - 矩形
我們必須明確知道,canvas元素本身沒有繪圖能力,所有的繪制工作必須在JavaScript內部完成公式方法
fillRect(x, y, width, height)
效果先看

canvas繪制一個紅色矩形
html代碼
<canvas id="cv" width="200" height="200"></canvas>
css代碼
* {background-color: #4e4e4e;}
canvas { background-color: white; }
javascript代碼
var c = docuent.getElementById("mycanvas");
var cts = document.getContext("2d");
ctx.fillStyle = "#ff0000";
ctx.fillRect(0,0,150,75);
案例分析 前兩步已經解釋過了,fillStyle屬性可以是顏色,漸變,或圖案;默認值是顏色中的黑色#000000。 fillRect(x, y, width, height);注意每個值的意思,別理解成(x1, y1, x2, y2)
5. canvas 繪制路徑 - 線條
canvas畫線,我們使用以下方法:
- moveTo(x, y) - 定義線條的開始位置;
- lineTo(x, y) - 定義線條的結束位置;
- 繪制線條我們必須使用到 "ink" 的方法,就像stroke().
效果先看

html代碼
<canvas id="cv" width="150" height="150">
<p>您的瀏覽器不支持canvas</p>
</canvas>
javascript代碼
var c=document.getElementById("cv");
var cxt=c.getContext("2d");
cxt.moveTo(20,10);
cxt.lineTo(200,100);
cxt.lineTo(20,100);
cxt.stroke();
css代碼
canvas {
border: solid 1px #000;
padding-left: 100px;
margin-left: 100px;
}
案例分析: 該案例中我故意埋了幾個點:
- 設置canvas寬度高度不足畫線設定的起始終或結束位置,所畫的線并不會超出畫布范圍。
- 設置padding-left: 100px;, 畫線受內邊距影響
- 設置margin-left: 100px;畫布右偏移了100像素,畫線相對畫布的位置依舊不變。
所以我們得出結論,無論什么情況下,畫線都只會在畫布內部有效。
6. Canvas繪制路徑 - 圓形
Canvas API 也使用了路徑的表示法。但是,路徑由一系列的方法調用來定義,而不是描述為字母和數字的字符串,比如調用 beginPath()和 arc() 方法。 一旦定義了路徑,其他的方法,如fill(),都是對此路徑操作。繪圖環境的各種屬性,比如 fillStyle,說明了這些操作如何使用。 繪制圓形,公式如下
arc(x, y, r, start, stop); //畫圓 start 和 stop 一般用Math.PI輔助得出
效果先看

在圓心為(70,60)處繪制一個半徑為40的圓
思路
繪制路徑調用beginPath() 和 closePath() 來描述開始和結束繪制, 調用fill()使其生效。
javascript代碼
var c = document.getElementById("cv");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(70, 60, 40, 0, 2*Math.PI);
ctx.closePath();
ctx.fillStyle="pink";
ctx.fill();
7. Canvas繪制圖形 - 綜合案例
在繼續往下說之前,我想讓大家再看一個復雜/系統一點的案例,這對我們更深入理解和鞏固canvas繪圖會有很大的幫助效果先看

綜合案例 - 繪制笑臉
html代碼
<canvas id="cv" width="150" height="150"></canvas>
javascript代碼
var c = document.getElementById("cv");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, 150, 150); // 擦除(0, 0)位置大小為150的矩形,擦除的意思就是把該區域變得透明
ctx.fillStyle="pink"; // 規定要填充區域的顏色(也可以是漸變或圖案)
ctx.fillRect(20, 20, 110, 110); //指定填充的區域
// 定義路徑,利用Path繪制復雜的路徑
var path = new Path2D();
path.arc(75, 75, 50, 0, 2*Math.PI, true); // true或false來指定是正向繪制還是反向繪制
path.moveTo(105, 78); // 將繪制筆頭移動到指定坐標
path.arc(75, 78, 30, 0, Math.PI, false); // 此處繪制一個 半圓
path.moveTo(65, 60);
path.arc(60, 60, 5, 0, 2*Math.PI, true);
path.moveTo(95, 60);
path.arc(90, 60, 5, 0, 2*Math.PI, true);
path.moveTo(75, 70);
path.lineTo(75, 78);
ctx.strokeStyle="white"; // 設置繪制筆頭的顏色
ctx.stroke(path); // 將所設定的路徑 畫 出來
8. 繪制文本陰影
canvas利用fillText()來規定文本,我們可以設置文本的字體,顏色,陰影等,與CSS完全一致。語法
c.fillText(text, padding-left, padding-top);
效果先看

給文字繪上陰影
javascript代碼
var c = document.getElementById("cv");
var ctx = c.getContext("2d");
ctx.shadowOffsetX = 4;
ctx.shadowOffsetY = 4;
ctx.shadowBlur = 4;
ctx.shadowColor = '#FF0000';
ctx.font = '18px Arial';
ctx.fillStyle = '#333333';
ctx.fillText('帶陰影的文字', 20, 40);
9. 繪制空心文本
繪制語法
c.strokeText(text, padding-left, padding-top);
效果先看

空心文字
很簡單,在上例的基礎上我做了一下兩個地方的修改,就得到了以上的效果。javascript代碼
ctx.font = '24px Arial';
ctx.strokeText('果汁涼茶', 25, 70);
10. 繪制漸變色
漸變色可以填充在矩形,圓形,線條,文本等等各種形狀中,填充我們指定的顏色繪制語法
// 創建 線性漸變
createLinearGradient( start_x, start_y, end_x, end_y);
// 創建一個徑向/圓/放射性漸變
createRadialGradient(start_origin_x, start_origin_y, start_r, end_origin_x, end_origin_y, end_r)
- 當我們使用漸變對象時,必須使用至少兩種顏色作為停止顏色。
- addColorStop()方法指定顏色停止,參數使用坐標來描述,可以是0-1;
- 使用漸變,設置fillStyle或strokeStyle()的值為漸變,然后繪制形狀,如矩形,文本,線條 。
createLinearGradient() 實例:
效果先看

線性漸變顏色填充
javascript代碼
var c = document.getElementById("cv");
var ctx = c.getContext("2d");
// 創建漸變規則
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "#ff0000");
grd.addColorStop(0.25, "#ffffff");
grd.addColorStop(0.5, "#00ff00");
grd.addColorStop(0.75, "#00ffff");
grd.addColorStop(1, "#ffff00");
// 將漸變顏色填充到畫布上
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 180, 80);
createRadialGradient() 實例
效果先看

放射性漸變顏色填充
html代碼
<canvas id="cv" width="200" height="200">
您的瀏覽器不支持canvas
</canvas>
javascript代碼
var c = document.getElementById("cv");
var ctx = c.getContext("2d");
// 創建漸變規則
var grd = ctx.createRadialGradient(100, 100, 3, 100, 100, 100);
grd.addColorStop(0, "#ff0000");
grd.addColorStop(0.25, "#ffffff");
grd.addColorStop(0.5, "#00ff00");
grd.addColorStop(0.75, "#00ffff");
grd.addColorStop(1, "#ffff00");
// 將漸變顏色填充到畫布上
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 180, 180);
11. 使用圖像
把一幅圖放置到畫布上,使用以下方法
使用語法
drawImage(image, start_x, start_y)
效果先看

圖片背景
javascript代碼
var c = document.getElementById("cv");
var ctx = c.getContext("2d");
var img=new Image()
img.src="flower.png"
cxt.drawImage(img,0,0);
結束語
除了能繪制基本的形狀和文本,還可以實現動畫、縮放、各種過濾和像素 轉換等高級操作。 如果考慮實現非常浮渣的操作,考慮一下優化方案:
- 通過創建一個不可見的canvas來繪圖,然后將最終繪制的結果復制到頁面的可見的canvas中;
- 盡量使用整數坐標而不是浮點數;
- 可以創建多個重疊的Canvas繪制不同的層,而不是在一個Canvas中繪制非常復雜的圖;
- 北京圖片如果不變,可以直接使用<img>標簽并放到最底層。
作者:果汁涼茶丶
鏈接:https://www.jianshu.com/p/7bb4896be61c
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。