Reputation: 10683
In attempting to get a drawing of a canvas and redrawing it onto the same canvas later is giving unexpected behavior. See Jsfiddle for example.
The logic is fairly straight forward:
var c=document.getElementById("cvs1"),
ctx = c.getContext("2d"),
bufferCvs = document.createElement('canvas'),
bufferCtx = bufferCvs.getContext('2d');
bufferCvs.width = c.width;
bufferCvs.height = c.height;
ctx.translate( c.width/2, c.height/2 );
ctx.fillStyle="#FF0000";
ctx.fillRect( -75, -50 ,150,100);
//Image data experiment
//Set the buffer width / height same size as rectangle
bufferCvs.width = 150;
bufferCvs.height = 100;
//Draw the "image" from the first context to the buffer by clipping the first, and pasting to 0,0 width the same "image" dimensions.
bufferCtx.drawImage( c, -75, -50, 150, 100, 0, 0, 150, 100 );
//clear out old canvas drawing
ctx.save()
ctx.setTransform(1,0,0,1,0,0,1,0,0);
ctx.clearRect(0, 0, c.width, c.height);
ctx.restore();
ctx.drawImage( bufferCvs, -75, -50, 150, 100 );
Since I'm keeping the exact same coordinates / dimensions, the expected output would be what was originally on canvas to begin with. However, only part of the upper left corner is drawn (see fiddle). I'm using drawImage for efficiency reasons, but I've used get/putImageData with the same results. Both width and height are defined as mentioned to fix other strange behaviors.
How would you go about making sure everything stored in the buffer canvas is drawn, instead of just the top corner?
Edit: To help with my question and what behavior I believe is going on I'll post some screens.
Step 1: Translate context 1 to the center, and draw a rectangle to represent an image.
ctx.translate( c.width/2, c.height/2 );
ctx.fillStyle="#FF0000";
ctx.fillRect( -75, -50 ,150,100);
Step 2: Use drawImage to "clip" from the -75, -50 point and cut out just the rectangle using the width 150, 100. This should be drawn onto the canvas buffer, but it is not
bufferCvs.width = 150;
bufferCvs.height = 100;
//Draw the "image" from the first context to the buffer by clipping the first at -75, -50 (the start of the image), and pasting to 0,0 width the same "image" dimensions.
bufferCtx.drawImage( c, -75, -50, 150, 100, 0, 0, 150, 100 );
I would expect the buffer canvas to look like this (It is not):
However, if I change the drawImage to
bufferCtx.drawImage( c, 0, 0, 150, 100, 0, 0, 150, 100 );
I get an expected amount of white space on the buffer (and the last drawImage back to the context without issue)
Step 3: Clear out the old "image" from the first context. This shouldn't change the translation since I restore the context state after performing the clear. (This works as expected)
ctx.save()
ctx.setTransform(1,0,0,1,0,0,1,0,0);
ctx.clearRect(0, 0, c.width, c.height);
ctx.restore();
Step 4: Simply take what is in the buffer canvas and draw it onto the original context where it started to return to this:
The idea is to more "clip" a region of the original, clear the old image, and paste the new clipped region centered back into the original context. I have looked at MDN's example, but the clipping portion of drawImage isn't performing as I expect.
Upvotes: 3
Views: 611
Reputation: 25682
The main issue is that the first canvas drawn over the bufferCvs
is not drawn on the place where you expect. The easiest way to prove this is by adding bufferCvs
to the DOM tree: http://jsfiddle.net/CdWn6/4/
I guess this is what you're looking for: http://jsfiddle.net/CdWn6/6/
var c=document.getElementById("cvs1"),
c2 = document.getElementById("cvs2"),
bufferCvs = document.createElement('canvas'),
bufferCtx = bufferCvs.getContext('2d'),
ctx = c.getContext("2d"),
ctx2 = c2.getContext("2d");
bufferCvs.width = c.width;
bufferCvs.height = c.height;
ctx.translate( c.width/2, c.height/2 );
ctx.fillStyle="#FF0000";
ctx2.translate( c.width/2, c.height/2 );
ctx2.fillStyle="#FF0000";
bufferCtx.translate( c.width/2, c.height/2 );
ctx.fillRect( -75, -50 ,150,100);
ctx2.fillRect( -75, -50 ,150,100);
//Image data experiment
bufferCtx.drawImage( c, -135, -110, 270, 220);
ctx.save()
ctx.setTransform(1,0,0,1,0,0,1,0,0);
ctx.clearRect(0, 0, c.width, c.height);
ctx.restore();
//Draw background to demonstrate coordinates still work
ctx.fillStyle="#00FF00";
//ctx.fillRect( -75, -50 ,150,100);
ctx.drawImage( bufferCvs, -75, -50, 150, 100 );
Upvotes: 0