首页 > 解决方案 > 应该在 ctx.lineTo 之前使用 ctx.moveTo

问题描述

我在 mdn 上找不到这个(我知道这不是官方参考)或其他任何地方;所以,我想我会问这个简单的问题:

例如,我有以下代码段:

var can = document.getElementById("can");
var ctx = can.getContext("2d");
var w = can.width; var h = can.height;
var ys = [1, 3, 2, 4, 5, 3, 2, 4, 5, 6, 7, 3];
ctx.beginPath();
for (var i = 0, iMax = ys.length; i < iMax; i++) {
    ctx.lineTo(i, ys[i]);
}
ctx.stroke();

它适用于 chrome、firefox、ie11,但我想知道代码的有效性和跨浏览器支持。我找不到任何提及它,但我认为必须提及它。

因此,我的问题是,应该在使用ctx.moveTo之前使用ctx.lineTo还是只使用ctx.lineTo第一次(之后ctx.beginPath)完全可以,为什么?(我找不到答案,但如果它是重复的,我很抱歉。)

标签: javascriptcanvas

解决方案


不,如果您刚刚调用,则无需moveTo在 a 之前调用。lineTobeginPath

根据规格

调用 lineTo(x, y) 方法时,必须运行以下步骤:

  1. 如果任一参数是无限或 NaN,则返回。
  2. 如果对象的路径没有子路径,则确保 (x, y) 存在子路径。
  3. 否则,使用直线将子路径中的最后一个点连接到给定点 (x, y),然后将给定点 (x, y) 添加到子路径中。

调用后beginPath对象的路径没有子路径,因此,我们以该算法的第二个项目符号结束。

确保存在子路径的算法是:

当用户代理要确保路径上有坐标 (x, y) 的子路径时,用户代理必须检查该路径是否设置了需要新的子路径标志。如果是这样,那么用户代理必须创建一个新的子路径,将点 (x, y) 作为它的第一个(也是唯一的)点,就像调用了 moveTo() 方法一样,然后必须取消设置路径的需要新子路径旗帜。

所以你第一次调用lineTobeginPath实际上是转换为moveTo调用。

var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.lineTo(120, 120); // converted to moveTo
ctx.lineTo(200, 150);
ctx.stroke();
<canvas id="canvas"></canvas>

请注意,lineTo将其算法设置为在此之后立即停止以确保存在子路径算法,这意味着其他方法将在此插入后继续绘制moveTo

var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(60, 60, 30, 0, Math.PI);
// first we'll get new (x, y) coordinates of the first point of our arc (90, 60)
// since there is no subpath yet, we implicitely call moveTo(90, 60)
// then we draw the arc as usual
ctx.stroke();
<canvas id="canvas"></canvas>


推荐阅读