Nikita Rybak
Nikita Rybak

Reputation: 68006

Clipping region is not cleared by restore()

I'm trying to draw shape1 clipped to region1 and shape2 clipped to region2. My natural assumption was that the following would get me desired effect.

context.save();
context.clip(region1);
context.fill(shape1);
context.restore();

context.save();
context.clip(region2);
context.fill(shape2);
context.restore();

However, to my surprise, the first restore() doesn't cancel current clipping region. Instead, the second region is combined with the first one. That is contrary to multiple online sources which claim that restore() is the way to go when you're done with clipping.

Live example. You can see that the second fill (blue) is clipped to region1+region2, not just region2.

Even stranger, this additive behaviour is enabled by the use of save/restore calls. If I drop them, second clip call is simply ignored.

So, I have two questions.

  1. Is there any logic to the way clipping works in html5 canvas?
  2. How can I accomplish what I originally set out to do?

Any help in figuring this out is appreciated!

Upvotes: 1

Views: 56

Answers (1)

markE
markE

Reputation: 105015

enter image description here

Always begin a new path drawing with context.beginPath().

Failing to do so will cause all previous drawing commands to be re-executed along with the newly added commands.

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

ctx.save();
ctx.beginPath();
ctx.rect(100, 0, 100, 300);
ctx.clip();
ctx.fillStyle = "lime";
ctx.fillRect(0,0,300,300);
ctx.restore();


ctx.save();
ctx.beginPath();
ctx.rect(50, 50, 200, 200);
ctx.clip();
ctx.fillStyle = "blue";
ctx.fillRect(0,0,300,300);
ctx.restore();
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

Upvotes: 1

Related Questions