Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
456 views
in Technique[技术] by (71.8m points)

canvas - Why does omitting beginPath() redraw everything?

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();
};
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...