HTML5 Canvas clip overlaps previous clip - html

I have this weird issue where setting up multiple clip rectangles in HTML5 causes the drawing to bleed/overlap into the previous clip boxes, even when each one is contained in a ctx.save() - ctx.restore().
Here is the code example:
var c=document.getElementById("myCanvas2");
var ctx=c.getContext("2d");
// 1st clip
ctx.save();
ctx.rect(20,20,100,100);
ctx.stroke();
ctx.clip();
// draw red rectangle after 1st clip()
ctx.fillStyle="red";
ctx.fillRect(0,0,300,140);
ctx.restore();
// 2nd clip
ctx.save();
ctx.rect(140,20,100,100);
ctx.stroke();
ctx.clip();
// draw blue rectangle after 2nd clip
ctx.fillStyle="blue";
ctx.fillRect(0,0,300,140);
ctx.restore();
And a jsfiddle:
http://jsfiddle.net/4eXw9/1/
Is there a way to stop a clip call from bleeding/overlapping previous clips?

You are missing a beginPath() on the second clip:
// 2nd clip
ctx.save();
ctx.beginPath()
ctx.rect(140,20,100,100);
ctx.stroke();
ctx.clip();
Modified fiddle
What happens is that your new rect is merged with the first one since stroking/filling does not clear the path - so both are stroked/filled again. To clear the path you must explicitly clear it using beginPath(). As the path also is the basis for clip()..

Related

Drawing rectangle on the canvas in html 5

I am using html5 canvas and drawing rectangles on the canvas with the following code,
function drawRectangle(mouseX,mouseY)
{
ctx.beginPath();
ctx.rect(25,25,100,100);
ctx.fill();
ctx.stroke();
}
I am getting rectangle on the canvas,but the problem is
Within that rectangle multiple lines is coming as the border.I dont want those lines.
Please suggest me.
Why dont you just use fillRect?
function drawRectangle(mouseX,mouseY)
{
ctx.beginPath();
ctx.fillRect(25,25,100,100);
}

custom shape in canvas?

is there any way to create the shape using 'bezier Curve' or 'quadratic curve' in html5 canvas . or is there any method to draw a polygon in canvas
For a polygon you can use the following(where ctx is your canvas's getContext('2d')):
ctx.fillStyle=*hex code of the color you want it to be";
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.lineTo(x3,y3);
*add more points if needed using a lineTo(x,y) for each of your points*
ctx.closePath();
ctx.fill();
If you want a stroke polygon use ctx.strokeStyle and ctx.stroke() instead of ctx.fillStyle and ctx.fill()
Sure you can, you have at least:
quadraticCurveTo
bezierCurveTo
Have a look to this sample code:
http://www.html5canvastutorials.com/labs/html5-canvas-playing-card-suits/

HTML5 Canvas - Different Strokes

I have to draw a graph with 3 different lines. A line graph.
I tried doing this:
function draw()
{
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.lineWidth=10;
ctx.strokeStyle="teal";
ctx.moveTo(10,CompanyA[0]);
ctx.lineTo(110,CompanyA[1]);
ctx.lineTo(210,CompanyA[2]);
ctx.stroke();
ctx.strokeStyle="green";
ctx.moveTo(10,CompanyB[0]);
ctx.lineTo(110,CompanyB[1]);
ctx.lineTo(210,CompanyB[2]);
ctx.stroke();
ctx.strokeStyle="yellow";
ctx.moveTo(10,CompanyC[0]);
ctx.lineTo(110,CompanyC[1]);
ctx.lineTo(210,CompanyC[2]);
ctx.stroke();
}
But apparently, the last stroke draws for all the lines. So I get 3 yellow lines, instead of a Teal, a Green and a Yellow one.
I tried creating three different Context (ctx1, ctx2 and ctx3), but for some reason, all were drawn with the "ctx3.stroke()" call.
What would be the correct way to do this?
Add a ctx.beginPath() call before every line, and also a ctx.closePath() after every ctx.stroke()
If you don't, every time you call the stroke() method, not only the new line will be drawn but also all the previous lines will be drawn again (with the new strokeStyle), since it's the same line path that is still open.
Although there is a functional answer here, I'd just like to add this.
var ctx1 = canvas.getContext("2d");
var ctx2 = canvas.getContext("2d");
var ctx3 = canvas.getContext("2d");
They all refer to the same object. It does not create a new context, it uses the one that's already attached to the canvas element. Delta is totally right in saying that it strokes yellow over the entire path because you did not begin a new path. ctx.beginPath() will solve your troubles.

How to resize a canvas element on mouseover

I want to resize and slowly growing size canvas element (like a arc) on the mouseover event. How can I do this?
mouseover on the canvas itself? Just add an event listener and redraw the scene the way you want:
// Every time the mouse comes over the canvas the radius increases.
// you could even add a timer so that every time the mouse stays over
// the canvas the radius continues to increase constantly
can.addEventListener('mouseover', function(e) {
radius += 10;
ctx.clearRect(0,0,can.width, can.height);
ctx.beginPath();
ctx.arc(150, 150, radius, 0, Math.PI*.8, false);
ctx.stroke();
}, false);
http://jsfiddle.net/dAQdL/
mouseover an "object" drawn on the canvas? You're gonna have to add object persistence and detection to the canvas.

Scale command applying to multiple shapes

Wondering why the scale parameter of the variable ´ell´ is applying to the next two circles I have created as well:
var ell=canvas.getContext("2d")
ell.beginPath()
ell.lineWidth=2
ell.fillStyle="#FFFFFF"
ell.strokeStyle="#000000"
ell.scale(1.2,0.5)
ell.arc(125,190,30,0,2*Math.PI,false)
ell.fill()
ell.stroke()
var circ=canvas.getContext("2d")
circ.beginPath()
circ.lineWidth=1
circ.fillStyle="#FFFFFF"
circ.strokeStyle="#000000"
circ.arc(150,95,15,0,2*Math.PI,false)
circ.fill()
circ.stroke()
var circ2=canvas.getContext("2d")
circ2.beginPath()
circ2.fillStyle="#1d1d1d"
circ2.arc(155,90,4,0,2*Math.PI,false)
circ2.fill()
It's supposed to be an eyeball, the first shape is an oval and the next two are supposed to be circles, however they are getting squished by the scale command, and their positions are thrown off as well.
Any help appreciated, thanks!!
You could either use setTransform and reset the scale manualy or
call save() before applying the scale and call restore() when your done with it.
var ctx=canvas.getContext("2d")
ctx.save(); // save the context state
ctx.beginPath();
ctx.lineWidth=2;
ctx.fillStyle="#FFFFFF";
ctx.strokeStyle="#000000";
ctx.scale(1.2,0.5);
ctx.arc(125,190,30,0,2*Math.PI,false);
ctx.fill();
ctx.stroke();
ctx.restore(); // restore the state to the last save()
// you can reuse the same context
ctx.save();
ctx.beginPath();
draw the second circle...
take a look at
https://developer.mozilla.org/en/Canvas_tutorial/Transformations