Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Canvas redraw itself every time anything changes?

Tags:

html

canvas

I have done some research on how canvas works. It is supposed to be "immediate mode" means that it does not remember what its drawing looks like, only the bitmap remains everytime anything changes.

This seems to suggest that canvas does not redraw itself on change.
However, when I tested canvas on iPad (basically I keep drawing parallel lines on the canvas), the frame rate degrades rapidly when there are more lines on the canvas. Lines are drawn more slowly and in a more jumpy way.

Does this mean canvas actually have to draw the whole thing on change? Or there is other reason for this change in performance?

like image 924
Codier Avatar asked Nov 17 '11 15:11

Codier


People also ask

How do you clear canvas and redraw?

To clear the Canvas, you can use the clearRect() method. This method performs pretty well than others for clearing the canvas (such as resetting the width/height, destroying the canvas element and then recreating it, etc..) const context = canvas. getContext('2d'); context.

How do I reset my canvas?

From the course navigation menu, select Settings. In the "Settings" sidebar at the right, select Delete All Course Content. You will be prompted to confirm. To proceed, click Reset Course Content, or click Cancel to cancel.

How do you erase a picture on canvas?

You can easily clear you canvas by resetting its width and height. For example: canvas. width = canvas. width should clear your drawing context.

How do you change the height and width of a canvas?

The width attribute specifies the width of the <canvas> element, in pixels. Tip: Use the height attribute to specify the height of the <canvas> element, in pixels. Tip: Each time the height or width of a canvas is re-set, the canvas content will be cleared (see example at bottom of page).


1 Answers

The HTML canvas remembers the final state of pixels after each stroke/fill call is made. It never redraws itself. (The web browser may need to re-blit portions of the final image to the screen, for example if another HTML object is moved over the canvas and then away again, but this is not the same as re-issuing the drawing commands.

The context always remembers its current state, including any path that you have been accumulating. It is probable that you are (accidentally) not clearing your path between 'refreshes', and so on the first frame you are drawing one line, on the second frame two lines, on the third frame three lines, and so forth. (Are you calling ctx.closePath() and ctx.beginPath()? Are you clearing the canvas between drawings?)

Here's an example showing that the canvas does not redraw itself. Even at tens of thousands of lines I see the same frame rate as with hundreds of lines (capped at 200fps on Chrome, ~240fps on Firefox 8.0, when drawing 10 lines per frame).

var lastFrame = new Date, avgFrameMS=5, lines=0;
function drawLine(){
  ctx.beginPath();
  ctx.moveTo(Math.random()*w,Math.random()*h);
  ctx.lineTo(Math.random()*w,Math.random()*h);
  ctx.closePath();
  ctx.stroke();
  var now = new Date;
  var frameTime = now - lastFrame;
  avgFrameMS += (frameTime-avgFrameMS)/20;
  lastFrame = now;
  setTimeout(drawLine,1);
  lines++;
}
drawLine();

// Show the stats infrequently
setInterval(function(){
  fps.innerHTML = (1000/avgFrameMS).toFixed(1);
  l.innerHTML = lines;
},1000);

Seen in action: http://phrogz.net/tmp/canvas_refresh_rate.html

For more feedback on what your code is actually doing versus what you suspect it is doing, share your test case with us.

like image 145
Phrogz Avatar answered Nov 13 '22 04:11

Phrogz