I'm creating a whiteboard application using ASP.NET/JavaScript. HTML5 canvas is my current tool for developing whiteboard features (drawing, text, image, shape ...). How can I save my scene so that I can load it later (and continue drawing)? I've seen a function for saving PNG image of the canvas, is it the only way of saving canvas data? or is there another way that enables me to save canvas data along their semantics, for instance can I save lines, shapes, texts and images drawing on the canvas? what are my options?
A canvas is a rasterised output of the instructions given to it, purely pixel data is stored. If you need to know the steps taken to get there you will need to log them in the javascript you are using to create it in the first place. Otherwise, if it was relatively simple, you could draw each element to stacked / offscreen canvases and export these separately. Obviously this could get expensive depending on the amount you need to do.
There are things like this that 'undo' canvas operations but essentially it's just storing an array of lines and redrawing them all from scratch every time. If you click undo it removes a line from the array, otherwise it adds one. To do what you desire you would need to store an array of operations to be drawn like this from a completely black canvas.
Related
There I am creating a stamp maker in HTML,Jquery and javascript. In the editor of my application image is adding to HTML canvas (simple) and also the text, I just create new line element and then append it to the canvas.But the problem is that I want my image to be in back of text. I googled it alot and also search stackoverflow I got the solution of creating multiple canvases but in last I have to download the canvas to file for user. There is the problem. And I want to export whole canvas along with text one and second image together.If I create seperate canvas for the text and another for image and give image one low zindex it would be fine but there will be one canvas to be exported as image.
Link to multiple layers in canvas html5 - canvas element - Multiple layers
I am hopping that we would come up with an idea of how to download both canvases as an image or find a method to take image to back of the canvas.
Any answer would be appreciated.
If you store the text, second image and first image in variables, you could just draw them on the canvas in the order you prefer. This means that, whenever there's some change in the image or text, you should clean the canvas and redraw everything.
Also, you may be interested in Compositing, since it allows you to decide where a new object is drawn in relation to the existing drawing (on top, behind, etc.)
Trying to make a simple animation engine for an HTML5 game. I have a timeline along the top composed of frame previews and a wireframe editor with a stickman for testing on a bigger, bottom canvas.
When I switch frames, I use drawImage() to copy the bottom canvas to a small frame preview along the top.
Is there a way to save the bottom canvas' current state in an array (each item corresponding to each frame) so that I can use drawImage() to place them as onion skins?
Here's the project if you want to see it visually:
https://jsfiddle.net/incon/owrj7e5z/
(If you look at the project, it doesn't really work yet, it's a big work in progress and is very glitchy)
This is what I was trying, and it works for previews, but won't redraw as onion skins on the bottom canvas.
var framePreviews = [undefined,undefined,undefined....];
var c = document.getElementById('bottomCanvas');
var tContext = document.getElementById('timelineCanvas').getContext('2d');
framePreviews[simulation.currentFrame] = c; // save canvas in an array
tContext.drawImage(framePreviews[simulation.currentFrame], simulation.currentFrame*60, 0, 60, 60/c.width*c.height); // draw the canvas 60px wide in the timeline
Don't.
An image is really heavy, whatever the mean of saving it you'll choose, there will always at least be once the ImageBitmap of your full sized canvas that will need to be stored in your browser's memory, and in a few frames, you'll blow it out.
You don't do any heavy calculations in your app, so you don't need to store these as images.
Instead only save the drawing commands, and redo the drawings every time.
Now, for the ones who do have to save computationally heavy frames, then the best is to generate an ImageBitmap from your canvas, but once again, this should be used only if drawing this one frame takes more than 16ms.
I am currently trying to build a relatively complex application using HTML5 Canvas objects and JS. To efficiently and realistically color areas I want to generate shadow maps based on image masks.
My problem is that the project is highly interactive, and I want to be as efficient as possible - so if anyhow possible I want to stay in one canvas. What I would now like to do is kinda "reset" the pixels taken into consideration for composite operations, so I can draw everything I want to draw onto my canvas, "reset" it (NOT clearing!), draw my mask and draw my shadow map (e. g. using source-in) on top of it.
Is this anyhow possible, or will I have to use a second canvas for this purpose?
Thanks!
Question:
Is canvas more suitable than svg in the following case?
Case:
I'm drawing a chart (using d3js library) similar to this one (but with much more data):
http://mbostock.github.com/d3/talk/20111116/iris-parallel.html
It's based on an svg and it works fine for several thousands of lines (up to 5000), adding more lines (svg path) decreases the performance dramatically (scrolling in the page becomes slow)
Keep in mind: That I need to add mouse events (which is handy in svg)
Generally svg is better suited for vector images, like in your example. However canvas has a lot of benefits in modern browsers such as hardware acceleration, so for drawing the lines, as long as zooming, panning ect. isn't required performance will be using canvas.
Mouse events can be a pain using canvas, since you have to manually keep track of everything, so with 5000+ points using canvas it wont be fun. The trade off however will be once the points are drawn, assuming you only draw them once the page will behave fine regardless of the number of lines, since they are all drawn to a raster image and aren't part of the DOM.
Honestly though the best way to find it is to test what you currently have using canvas.
When performance becomes a problem, switching to canvas might be an option. In this case you can draw the canvas once. Afterwards it's pretty much treated like an image. Drawing might take some time, but afterwards it can be scaled pretty quickly. Note that it is possible to draw a rendered SVG to a canvas using the context.drawImage method (example). So you could keep your SVG generation code to create an SVG in the background, and then draw it to the canvas.
But keep in mind that it won't scale as beautiful as an SVG as soon as it is on the canvas. When the user zooms in, it will get blurry or pixely, depending on how the browser scales graphics.
Click events on canvas can be handled in two ways. Either keep an array of click targets, and add an onclick event handler to the canvas. When a click occurs, iterate the array and check which one is closest to the click coordinates.
The other option is to use hit regions. These have to be defined as polygonal paths.
+1 to everything said above. I've seen some amazing performance increases when using canvas over SVG and over compositing images using the DOM.
About manipulating the canvas image with mouse events, I imagine the best approach for an image such as you are describing is to abstract it away using a library like the following:
http://paperjs.org
http://kineticjs.com
http://www.createjs.com/#!/EaselJS
Keep your code away from the canvas itself and let a library do the thinking for you.
I am new to canvas (HTML5) i have to design a paint application on canvas. There is a feature like dynamic addition of the selected image at canvas (on mouse-movements) and functionality to delete and drag that added image (Same for Text addition). Now my Question is how can we delete the images from the canvas (Note :There are no fixed no. of images added to the canvas.) Can you please suggest me the approach ??
An HTML5 Canvas is much like a real-world canvas. When you draw to the canvas the ink changes the canvas, blending with the other contents already there and forever changing them.
Ask Monet "How do you add a new person to your painting?" and he might say "you just paint them where you want them!" Similarly, you use drawImage() to 'paint' an image to your Canvas.
However, if you ask Monet "How do you remove a person from a painting?" and he would likely look at you funny and then respond "Quoi? You would have to either make a new painting, or else paint over top of the person!" Similarly, if you want to "remove" something from your canvas you either have to start over (clear the canvas and draw everything except that thing) or re-paint what was 'behind' your image on top of it.
Here is an example I made that shows one way that you can 'save' part of a canvas (by drawing it to another canvas) and then later drawing it back over something to 'erase' it.
However, I generally advise you not to use an HTML5 Canvas unless you know why you need it. You mention adding and removing items, and also detecting mouse movements. Using a retained-mode drawing system—like HTML or SVG—means that you actually add or remove or change items in an object representation, and it is up to someone else (the browser) to figure out how to best redraw them.
You may be best served by letting the "paint" portions of the user input be done on one or more canvases, and then compositing these canvases with other items (such as <div>s with text, or <img> for pictures, or vector-based SVG artwork).
You can make your own retained-mode system on type of canvas, or you can use someone else's library that does this. But instead I'd suggest that you consider whether this is the best and easiest way to accomplish your goals.