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


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


先看兩個例子
例1:

<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.png

例2:去掉第2個beginPath()

<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. closePath

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

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

例3:

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()

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會自動把沒有封閉的路徑首尾相連,之后進行填充


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM