上一章節我們說到,線性路徑的繪製,主要利用movoTo(),lineTo()等方法,當然 Canvas 2D API 也提供了虛線的繪製方法,CanvasRenderingContext2D.setLineDash(); 下麵我們就來看看虛線的繪製方法 語法 參數 segments: 一個Array ...
上一章節我們說到,線性路徑的繪製,主要利用movoTo(),lineTo()等方法,當然 Canvas 2D API 也提供了虛線的繪製方法,CanvasRenderingContext2D.setLineDash();
下麵我們就來看看虛線的繪製方法
語法
ctx.setLineDash(segments);
參數 segments:
一個Array數組。
一組描述交替繪製線段和間距(坐標空間單位)長度的數字。
如果數組元素的數量是奇數, 數組的元素會被覆制並重覆。例如, [5, 15, 25] 會變成 [5, 15, 25, 5, 15, 25]。
這裡最後一句話有可能我們沒有看明白,沒關係我們繼續往下看。
我們先繪一條簡單的虛線
function drawDashed(){ cxt.lineWidth = 4; cxt.strokeStyle = 'green'; cxt.beginPath(); cxt.setLineDash([5, 15]); cxt.moveTo(20, 20); cxt.lineTo(400, 20); cxt.stroke(); }
因此繪製虛線也是非常簡單,我們試著改變setLineDash()方法的參數看看結果有什麼不同
function drawDashed(){
cxt.lineWidth = 4; cxt.strokeStyle = 'green'; cxt.beginPath(); cxt.setLineDash([5]); cxt.moveTo(0, 60); cxt.lineTo(400, 60); cxt.stroke(); cxt.lineWidth = 4; cxt.strokeStyle = 'red'; cxt.beginPath(); cxt.setLineDash([]); cxt.moveTo(0, 100); cxt.lineTo(400, 100);
cxt.stroke();
}
從這個例子我們可以看出當我們的參數數組只有一個元素時我們的 “線段與間隔” 是相等的,當參數數組的元素為空時,我們繪製的是一條實線。
我們在來看幾個例子
function drawDashed(){ cxt.lineWidth = 4; cxt.strokeStyle = 'blue'; cxt.beginPath(); cxt.setLineDash([20, 5]); cxt.moveTo(20, 40); cxt.lineTo(380, 40); cxt.stroke(); cxt.strokeStyle = 'green'; cxt.beginPath(); cxt.setLineDash([10, 20, 30]); cxt.moveTo(20, 80); cxt.lineTo(380, 80); cxt.stroke(); cxt.strokeStyle = 'red'; cxt.beginPath(); cxt.setLineDash([10, 20, 30, 40]); cxt.moveTo(20, 120); cxt.lineTo(380, 120); cxt.stroke(); }
有上圖幾個例子我們可以看出,setLineDash()方法是根據參數中的元素在 “線段與間隔” 之間形成組,然後進行迴圈,進而繪製出虛線。
但是第二個例子當中我們傳入的參數的元素個數是基數,看起來和參數元素為偶數時有點區別,它會複製元素並重覆,
這就是我們開始所說的 如果參數 segments元素的數量是奇數, 數組的元素會被覆制並重覆。[10, 20, 30] 會變成 [10, 20, 30, 10, 20, 30]。
getLineDash 方法
有setLineDash的方法去設置虛線的線段與間距,相應的有個方法是獲取虛線的線段和間距的方法。
ctx.getLineDash()
該方法返回一個 Array數組。一組描述交替繪製線段和間距(坐標空間單位)長度的數字。如果數組元素的數量是奇數,數組元素會被覆制並重覆。 例如, 設置線段為 [5, 15, 25] 將會得到以下返回值 [5, 15, 25, 5, 15, 25]。
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.setLineDash([5, 15]);
ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(400, 100);
ctx.stroke();
console.log(ctx.getLineDash()); // [5, 15]
擴展CanvasRenderingContext2D 繪製虛線
我們不僅可以利用 canvas API 繪製虛線,我們還可以擴展一個自己繪製虛線的方法。
擴展思路:
1. 獲取起點坐標
2. 計算虛線的總長度,計算虛線包含多少短線然後迴圈繪製
話不多說,我們直接上代碼
var canvas = document.getElementById('canvas'); var cxt = canvas.getContext('2d'); var moveToFunction = CanvasRenderingContext2D.prototype.moveTo; CanvasRenderingContext2D.prototype.moveToLocation = {}; // 重新定義moveTo方法 CanvasRenderingContext2D.prototype.moveTo = function (x, y){ this.moveToLocation.x = x; this.moveToLocation.y = y; moveToFunction.apply(this, [x, y]); }; CanvasRenderingContext2D.prototype.dashedLineTo = function(x, y, dashedLength){ dashedLength = dashedLength === undefined ? 5 : dashedLength; var startX = this.moveToLocation.x; var startY = this.moveToLocation.y; var deltaX = x - startX; var deltaY = y - startY; var numberDash = Math.floor(Math.sqrt(deltaX*deltaX + deltaY*deltaY)/dashedLength); for(var i=0; i < numberDash; i++){ this[i%2 === 0 ? 'moveTo' : 'lineTo'](startX + (deltaX/numberDash)*i, startY + (deltaY/numberDash)*i); //等同於this.moveTo(x, y)或者 this.LineTo(x, y) } this.moveTo(x, y); //連續繪製虛線時,起點從當前點開始 }; //繪製虛線 cxt.lineWidth = 3; cxt.strokeStyle = 'green'; cxt.moveTo(20, 20); cxt.dashedLineTo(200, 200); cxt.dashedLineTo(300, 100, 10); cxt.dashedLineTo(400, 300); cxt.stroke();
總結:
我們可以通過setLineDash()方法繪製虛線,該方法會以參數的元素個數為 組 的形式去進行 迴圈 繪製,但是要註意傳入方法是參數的元素個數。
我們還可以自定義擴展繪製虛線的方法,主要就是獲取起點進而計算線段數進行迴圈繪製
對canvas繪製圖形感興趣的同學,請持續關註後續更新,如有不對的地方也請指出並多多交流。
如需轉載,還請註明出處,非常感謝!