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:
- Given an image on the canvas, and translation to the center (I'm using a rectangle to demonstrate).
- Clip out a section of the image. I'm simply copying the entire "image" in the example.
- Possibly do manipulation.
- Paste back to the same canvas after clearing it. The point being to clip a section of the original image at a given point with a width / height, and paste it later with modifications.
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.