1

I have a canvas with a large image in the background and a smaller round image in front of it. I achieved this round image effect by using clip like so

ctx.save();

ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2, true);   
ctx.closePath();
ctx.clip();

ctx.drawImage(img,x-r,y-r,2*r,2*r);     // draw the image
ctx.restore();

then I want to rotate the round image, so I use a second context and rotate and redraw like so

backCanvas=document.createElement('canvas');    
backContext=backCanvas.getContext('2d');
backCanvas.width=w;
backCanvas.height=h;

backContext.translate(w/2,h/2);
backContext.rotate(a);

backContext.drawImage(img,-w/2,-h/2,w,h);

var imgData=backContext.getImageData(0,0,w,h);

ctx.save();

ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2, true);   
ctx.closePath();
ctx.clip();
ctx.putImageData(imgData,x,y);

ctx.restore();

But what happens is that the black-transparent background gets copied from the back canvas and the clip fails to "clip" it.

Any help would be appreciated

puk
  • 16,318
  • 29
  • 119
  • 199
  • Just FYI, If the image you are drawing to the canvas is on a different domain, you won't be allowed to call getImageData. – Simon Sarris Mar 11 '11 at 13:29
  • yes you're absolutely right. I ran into this problem a while back and got around it by issuing the command <--allow-file-access-from-files> – puk Mar 11 '11 at 21:10

1 Answers1

6

According to the specs,

The current path, transformation matrix, shadow attributes, global alpha, the clipping region, and global composition operator must not affect the getImageData() and putImageData() methods.

In your case, why are you using an additional canvas and pixel data manipulations? Why not just

ctx.save();

ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2, true);   
ctx.closePath();
ctx.clip();

ctx.translate(x, y);
ctx.drawImage(img, -r, -r, 2*r, 2*r);
// not restoring context here, saving the clipping region and translation matrix

// ... here goes the second part, wherever it is:
ctx.save();
ctx.rotate(a);
ctx.drawImage(img, -r, -r, 2*r, 2*r);
ctx.restore();
atomizer
  • 4,458
  • 1
  • 17
  • 9
  • sorry, I'm still new to the concept of clips and transformations. I'll give it a try – puk Mar 15 '11 at 05:06
  • It worked! Thanks. But I had to add a ctx.restore() at the end to make it work – puk Mar 15 '11 at 05:28