canvas

在繪製含有大量元素的圖表的時候,SVG 往往因爲性能問題而無法勝任。英文中 Canvas 的意思是“畫布”,不過這裏說的 Canvas 是 HTML5 中新出的一個元素。開發者可以在上面繪製一系列圖形。Canvas 在 HTML 文件中的寫法:

<canvas id="canvas" width="寬度" height="高度"></canvas>
Canvas 絕大部分的繪圖方法都與<canvsa> 標籤無關,需要使用 JavaScript 對其進行操作,這就是所謂的 Canvas API
首先獲取到這個元素:
var canvas = document.getElementById('canvas');
然後通過一個方法來獲取可以調用一切 Canvas API 的入口:
var ctx = canvas.getContext('2d');

Canvas 中的基本概念

座標

與數學上常見的笛卡爾座標系不太相同,Canvas 的座標系是計算機中常見的座標系,它長這樣:
這裏寫圖片描述
畫布的最左上角是 (0,0),往右 x 增大,往下 y 增大,而且 x 和 y 都是整數(就算在計算過程中不是整數,在繪製的時候也會當作整數處理),單位是像素。

繪圖

Canvas 中,你需要控制一隻畫筆的移動和繪製。 Canvas 中你可以直接利用一些函數來畫圖,不用去控制那隻畫筆的位置。

Canvas 中的基本圖形

通過上文定義的 ctx 變量可以幹許多有意思的事情,我們先看看如何繪製一些基本圖形。

線條

我們指定畫筆移動到某一點,然後告訴畫筆需要從當前這一點畫到另一點。我們可以讓畫筆多次移動、繪製,最後統一輸出到屏幕上。例子如下:

ctx.moveTo(10, 10);
ctx.lineTo(150, 50);
ctx.lineTo(10, 50);
ctx.moveTo(10, 20);
ctx.lineTo(40, 70);
ctx.stroke();

上面的代碼中,lineTo 是產生線條用的函數,執行完之後畫筆就移到了線條的終點。需要注意的是,線條此時並沒有顯示在屏幕上,必須調用 stroke 纔會顯示。這樣設計是有道理的,因爲向屏幕上輸出內容需要耗費大量的資源,我們完全可以先攢夠一波 lineTo,最後用 stroke 放一個大的。

路徑

繪製路徑非常簡單,只需要先告訴 ctx 一聲“我要開始畫路徑了”,然後通過各種方法(例如 lineTo)繪製路徑。如果需要畫一個封閉路徑,那就最後告訴 ctx一聲:“我畫完了,你把它封閉起來吧。”當然,不要忘記利用 stroke 輸出到屏幕上。
一個簡單的例子:

ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(150, 50);
ctx.lineTo(10, 50);
ctx.closePath();
ctx.stroke();

如果我不想只描繪路徑線條,而是想填充整個路徑呢?可以將最後一行的 stroke 改成 fill,這樣就跟使用了畫圖中的油漆桶一樣,封閉路徑裏面的內容就都被填充上顏色了:
ctx.fill();

弧 / 圓形

繪製弧的函數參數比較多:

ctx.arc(圓心 x 座標, 圓心 y 座標, 半徑, 起始角度, 終止角度, 是否爲逆時針);

注意,在 Canvas 的座標系中,角的一邊是以圓心爲中心的水平向右的直線。角度單位均爲弧度。方向爲逆時針,於是就有了這麼一個弧。如果方向爲順時針,那麼就會是一個跟它互補的、非常非常大的弧……
這裏寫圖片描述
所以如果轉了 2π 圈之後,弧就成了圓形,因此也可以使用繪製弧的方式來繪製圓形:

矩形

// 只描邊
ctx.strokeRect(左上角 x 座標, 左上角 y 座標, 寬度, 高度);
// 只填充
ctx.fillRect(左上角 x 座標, 左上角 y 座標, 寬度, 高度);

線條樣式 / 填充樣式

之前繪製的所有圖形都是黑色的,但是 Canvas 肯定不止這麼一種顏色。事實上,Canvas 可以單獨設置線條樣式和填充樣式,分別使用的是 strokeStyle 和 fillStyle。可能的值有三種:純色、漸變、圖像。既然線條樣式與填充樣式的使用方法相同,那麼下面統一以填充樣式爲例。如果想設置線條樣式,直接將所有的 fillStyle 改成 strokeStyle 即可,裏面的參數都不變。

/* 純色填充 */
// 普通的顏色
ctx.fillStyle = '#0000ff';
// 帶有透明度的顏色
ctx.fillStyle = 'rgba(64, 0, 127, 0.5)';

/* 漸變填充 */
// 設置漸變的尺寸(參數分別爲起始點的 x 和 y、終止點的 x 和 y)
var gradient = ctx.createLinearGradient(0, 0, 170, 0);
// 設置過渡色,第一個參數是漸變的位置,第二個參數是顏色
gradient.addColorStop(0, 'magenta');
gradient.addColorStop(0.5, 'blue');
gradient.addColorStop(1.0, 'red');
// 設置填充樣式
ctx.fillStyle = gradient;

/* 圖片填充 */
// 創建圖片
var image = new Image;
image.src = '/path/to/image.png';
// 創建圖片筆觸,可以指定圖片的平鋪方式,這裏是橫向平鋪
var pattern = ctx.createPattern(image, 'repeat-x');
// 設置筆觸填充
ctx.fillStyle = pattern;

關於漸變,除了代碼中提到的線性漸變以外,還有reateRadialGradient,也就是徑向漸變。

設置完填充樣式之後,就可以使用 fill 來填充啦!如果設置的是線條樣式,那麼就可以使用 stroke 來描邊。

當然,對於線條樣式,還有個額外的方法叫 lineWidth 可以用來控制線條的寬度。

文字

要想在畫布上畫文字,首先需要知道所使用的字體和字號:

ctx.font = '30px Verdana';

然後就可以通過 strokeText 或者 fillText 來對字體描邊或者填充字體。

ctx.strokeText("Hello Coding!", 23, 33);
ctx.fillText("Hello Coding!", 23, 66);
發佈了21 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章