应该在 ctx.lineTo 之前使用 ctx.moveTo

dyl*_*nmc 1 javascript canvas

我在 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();
Run Code Online (Sandbox Code Playgroud)

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

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

Kai*_*ido 9

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

根据规格

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

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

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

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

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

所以你先调用lineTo之后beginPath实际上就转换为moveTo调用了。

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

请注意,只有在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();
Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas"></canvas>
Run Code Online (Sandbox Code Playgroud)