Consider the following piece of code (test it yourself):
function draw() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
ctx.stroke();
ctx.moveTo(75, 75);
ctx.save();
ctx.setLineDash([3, 3]);
ctx.lineTo(90, 90);
ctx.stroke();
ctx.restore();
//ctx.stroke();
}
draw();
<canvas id="canvas"></canvas>
It plots this:
However, if I uncomment the last ctx.stroke()
, it draws a line on top of the dashed one, not sure if from (75, 75) to (90, 90) or the other way around:
function draw() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
ctx.stroke();
ctx.moveTo(75, 75);
ctx.save();
ctx.setLineDash([3, 3]);
ctx.lineTo(90, 90);
ctx.stroke();
ctx.restore();
ctx.stroke();
}
draw()
<canvas id="canvas"></canvas>
I thought saving and restoring didn’t affect the "path cursor", and there’s either any "pending draw command", and so I expected the extra (and accidental) stroke
after restore
don’t have any effect whatsoever.
What is going on exactly and how does save()/restore()
relate to this?
2
Answers
I answer myself. The reason of that effect turned out to have nothing to do with
save
andrestore
, but withstroke
. If you callstroke
repeatedly, you draw the path repeatedly, like if the laststroke
didn't "clear it up", so the path is still available to keep growing or adding more pieces to it.In my example above, the second
stroke
just had a different dash style, and so the secondstroke
was applied with other settings.In this other simpler example, I draw an almost transparent path, and as I added more and more calls to
stroke
, the path was progressively less transparent:save()
andrestore()
only saves the canvas drawing state, it does not saves/restores the actual line (with eglineTo
andstroke
).So your last
stroke
is still affected by thelineTo
called before.