Canvas: returning to state before drawing - javascript

Is it possible to go back after I use drawImage?
Example:
I draw an image and them overdraw another. I want to delete the first image and, on the clear surface, draw a new image.
Is it possible?

if you want to undo drawImage changes, you must save canvas data before doing drawImage like:
tmp = canvas.getContext("2d").getImageData(0, 0, with, height);
//do changes here
canvas.getContext("2d").putImageData(tmp , 0, 0);
//here changes will be lost
this is unswer to the title, question content was not clear for me

Related

GetImageData and multiple images

How to use getImageData() in js, when the images are drawn into the canvas on top of one another? (I need the data of each image separately.)
Here's one way:
// get the imageData for the second image
context.drawImage(secondImage,0,0);
var imageData2=context.getImageData(0,0,canvas.width,canvas.height);
context.clearRect(0,0,canvas.width,canvas.height);
// get the imageData for the first image
context.drawImage(firstImage,0,0);
var imageData1=context.getImageData(0,0,canvas.width,canvas.height);
// and now redraw the second image back on the canvas
context.drawImage(secondImage,0,0);
Or simply create a canvas object for each image. They will visually layer correctly but you can work with image independently. If you don't mess with the z-index they will render in the order you add the canvas objects.

Visualizing html5 canvas

This may be off topic but I'm not sure where else to go with this question. I'm just getting started with HTML5 canvas element and all of the incredibly powerful things it can do. I was hoping someone could offer some advise. When working with custom paths and bezier curves, what is the easiest/best way to visualize where the points belong on the canvas to achieve a desired effect. Right now it feels like I'm just guessing plotting points in any place hoping to end up with the right angle/shape that I want.
To be more specific I want to create a shape that will act as an image mask, and will later need to animate this shape. Much like this fiddle http://jsfiddle.net/jimrhoskins/dDUC3/1/ (someone else's work) but since I can't see where the picture is on the canvas or where any of the points are, I'm really just guessing at the approximate shape I need to make. I'm just wondering if there's a better way, or some function in javascript that can map the location of an image and give me at least a better place to start.
Here is what I know/have tried already
// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
// Create an image element
var img = document.createElement('IMG');
// When the image is loaded, draw it
img.onload = function () {
// Save the state, so we can undo the clipping
context.save();
// Create a shape, of some sort
context.beginPath();
context.moveTo(somex, somey);
context.bezierCurveTo(somexstart, someystart, somexcontrol, someycontro, somexend, someyend);
context.arcTo(somecoordinates);
context.closePath();
// Clip to the current path
context.clip();
context.drawImage(img, 0, 0);
// Undo the clipping
context.restore();
}
// Specify the src to load the image
img.src = "url";
How about opening the image in an SVG editor. Drawing a path on a layer above the image. Then open the SVG and copy the coordinates?
Try an SVG Editor. You can get the points there. You can add images too. SVG animation is used nowadays as well. If you have Adobe Illustrator, it will be easier to draw there and just save it as SVG.

Drawing a Canvas into a smaller Canvas not working

For a Project I want to take the content of a canvas (Called SAVE_CV) and display it in another, smaller canvas.
Some things that I am aware of so far that could be causing me problems: resizing a canvas clears its content, the JS-size of a canvas is different from the CSS-size.
I want the smaller canvas to be 500px wide and appropriately high.
function restoreTaggingCV() {
var cv = document.getElementById( 'taggingCV' );
var ctx = cv.getContext( "2d" );
var styleHeight = SAVE_CV.height * 500 / SAVE_CV.width;
ctx.drawImage(SAVE_CV, 0, 0, cv.width, cv.height);
}
This is my Code so far. Whenever I try to resize the smaller canvas appropriately it only gives me a blank canvas with nothing in it. I tried to set the size with "cv.height = X" and "cv.style.height = styleHeight + 'px'" but neither worked. Also I would love to set the width of the canvas using CSS.
Appreciate any help.
EDIT
I want the image in a picture because later I want the user to mark areas in the smaller version which I then want to use to create individual imaged from the big version. I want to visualise thise area to the user. I probably could do all this by using an image and putting divs over it or something but I just fell more comfident using a canvas since I am pritty new to HTML and CSS.
Try using the CanvasRenderingContext2d.prototype.scale method. It sets the scale factor of the canvas and renders anything in the current state with it's dimensions multiplied by the factor.
So before you use the drawImage function, you scale the context appropriately (in this case, down). For example:
context.save();
context.scale(0.5, 0.5);
context.drawImage(canvas, 0, 0);
context.restore();
This would render the canvas on the context at 0.5 times it's current size. See in this fiddle how I used it to mirror a larger canvas onto a smaller, separate one.
Canvas objects don't like to be resised. After drawing Your image simply convert it toDataURL() and set as image source. They You may resize image as you want.
$img.attr('src',canvas.toDataURL());

erase part moving image

Is there a way to clear the canvas (html5)of only 1 element only ? I have a moving image on a canvas and when I erase the image the background color goes as well. Is there a way to just remove the image and not the whole background. My background is just a simple color but in the future it will be more complicated.
This is also tricky because there is no way to get image x,y pos from a property.
ClassLoadImages.prototype.m_move = function(){
this.x=++img1_x;
this.y=++img1_y;
//img1_x++;
//img1_y++;
// alert(img.x);
ctx.drawImage(img.imgElement, this.x, this.y);
// ctx.fillText("finished loading " ,10,40);
};
function doGameLoop() {
ctx.clearRect(0,0,600,400);
img.m_move();
if (img.x>30)
{
clearInterval(gameLoop);
}
}
var img= new ClassLoadImages('images/image4.jpg');
gameLoop = setInterval(doGameLoop, 100);
</script>
Simple answer is no. A canvas is a flat bitmap, not a layered collection of objects. Once you draw to it you lose the background behind the thing you draw.
You could try to implement the functionality yourself by recording the steps you used to create the canvas in the first place, and re-creating it with or without the relevant image.

Rubber Banding in HTML5

I wish to draw a rectangle on my canvas but stretching the start point. but how do i erase the previous rectangles drawn during the process. I mean if my background color is red and i want to draw a black rectangle over it. while erasing the intermediate rectangles drawn during rubber banding, i wish to retain the background.
The question is a little hard to understand, but I'm assuming what you want to do is the following using getImageData and putImageData:
// save the entire canvas (in this example, its 500 x 500) to be restored later
image = context.getImageData(0, 0, 500, 500);
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height); // clear entire canvas
context.putImageData(image, 0, 0); // restore entire canvas saved previously
/** Now, draw other stuff on top of the canvas **/
}
You need to redraw the portion of the background the black rectangle previously occupied. It may be simpler to just redraw the entire background.
You simply have to keep track of every single object you want to draw and redraw every single one of them each frame.
You can optimize the process a bit, but you must keep track of each thing drawn so you can redraw.

Categories