Reputation:
I want to draw a couple of simple lines to a canvas but it will not work if I do not have beginPath() and restore() in my scripting code. Do you have to have these to draw something to the HTML 5 Canvas?
Code:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.lineWidth="5";
ctx.strokeStyle="green"; // Green path
ctx.moveTo(0,75);
ctx.lineTo(250,75);
ctx.strokeStyle="purple"; // Purple path
ctx.moveTo(50,0);
ctx.lineTo(150,130);
</script>
</body>
</html>
Upvotes: 0
Views: 1651
Reputation: 19294
A canvas deals with paths.
So, as the name suggests, beginPath will starts a new path.
Each retained draw command you will call after-wise will add-up to the current path.
( retained draw command are commands that have no direct effect : moveTo, lineTo, (Curve)To, arc, rect. )
Rq1 : Using moveTo is a special command : it will begin a new sub-path, it's like releasing the pen from the paper.
Rq2 : closePath is not required, use it if you want to link the last point to the first one easily.
When using fill or stoke, the current retained path (=all the sub-path of the current path) will get stroked/filled using current transform, clipping and color setting.
Notice that there are also direct command : fill/strokeRect, fill/strokeText, drawImage, get/putImageData.
Those commands do not require to begin a new path, and do not affect the current path -they directly draw on the canvas-.
So rule is simple :
• if you use retained commands, you must use beginPath.
• If you use direct commands do not use beginPath, just send the command.
As you noticed, you can change a lot of settings on the canvas :
• you have render settings : strokeStyle / fillStyle / globalCompositeOperation / globalAlpha / lineWidth / font / textAlign/ shadow / ...
• you have transform settings that allow you to translate/scale/rotate the next draw.
• you can define clipping to avoid the draw to occur in some areas.
save() and restore() allows you not to get lost in the status of the current canvas.
Rule is : anyway you change the context in a way that could affect the render of other drawings you make, just save() before, and restore after.
example 1 :
function strokeLine ( x1, y1, x2, y2, color) {
ctx.beginPath();
ctx.strokeStyle = color;
ctx.moveTo(x1, y1);
ctx.lineTo(x2,y2);
ctx.stroke();
}
i used moveTo/lineTo (retained) command, so without thinking i use beginPath. here the strokeStyle is set on each call, so no need to save context.
example 2 :
function drawImageRotated( img, x, y, rotation ) {
ctx.save();
ctx.translate(x + img.width/2, y + img.height/2); // translate to the middle of the image
ctx.rotate(rotation); // rotate context
ctx.drawImage(img, x - img.width/2, y - img.height/2 ); // draw the image in rotated context
ctx.restore();
}
here no need to use beginPath() since i use only a direct command (drawImage).
But concerning canvas status, i don't want the context to remain translated/rotated after the call. So i started by a save, and ended by a restore, so the caller keeps the same context after the call.
Upvotes: 3
Reputation: 21575
beginPath()
is used to start drawing a contour, you will need it. Then we use stroke()
to actually draw to the HTML5 Canvas visually.
ctx.beginPath(); // Start drawing
// Drawing Methods Here
ctx.stroke() // Show what we drew.
restore()
is for changes in the state of the Canvas: rotation, scaling, skew, etc. This method reverts it to the last state of the Canvas that was saved. But it isn't used for actually drawing on our canvas, but changing it's state.
Upvotes: 3