canvas的beginPath和closePath分析總結,包括多段弧的狀況

參考博文:
  Html5 canvas畫圖教程17:論beginPath的重要性


先看兩個例子
例1:html

<canvas id="myCanvas" width="300" height="300" style="border:1px solid #000000;">
    您的瀏覽器不支持 HTML5 canvas 標籤。
</canvas>
<script>
    var ctx = document.getElementById("myCanvas").getContext('2d');
    ctx.beginPath();
    ctx.moveTo(100.5,20.5);
    ctx.lineTo(200.5,20.5);
    ctx.strokeStyle = 'black';//默認strokeStyle='black', lineWidth=1, 此處可省略
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(100.5,40.5);
    ctx.lineTo(200.5,40.5)
    ctx.strokeStyle = 'red';
    ctx.stroke();
</script>

結果:
Paste_Image.pnghtml5

例2:去掉第2個beginPath()canvas

<canvas id="myCanvas" width="300" height="300" style="border:1px solid #000000;">
    您的瀏覽器不支持 HTML5 canvas 標籤。
</canvas>
<script>
    var ctx = document.getElementById("myCanvas").getContext('2d');
    ctx.beginPath();
    ctx.moveTo(100.5,20.5);//①
    ctx.lineTo(200.5,20.5);//②
    ctx.strokeStyle = 'black';//默認strokeStyle='black', lineWidth=1, 此處可省略
    ctx.stroke();

    ctx.moveTo(100.5,40.5);//③
    ctx.lineTo(200.5,40.5)//④
    ctx.strokeStyle = 'red';
    ctx.stroke();
</script>

結果:
Paste_Image.png瀏覽器

1. beginPath函數

  • canvas中的繪製方法(如stroke, fill),都會以「上一次beginPath」以後的全部路徑爲基礎進行繪製。好比例2中stroke了兩次,都是以第一次beginPath後的全部路徑爲基礎畫的。
    • 第一次stroke:畫①②,黑色
    • 第二次stroke:畫①②③④,紅色(其中①②紅色覆蓋以前的黑色)
  • 無論你用moveTo把畫筆移動到哪裏,只要不beginPath,那你一直都是在畫一條路徑(注:此處『一條路徑』並不是指連在一塊兒)
    • fillRect與strokeRect這種直接畫出獨立區域的函數,也不會打斷當前的path.

2. closePathcode

  • closePath的意思不是結束路徑,而是關閉路徑,它會試圖從當前路徑的終點連一條路徑到起點,讓整個路徑閉合起來。可是,這並不意味着它以後的路徑就是新路徑了
  • 與beginPath幾乎沒有關係:不要企圖經過閉合現有路徑來開始一條新路徑,而開始一條新路徑,之前的路徑也不會閉合。



對於繪製多段弧,看下面幾個例子:htm

例3:blog

var context = document.getElementById("myCanvas").getContext('2d');
context.strokeStyle="#005588";
for (var i = 0; i < 10; i ++){
    context.beginPath();
    context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
    context.closePath();
    context.stroke();
}

結果:
Paste_Image.png教程

例4:在例3的基礎上只去掉closePath()ip

var context = document.getElementById("myCanvas").getContext('2d');
context.strokeStyle="#005588";
for (var i = 0; i < 10; i ++){
    context.beginPath();
    context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
    //context.closePath();
    context.stroke();
}

結果:
Paste_Image.png

例5:在例3的基礎上去掉beginPath()和closePath()

var context = document.getElementById("myCanvas").getContext('2d');
context.strokeStyle="#005588";
for (var i = 0; i < 10; i ++){
    //context.beginPath();
    context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
    //context.closePath();
    context.stroke();
}

結果:
Paste_Image.png

可見,在這種狀況下,每一個弧畫完都會連到下一個弧的起點

例6:在例3的基礎上只去掉beginPath()

var context = document.getElementById("myCanvas").getContext('2d');
context.strokeStyle="#005588";
for (var i = 0; i < 10; i ++){
    //context.beginPath();
    context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
    context.closePath();
    context.stroke();
}

結果:
Paste_Image.png
這樣看不太清晰,咱們將i < 10改成i < 3,只顯示前三個:
Paste_Image.png

可見,在這種狀況下,每一個弧畫完都會先回到第一個弧的起點,而後再連到下一個弧的起點

例7:在例3的基礎上將stroke()改成fill()

var context = document.getElementById("myCanvas").getContext('2d');
    context.fillStyle="#005588";
    for (var i = 0; i < 10; i ++){
        context.beginPath();
        context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
        //context.closePath();
        context.fill();
}

結果:
Paste_Image.png

例8:在例7的基礎上去掉closePath()

var context = document.getElementById("myCanvas").getContext('2d');
    context.fillStyle="#005588";
    for (var i = 0; i < 10; i ++){
        context.beginPath();
        context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
        context.closePath();
        context.fill();
}

結果:
Paste_Image.png

比較例7和例8可知: 不管是否closePath(),結果都同樣。 由於closePath()對於fill()是沒有用的:不管是否closePath(),調用fill()時,canvas會自動把沒有封閉的路徑首尾相連,以後進行填充

相關文章
相關標籤/搜索