zoukankan      html  css  js  c++  java
  • 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会自动把没有封闭的路径首尾相连,之后进行填充

  • 相关阅读:
    BZOJ 3522 Hotel
    BZOJ 1864 三色二叉树
    396595
    CodeForces
    CodeForces
    CodeForces
    E. 数字串
    算术基本定理总结
    Cyclic Nacklace 杭电3746
    Period
  • 原文地址:https://www.cnblogs.com/xuehaoyue/p/6549682.html
Copyright © 2011-2022 走看看