Why does omitting beginPath() redraw everything?

梦想与她 提交于 2019-12-29 02:04:06

问题


Without context.beginPath(); the 10px red stroke at the top is redrawn as a 30px green stroke, even though the 30px and green context properties aren't called until after the stroke has already been drawn. Why is that?

window.onload = function() {
var canvas = document.getElementById("drawingCanvas");
var context = canvas.getContext("2d");  

context.moveTo(10,50);
context.lineTo(400,50);
context.lineWidth = 10;
context.strokeStyle = "red";
context.stroke();

//context.beginPath();
context.moveTo(10,120);
context.lineTo(400,120);
context.lineWidth = 30;
context.strokeStyle = "green";
context.stroke();
};

回答1:


The default internal Path object accumulates internally all path method calls such as lineTo, rect, arc and so forth (with a few exceptions such as fillRect, strokeRect, fillText etc. which are rasterized directly based on current settings). These are at this point only vector representations.

Every time you call stroke() or fill() the Path object is rasterized with the current stroke and/or fill color settings.

After you have rasterized the path it does not clear itself and you can continue to accumulate paths to it.

beginPath() is the only way to discard existing (sub) paths and start fresh. As it only clears the internal paths and not the rasterized result on the canvas this is usually never a problem unless you want to reuse those paths.

There is another way you can do this without using beginPath() when the Path object is exposed in more browsers (currently only Chrome let you use a Path object directly but does not seem to integrate it for canvas use quite yet).

You could make different Path objects and rasterize those separately:

var path1 = new Path();
var path2 = new Path();

path1.moveTo(10,50);
path1.lineTo(400,50);

context.lineWidth = 10;
context.strokeStyle = "red";
context.stroke(path1);

path2.moveTo(10,120);
path2.lineTo(400,120);

context.lineWidth = 30;
context.strokeStyle = "green";
context.stroke(path2);

Here you won't need beginPath() and you can reuse those objects - combined with translate and so forth you basically have a more object oriented canvas.

As a side note: Many have the impression that closePath() will "end" the path but all it does is to close the "loop" connecting the first point with the last point. You can still add new paths to it.



来源:https://stackoverflow.com/questions/21869609/why-does-omitting-beginpath-redraw-everything

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!