Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save <canvas> contents to be redrawn in later animation frames?

I am drawing a graph on a <canvas> that requires expensive calculations. I would like to create an animation (when moving the mouse across the canvas) where the graph is unchanging, but some other objects are drawn over it.

Because the canvas will have to be redrawn a lot, I don't want to perform the calculations to render the graph for every frame. How can I draw the graph once, save it, and then use the saved rendering to redraw subsequent frames of the animation, so that the expensive calculations only have to happen once & all I have to redraw is the much simpler animation layer?

I tried drawing the graph on a second canvas & then using ctx.drawImage() to render it onto the main canvas, but drawing on the canvas doesn't seem to work unless it's in the dom & not display:none;. Do I have to do something hacky like position the temp canvas out of view, or is there a cleaner way to do this?

like image 666
Bryan Avatar asked Jul 01 '09 04:07

Bryan


3 Answers

You need to use at least 2 canvases : one with the complex drawing, and the second, on top of the first (with the same size, positioned in absolute), with the animated shapes. This method will work on IE, and getImageData doesn't work with ExCanvas.

Every library which does complex drawings on canvases use this method (Flot and others).

<div style="width: 600px; height: 300px; position: relative;" id="container">
  <canvas class="canvas" style="position: absolute; left: 0px; top: 0px;" width="600" height="300"/>
  <canvas class="overlay" style="position: absolute; left: 0px; top: 0px;" width="600" height="300"/>
</div>
like image 96
Fabien Ménager Avatar answered Sep 21 '22 11:09

Fabien Ménager


How about drawing your graph the first time on your canvas and then

var imdata = ctx.getImageData(0,0,width,height);

and then

ctx.putImageData( imdata, 0,0);

for the rest of the rendering.

like image 20
Clint Avatar answered Sep 18 '22 11:09

Clint


I had to make a few changes to the flot.js charting library. I'm 99% sure that it uses overlapping canvases. There's a chart layer and an overlay layer. You could look at the source code.

like image 38
Nosredna Avatar answered Sep 22 '22 11:09

Nosredna