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

时间:2018-07-16 18:58:03

标签: javascript canvas

我无法在mdn(我知道它不是官方参考书)或其他任何地方找到此文件;所以,我以为我会问这个简单的问题:

例如,我有以下代码段:

nuget locals all -clear

它可以在chrome,firefox,ie11中使用,但是我想知道代码和跨浏览器支持的有效性。我找不到任何提及,但我认为必须有所提及。

因此,我的问题是,应该先使用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(); 还是先使用ctx.moveTo(在ctx.lineTo之后使用ctx.lineTo,这是完全可以的,为什么? (我无法找到答案,但是如果重复的话,抱歉。)

3 个答案:

答案 0 :(得分:1)

否,如果您刚刚致电moveTo,则无需在lineTo之前致电beginPath

根据specs

  

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

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

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

ensure there is a subpath的算法是:

  

当用户代理要确保路径上有坐标(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();
<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>

答案 1 :(得分:1)

就像其他人所说的那样,moveTo()用于设置行的起始点。 ctx.moveTo(x,y)如果要从另一点开始绘制,将很有用。

for (var i = 0, iMax = ys.length; i < iMax; i++) {
    ctx.lineTo(i, ys[i]);
}
//uncomment
// ctx.moveTo(20, ys[0]+20)
for (var i = 0, iMax = ys.length; i < iMax; i++) {
    ctx.lineTo(i+20, ys[i]+20);
}
ctx.stroke();

编辑此笔以查看其区别: https://codepen.io/caiodv/pen/rrLMRm

答案 2 :(得分:0)

我现在已正确签出:

ctx.moveTo函数仅在您要开始绘制新路径时才可以使用。您可以使用ctx.lineTo函数代替ctx.moveTo函数。

如果仅写ctx.lineTo(50, 50),则计算机会像ctx.moveTo(50, 50);一样理解它。如果没有来自ctx.lineTo的来电,您将无法进行绘画。在这种情况下,您必须在通话后再次使用来自ctx.lineTo的下一个通话。

var ctx = document.querySelector('canvas').getContext('2d');
ctx.lineTo(50, 50); // it is like moveTo
ctx.lineTo(150, 150);

ctx.moveTo(180, 150);
ctx.lineTo(180, 50);
ctx.stroke();
<canvas width="250" height="250"></canvas>

在上面的示例中,您可以看到两条未连接的线,因为通过调用ctx.moveTo,我们开始绘制一条新路径。