首頁 >web前端 >H5教程 >如何繪製路徑-線段

如何繪製路徑-線段

PHP中文网
PHP中文网原創
2017-06-20 14:00:452792瀏覽

Canvas繪圖環境中有些屬於立即繪製圖形方法,有些繪圖方法是基於路徑的。

立即繪製圖形方法僅有兩個strokeRect(),fillRect(),雖然strokezText(),fillText()方法也是立即繪製的,但是文字不算是圖形。

基於路徑的繪製系統
大多數繪製系統,如:SVG(Scalable Verctor Graphics, 可縮放的向量圖形),Adobe Illustrator等,都是基於路徑的,

使用這些繪製系統時,你需要先定義一個路徑,然後再對其進行描邊或填充,也可以描邊加填充這樣圖形才能顯示出來。

Canvas中的三種繪製方式:

 

繪製一條線段

 

#Canvas繪圖環境中,線段也是基於路徑繪製的,稱為線性路徑,創建線性路徑的方法:moveTO()與lineTo(),在建立路徑之後呼叫stroke()方法,才能在Canvas中畫出線段出來。

這就是前面我們所說的基於路徑的繪製方法,必須對其進行描邊或填充;

通常兩點連一線因此繪製線段非常簡單,透過moveTO()指定線的起點,透過lineTo()移動到另一個點。

function drawLine(){
    cxt.moveTo(50, 50);
    cxt.lineTo(100, 100);
}

然而這樣我們在畫布中是看不見線段的,前面我們說到基於路徑的繪製方法,必須描邊或填滿。所以要看到結果,我們必須還要使用stroke()方法。

因此我們把方法修改成下面這樣就會畫出一條線段

#
function drawLine(){
    cxt.moveTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}

##我們只使用lineTo()也是能在畫布中繪製出線段的,我們把上面的程式碼改成如下面所示,效果也是一樣的

function drawLine(){
    cxt.lineTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}

總結下moveTo()與lineTo()的用法

  • #moveTo(x,y): 將筆觸移到指定的座標x以及y上,在目前路徑中增加一條子路徑,該方法不會清除目前路徑中的任何子路徑。

  • lineTo(x,y): 繪製一條從目前位置到指定x以及y位置的直線,如果目前路徑中沒有子路徑,那麼這個方法的行為與moveTo()一樣。 如果目前路徑中存在子路徑,此方法會將你所指定的這個點加入子路徑中。

改變線段的樣式

#改變線段的寬度

 

function= 14;
    cxt.lineTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}
 

#改變線段的顏色##

function drawLine(){
    cxt.lineWidth = 14;
    cxt.strokeStyle = 'green';
    cxt.lineTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}
 

我們也可以利用CanvasGradient物件或CanvasPattern物件為線段新增漸層色或圖案

function drawLine(){
    cxt.lineWidth = 14;var gradient = cxt.createLinearGradient(0, 0, canvas.width/2, canvas.height/2);
    gradient.addColorStop(0, 'blue');
    gradient.addColorStop(0.5, 'purple');
    gradient.addColorStop(1, 'yellow');
    cxt.strokeStyle = gradient;
    cxt.lineTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}

 

beginPath()與closePath()

從上面canvas中的三種繪製方式中我們可以看出,第二行的弧形路徑是開放路徑,最後一行的弧形是封閉路徑。那麼封閉的路徑是怎麼實現的呢?

下面我們來看看canvas中路徑繪製中兩個比較重要的方法

  • beginPath():清除目前所有子路徑,以此來重置目前路徑,重新規劃一條路徑。

  • closePath(): 用來封閉某段開放路徑。不是必需的,如果圖形是已經閉合了的,即當前點為開始點,則該函數什麼都不做。

先畫出一條折線

function drawLine(){
    cxt.strokeStyle = 'green';
    cxt.lineWidth = 2;
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.stroke();
}

修改上面例子中的代码在代码中添加beginPath()与closePath()方法

cxt.strokeStyle = 'green'= 250, 5050, 150150, 150150, 250  cxt.closePath();
}

