admin管理员组

文章数量:1401484

I couldn't find this on mdn (I know it's not the official reference) or anywhere else; so, I thought I would just ask this easy question:

For example, I have the following snippet:

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();

It works in chrome, firefox, ie11, but I was wondering about the validity of the code and cross-browser support. I couldn't find any mention of it, but I assume that there must be some mention of it.

Therefore, my question is, should one use ctx.moveTo before using ctx.lineTo or is it pletely fine to merely use ctx.lineTo first (after ctx.beginPath), and why? (I couldn't find an answer on this, but sorry if it's a duplicate.)

I couldn't find this on mdn (I know it's not the official reference) or anywhere else; so, I thought I would just ask this easy question:

For example, I have the following snippet:

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();

It works in chrome, firefox, ie11, but I was wondering about the validity of the code and cross-browser support. I couldn't find any mention of it, but I assume that there must be some mention of it.

Therefore, my question is, should one use ctx.moveTo before using ctx.lineTo or is it pletely fine to merely use ctx.lineTo first (after ctx.beginPath), and why? (I couldn't find an answer on this, but sorry if it's a duplicate.)

Share Improve this question asked Jul 16, 2018 at 18:58 dylnmcdylnmc 4,0204 gold badges31 silver badges44 bronze badges 3
  • 3 If you want your path to start at somewhere other than 0, 0 then you need to use moveTo or translate first. – Dan Prince Commented Jul 16, 2018 at 19:01
  • 1 Pointer will be at x=0 and y=0 at first. On your first lineTo call, it will draw line between (0,0) to the given point. And pointer will move to that point. Like so on. If you want to change the pointer position use ctx.moveTo(x, y) . pointer will move to (x, y) – Durga Commented Jul 16, 2018 at 19:01
  • Ah. Ok. For some reason, despite using canvas quite frequently, I was not aware that the path was initially positioned at (0,0), but this makes a lot of sense. Luckily, this is where I wanted to start it. Thanks :) (I tried to upvote Durga but it said that I cannot upvote after undo-ing upvote, even though this I did no such thing .. sorry.) Perhaps this should be referenced on mdn? Or am I just a dummy for not experimenting first? O_O – dylnmc Commented Jul 16, 2018 at 19:04
Add a ment  | 

3 Answers 3

Reset to default 9

No, there is no need to call moveTo before a lineTo if you just called beginPath.

According to specs:

The lineTo(x, y) method, when invoked, must run these steps:

  1. If either of the arguments are infinite or NaN, then return.
  2. If the object's path has no subpaths, then ensure there is a subpath for (x, y).
  3. Otherwise, connect the last point in the subpath to the given point (x, y) using a straight line, and then add the given point (x, y) to the subpath.

After calling beginPath, the object's path has no subpaths, and thus, we end in the second bullet of this algorithm.

The algorithm to ensure there is a subpath is:

When the user agent is to ensure there is a subpath for a coordinate (x, y) on a path, the user agent must check to see if the path has its need new subpath flag set. If it does, then the user agent must create a new subpath with the point (x, y) as its first (and only) point, as if the moveTo() method had been called, and must then unset the path's need new subpath flag.

So you first call to lineTo after beginPath is actually converted to a moveTo call.

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

Note that only lineTo has its algorithm set to stop right after this ensure there is a subpath algorithm, this means that other methods will continue drawing after this inserted 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>

I have checked it out now correctly:

ctx.moveTo function you can use only if you want to start to draw a new path. And ctx.lineTo function you can use instead of ctx.moveTo function.

If you write only ctx.lineTo(50, 50) then the puter understands it like ctx.moveTo(50, 50);. Without following call from ctx.lineTo you can not draw. In this case you have to use after this call the next call from ctx.lineTo again.

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>

In my example above you can see two unconnected lines because with the call ctx.moveTo we start to draw a new path.

Like others have said, moveTo() is used to set the initial point of your line. ctx.moveTo(x,y) would be useful if you wanted to draw again, but starting from another point.

for (var i = 0, iMax = ys.length; i < iMax; i++) {
    ctx.lineTo(i, ys[i]);
}
//unment
// 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();

Edit this pen to see the difference: https://codepen.io/caiodv/pen/rrLMRm

本文标签: javascriptShould One Use ctxmoveTo Before ctxlineToStack Overflow