ctx.fill方法填充的两个重叠图中的哪一个?

时间:2017-08-26 03:09:50

标签: javascript canvas fill stroke

我有两个略有不同的代码片段,会产生不同的结果。在第一部分中,我首先绘制内部三角形,然后绘制外部正方形。在第二部分中,我首先绘制外部正方形,然后绘制内部三角形。但是,对于第二段代码,整个方块都被填充。为什么会这样?

<body>
  <canvas id="c" width="300" height="300"></canvas>
  <script>
    var c = document.getElementById('c');
    var ctx = c.getContext('2d');

    ctx.moveTo(75 ,75);
    ctx.lineTo(125, 75);
    ctx.lineTo(125, 125);
    ctx.lineTo(75, 75);
    ctx.fill();

    ctx.moveTo(50, 50);
    ctx.lineTo(150,50);
    ctx.lineTo(50,150);
    ctx.lineTo(50,50);
    ctx.stroke();

  </script>
</body>

The result of the above code

<body>
  <canvas id="c" width="300" height="300"></canvas>
  <script>
    var c = document.getElementById('c');
    var ctx = c.getContext('2d');

    ctx.moveTo(50, 50);
    ctx.lineTo(150,50);
    ctx.lineTo(50,150);
    ctx.lineTo(50,50);
    ctx.stroke();

    ctx.moveTo(75 ,75);
    ctx.lineTo(125, 75);
    ctx.lineTo(125, 125);
    ctx.lineTo(75, 75);
    ctx.fill();

  </script>
</body>

The result of the above code

1 个答案:

答案 0 :(得分:0)

使用ctx.beginPath清除旧路径并开始新路径。

使用路径构建方法时,ctx.rectctx.arcctx.moveToctx.lineToctx.quadraticCurveToctx.bezierCurveTo,{{1 }},ctx.ellipsectx.arcTo您要添加到2D上下文内存中保存的当前路径。

当您致电ctx.closePathctx.fill时,您会渲染当前存储的路径。使用第1段路径构造函数方法不断添加存储的路径。路径保持存储状态,直到您调用ctx.stroke,这将清除当前路径并开始新路径。

注意调整画布大小也会清除当前路径并将画布上下文重置为默认状态,但不建议将其恢复为默认状态状态。

因此,要正确渲染这两条路径,请使用ctx.beginPath为每个要渲染的路径创建新路径。

ctx.beginPath

注意,当您使用const canvas = document.createElement("canvas"); document.body.appendChild(canvas); const ctx = canvas.getContext('2d'); ctx.beginPath(); // begin a new path // Note that the path is offset by 0.5 // A line is defined by its center. A line 1 pixel wide has half the line // above and half below. If you render at the pixel boundary from 50,50 to 100,50 // half the line is rendered on the 49th row and half on the 50th row. // Offsetting by 0.5 ensures the line is rendered on the pixels you want // producing a better quality line. ctx.moveTo(50.5, 10.5); ctx.lineTo(150.5,10.5); ctx.lineTo(50.5,110.5); //ctx.lineTo(50,10); ctx.closePath(); // use this as lineTo does not connect the start and end lines. ctx.stroke(); ctx.beginPath(); ctx.moveTo(75 ,75); ctx.lineTo(125, 75); ctx.lineTo(125, 125); ctx.lineTo(75, 75); // you don't need to use closePath here as fill does not treat continuous path // segments as special. ctx.fill();时,方法ctx.beginPath的行为类似于ctx.lineTo,如果它是ctx.moveTo之后调用的第一个方法{1}}致电。这有助于降低渲染函数的复杂性。

正确使用ctx.beginPath

认为ctx.closePathctx.closePath相关是一个常见的错误。函数ctx.beginPath是一个路径构造函数,它通过创建从最后添加的点到ctx.closePath调用后的最后一个ctx.moveTo或第一个点的行来添加到当前路径。

ctx.beginPath

为什么要使用const canvas = document.createElement("canvas"); document.body.appendChild(canvas); const ctx = canvas.getContext('2d'); canvas.width = 400; ctx.beginPath(); // begin a new path ctx.beginPath(); ctx.moveTo(100.5, 10.5); ctx.lineTo(150.5, 110.5); ctx.lineTo(50.5, 110.5); ctx.closePath(); // creates a line from (50,110) to (100,10) ctx.moveTo(300.5, 10.5); ctx.lineTo(350.5, 110.5); ctx.lineTo(250.5, 110.5); ctx.closePath(); // creates a line from (250,110) to (300,10) ctx.stroke();

ctx.closePath()确保形状的两端作为单个路径连接,并使用ctx.closePath设置进​​行渲染。如果您不使用它,则路径已打开,ctx.lineJoin设置将应用于结尾

该代码段显示了ctx.lineCap与使用ctx.closePath之间的差异,以创建一条回到开头的行。注意三角形顶部的连接。左侧使用ctx.lineTo,右侧使用ctx.closePath

ctx.lineTo