可以看出我们在画布中绘制了两条路径

注意:调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo()。所以我们在绘制图形的时候一定要先使用beginPath()。

 

我们继续修改我们的代码

function drawLine(){//描边三角形cxt.strokeStyle = 'green';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.closePath();
    cxt.stroke();//折线cxt.translate(150, 0);
    cxt.strokeStyle = 'red';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.stroke();
    cxt.closePath();//绿色填充三角形cxt.translate(150, 0);
    cxt.fillStyle = 'green';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.fill();
    cxt.closePath();//红色填充三角形cxt.translate(150, 0);
    cxt.fillStyle = 'red';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.closePath();
    cxt.fill();
}

从上面的例子我们可以看出closePath()的位置不同,也会影响我们的图形

注意:当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以此时closePath()函数不是必须的。

但是调用stroke():如果你在stroke()方法之前只用closePath()会形成闭合路径,如果在stroke()方法之后调用closePath()方法,此时图形已经绘制完成,当前的绘制路径已经关闭,所以closePath()方法不起作用。

 

线段与像素边界

先来看一个例子

function drawLine(){//描边三角形cxt.lineWidth = 1;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(450, 50);
    cxt.stroke();
    cxt.beginPath();
    cxt.moveTo(50.5, 150.5);
    cxt.lineTo(450.5, 150.5);
    cxt.stroke();
}

 

从图中我们可以看出,我们将两条线段的lineWidth都是设置为1像素,但是上面的线段画出的却是两像素。

 

如果你在某2个像素的边界处绘制一条1像素宽的线段,那么该线段实际会占据2个像素的宽度;

因为当你在像素边界处绘制一条1像素宽度的垂直线段时,canvas的绘图环境对象会试着将半个像素画在边界中线的右边,将另外半个像素画在边界中线的左边。

然而,在一个整像素的范围内绘制半个像素宽的线段是不可能的,所以在左右两个方向上的半个像素都被扩展为1个像素。

 

另外一方面,绘制在两个像素之间,这样的话,中线左右两端的那半个像素就不会延伸,它们结合起来恰好占据1个像素的宽度。所以说,如果要绘制一条真正1像素宽度的线段,你必须将该线段绘制在某两个像素之间

 

网格的绘制

既然我们已经明白了如何绘制真正的1像素的线段,那我们就开始绘制网格

function drawLine(stepx, stepy){
    cxt.lineWidth = 0.5;
    cxt.strokeStyle = 'green';//绘制竖线for(var i= stepx + 0.5; i< cxt.canvas.width; i+= stepx){
        cxt.beginPath();
        cxt.moveTo(i, 0);
        cxt.lineTo(i, cxt.canvas.height);
        cxt.stroke();
    }//绘制横线for(var i= stepy + 0.5; i< cxt.canvas.height; i+= stepy){
        cxt.beginPath();
        cxt.moveTo(0, i);
        cxt.lineTo(cxt.canvas.width, i);
        cxt.stroke();
    }
}
drawLine(10, 10);

上面範例我們將線段繪製在兩個像素之間的像素上,而且繪製出來的線段僅有0.5像素寬,

雖說canvas規格沒有明文規定,不過所有瀏覽器的Canvas實作都使用了「抗鋸齒」技術,以便創造出「次像素」線段的繪製效果來

 

總結

#本節內容主要解譯canvas中路徑中線性路徑的繪製方法,主要是利用moveTo()定義起點,lineTo()定義終點,stroke()描繪當前路徑。這三個方法繪製線段

canvas中繪製路徑有兩個重要的方法,beginPath()與closePath()。繪製圖形前先呼叫beginPath()是繪製多個圖形必要的步驟。

closePath()在使用fill()時是可以省略的,而且也要注意closePath()方法的呼叫位置。

繪製線段時我們可以使用 lineWidth改變線段的寬度,strokeStyle改變線段的顏色。

弄清楚線段的像素邊界,這樣我們才能繪製出真正的1像素線寬的線段。

以上是如何繪製路徑-線段的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn