Does the beginPath and the closePath have to be included for this line to draw or for all of the graphics. I have the new HTML 5 Canvas book but this I was not completely certain of. I commented out the two lines and the line still displayed. What is the significance of these two lines.
Question: What does the beginPath() and closePath() do?
Code:
context.lineJoin='round';
context.lineCap='butt';
context.beginPath();
context.moveTo(10, 100);
context.lineTo(35, 100);
context.lineTo(35,125);
context.stroke();
context.closePath();
No, beginPath and closePath are not necessary.
A canvas context has a current path. You can add instructions to that path with methods such as moveTo and lineTo, among others. When you're done constructing the path, you can use methods such as stroke and fill, which draw on the canvas using the current path.
closePath is just another instruction you can add. You may not notice its effect when using fill, but when using stroke, it will (essentially) do a line back to the starting position, ‘closing’ the path. Compare and contrast:
ctx.moveTo(10, 10); ctx.moveTo(10, 10);
ctx.lineTo(90, 10); ctx.lineTo(90, 10);
ctx.lineTo(90, 90); ctx.lineTo(90, 90);
ctx.closePath();
ctx.stroke(); ctx.stroke();
beginPath, on the other hand, discards the previous path and lets you start a new one. Without it, you'd be appending more and more to the previous path, which may be undesirable. Compare and contrast:
ctx.moveTo(10, 10); ctx.moveTo(10, 10);
ctx.lineTo(90, 10); ctx.lineTo(90, 10);
ctx.lineWidth = 4; ctx.lineWidth = 4;
ctx.strokeStyle = "red"; ctx.strokeStyle = "red";
ctx.stroke(); ctx.stroke();
ctx.beginPath();
ctx.moveTo(10, 20); ctx.moveTo(10, 20);
ctx.lineTo(90, 20); ctx.lineTo(90, 20);
ctx.lineWidth = 2; ctx.lineWidth = 2;
ctx.strokeStyle = "blue"; ctx.strokeStyle = "blue";
ctx.stroke(); ctx.stroke();
beginPath() clears the old path so you can define a new one.
closePath() connects the first point with the last point and is not needed in your example. In any case it would have be used before stroking of filling to have an effect on the rasterized result.
Related
I want to either remove, change the colour of or change the position of the second line.
Also, is there a way to make the colour of an already created line different?
var cvs = document.querySelector('#canvas')
var ctx = cvs.getContext('2d')
cvs.height = window.innerHeight - 40
cvs.width = window.innerWidth - 40
window.addEventListener('resize', () => {
cvs.height = window.innerHeight - 40;
cvs.width = window.innerWidth - 40;
})
ctx.beginPath();
ctx.strokeStyle = 'red'
ctx.lineWidth = '5'
ctx.lineCap = 'round'
ctx.moveTo(200, 600)
ctx.lineto(100,100)
ctx.closePath();
//Second path which is what i want to remove only
ctx.beginPath();
ctx.strokeStyle = 'blue'
ctx.lineWidth = '37px'
ctx.moveTo(100,100)
ctx.lineTo(300, 500)
ctx.stroke()
ctx.closePath()
Objects painted on the canvas cannot be modified, but they can be painted over. Unlike HTML or SVG, the the canvas does not have its own DOM, so there is no way to access objects that have already painted on the canvas.
Approach 1:
The most common approach is to clear the canvas, adjust any attributes (position, color, etc), and repaint the objects onto the canvas.
ctx.clearRect(0, 0, cvs.width, cvs.height) //removes everything from the canvas
ctx.beginPath();
ctx.strokeStyle = 'red'
ctx.lineWidth = '5'
ctx.lineCap = 'round'
ctx.moveTo(200, 600)
ctx.lineTo(100,100)
ctx.stroke();
ctx.closePath(); //repaints the first object, the second path is gone.
Pros:
more robust: will work in all situations (even when objects overlap)
Scales well: better when lots of objects are painted
Cons:
every object has to be repainted on the canvas. (removes everything)
Approach 2:
The closest approach to removing a single object, it paints over the existing object and repaint it somewhere else.
ctx.beginPath();
ctx.strokeStyle = 'white' //background color
ctx.lineWidth = '37px'
ctx.moveTo(100,100);
ctx.lineTo(300, 500);
ctx.stroke();
ctx.closePath(); // covers up the second path
ctx.beginPath();
ctx.strokeStyle = 'blue'
ctx.lineWidth = '37px'
ctx.moveTo(100,100)
ctx.lineTo(600, 500) //repaint this object somewhere else
ctx.stroke()
ctx.closePath()
Pros:
Only removes the second path, leaves everything else
simpler when fewer objects are on the canvas
Cons:
Will not work when objects overlap.
Does not scale well: this solution will get more complex when more objects are being modified.
More resources:
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial
How do I empty the data in my ctx?
Basically the second stroke() should do anything, but draws another triangle. How do I clear this triangle from ctx?
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.save();
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();
ctx.stroke();//First stroke
ctx.restore();//Does not empty line paths?
ctx.strokeStyle = "green";
ctx.stroke();//Seccond stroke, same triangle drawn, but green (I do not want to draw the triangle)
https://jsfiddle.net/dh3e5wg6/
I'm wondering if the following code yields appropriate behavior. I feel like the top left square should still be green. that is, if I clip one area, ten restore, then paint in a second area, the canvas paints in BOTH areas. Why?
https://jsfiddle.net/s6t8k3w3/
var my_canvas = document.getElementById('canvas');
var ctx = my_canvas.getContext("2d");
//Make Clipping Path 1
ctx.save();
ctx.rect(20, 20, 100, 100);
ctx.clip();
//Fill Background with Green
ctx.fillStyle = 'rgba(0,255,0,1)';
ctx.fillRect(0, 0, my_canvas.width, my_canvas.height);
//Close Clipping Path 1
ctx.restore();
//Open Clipping Path 2
ctx.save();
ctx.rect(50, 50, 100, 100);
ctx.clip();
//Fill background with Blue
ctx.fillStyle = 'rgba(0,0,255,1)';
ctx.fillRect(0, 0, my_canvas.width, my_canvas.height);
//Draw Line
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(500, 500);
ctx.stroke();
//CloseClipping Path 2
ctx.restore();
You're not actually opening a second clipping path with that second ctx.save(); to do that, you need to call ctx.beginPath()
please I am a little confused so I need your help .
My question is how can we take advantage of moveTo() html5 method ?
for example I found this example on stackOverflow
function drawSmile(ctx, x, y, faceRadius, eyeRadius) {
ctx.save(); // save
ctx.fillStyle = '#FF6'; // face style : fill color is yellow
ctx.translate(x, y); // now (x,y) is the (0,0) of the canvas.
ctx.beginPath(); // path for the face
ctx.arc(0, 0, faceRadius, 0, 6.28);
ctx.fill();
ctx.fillStyle = '#000'; // eye style : fill color is black
ctx.beginPath(); // path for the two eyes
ctx.arc(faceRadius / 2, - faceRadius /3, eyeRadius, 0, 6.28);
ctx.moveTo(-faceRadius / 2, - faceRadius / 3); // sub path for second eye
ctx.arc(-faceRadius / 2, - faceRadius / 3, eyeRadius, 0, 6.28);
ctx.fill();
ctx.restore(); // context is just like before entering drawSmile now.
}
drawSmile(c, 200,200, 60, 12);
but when I removed the line number 11 in the code which uses the moveTo method no thing changed!!!!.
The moveTo() HTML5 method lets you to move your (0,0) origin to another point in the space.
Here you have and example. To draw some kind of triangle:
// first part of the path
ctx.moveTo(20,20);
ctx.lineTo(100, 100);
ctx.lineTo(100,0);
// second part of the path
ctx.moveTo(120,20);
ctx.lineTo(200, 100);
ctx.lineTo(200,0);
// indicate stroke color + draw the path
ctx.strokeStyle = "#0000FF";
ctx.stroke();
In this example we simply called moveTo(x, y) after drawing the first part of the path (the shape on the left). Then, we only called stroke() once to draw the whole path.
i currently have the following:
ctx.save();
ctx.translate(459,258);
ctx.rotate(sec * Math.PI/36);
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(135,0);
ctx.lineTo(210,0);
ctx.strokeStyle = 'rgba(0,153,255)';
ctx.stroke();
ctx.restore();
drawing a circle of lines (stroke). I want to convert it into a clearRect so that instead of drawing this circle of lines, i want it to erase a circle in the same shape... how can i do this?
i tried doing this but it did not work:
ctx.save();
ctx.translate(459,258);
ctx.rotate(sec * Math.PI/36);
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(135,0);
ctx.lineTo(210,0);
ctx.clear();
ctx.restore();
thanks.