jeffery_the_wind jeffery_the_wind - 2 months ago 11
HTML Question

layering and outlining on HTML canvas

I have been working on a seemingly simple graphic. I wish to create circles, with a line connecting the circles, and filling the circles in with some background. I have almost got it, but this one piece is tripping me up.

I can define the canvas, create the circles, and line connecting them just fine:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = $(window).width();
canvas.height = $(window).height();

ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 10;

//Create two nodes
ctx.arc( 100, 100, 25, 0, 2*Math.PI);
ctx.moveTo(200+25, 200)
ctx.arc( 200, 200, 25, 0, 2*Math.PI);

//line connecting two nodes
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);

ctx.stroke();


This would look like this:

enter image description here

What I then do is fill the circles with an image (this is why I use
clip()
), but using a white color fill for the sake of example demonstrates the problem as well:

//simulate filling in nodes with image, in this case solid color
ctx.clip();
ctx.fillStyle = "white";
ctx.fill();


enter image description here

Now I am almost there, but there are some jagged edges there that I have read is just a little "bug" in Chrome, and also I like that thick black outline on the circles. So, I want to go back over just the 2 circles and outline them. It seems no matter what I do, the context always remembers that line connecting the two, and I end up with the connector line over the top of the image after calling
stroke()
:

//would like to just re-outline circles, not connecting line
ctx.stokeStyle = "black";
ctx.arc( 100, 100, 25, 0, 2*Math.PI);
ctx.moveTo(200+25, 200)
ctx.arc( 200, 200, 25, 0, 2*Math.PI);
ctx.stroke();


enter image description here

What I can't figure out is how to just outline the 2 circles again after filling in the white background (loading the image)?

I think about it like drawing in layers. First I draw some lines, then I put the images in, then I draw again on top. Not sure if the html canvas is meant to be used like that. Thanks.

JSFiddle Example Here

Answer

You are forgetting to begin a new path.

Whenever you start a new shape you must use ctx.beginPath or the context will redraw all the previous paths.

BTW the jaggy circles is because you are re-rendering them, this causes the edges to get jaggies.

var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 500;
document.body.appendChild(canvas);
ctx.setTransform(1,0,0,1,0,-50); // just moving everything up to be seen in snippet.

ctx.beginPath();
ctx.strokeStyle = "black";
ctx.fillStyle = "#FAFAFF";
ctx.lineWidth = 10;

//Create two nodes
/*   dont draw the two circle the first time as you are
     doubling the render causing the edges to get to sharp
     making them appear jaggy.
ctx.arc( 100, 100, 25, 0, 2*Math.PI);
ctx.moveTo(200+25, 200)
ctx.arc( 200, 200, 25, 0, 2*Math.PI);
*/
//line connecting two nodes
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);

ctx.stroke();

ctx.beginPath();  // start a new path and removes all the previous paths

//Create two nodes
ctx.arc( 100, 100, 25, 0, 2*Math.PI);
ctx.moveTo(200+25, 200)
ctx.arc( 200, 200, 25, 0, 2*Math.PI);
ctx.fill();

ctx.beginPath();  // start a new path and removes all the previous paths

//Create two nodes
ctx.arc( 100, 100, 25, 0, 2*Math.PI);
ctx.moveTo(200+25, 200)
ctx.arc( 200, 200, 25, 0, 2*Math.PI);
ctx.stroke();

Comments