Clear Canvas Rect (but keep background)

Basics: HTML5 Canvas as a Non-Retained Drawing Mode Graphics API

First, let us discuss the manner in which the HTML5 Canvas works. Like a real-world canvas with fast-drying oil paints, when you stroke() or fill() or drawImage() onto your canvas the paint becomes part of the canvas. Although you drew a ‘circle’ and see it as such, the pixels of the circle completely replaced the background (or in the case of anti-aliasing at the edges of the circle, blended with and forever changed them). What would Monet say if you asked him to ‘move’ one of the people in a painting a little bit to the right? You can’t move the circle, you can’t erase the circle, you can’t detect a mouseover of the circle…because there is no circle, there is just a single 2D array of pixels.

Some Options

  1. If your background is fully static, set it as a background image to your canvas element via CSS. This will be displayed and overlaid with content you draw, but will not be cleared when you clear your canvas.

  2. If you cannot do the above, then you might as well just clear the entire canvas and re-paint it every frame. In my tests, the work needed to clear and redraw just a portion of the canvas is not worth the effort unless redrawing the canvas is very expensive.

    For example, see this test: http://phrogz.net/tmp/image_move_sprites_canvas.html
    In Safari v5.0.4 I see 59.4fps if I clear and re-draw the entire canvas once per frame, and 56.8fps if I use 20 clearRect() calls and 20 drawImage() calls to re-draw just the dirtied part of the background each frame. In this case it’s slower to be clever and keep track of small dirty regions.

  3. As another alternative, use a retained-drawing graphics system like SVG or HTML. With these, each element is maintained independently. You can change the position of the item and it will magically move; it is up to the browser to intelligently draw the update in the most efficient manner possible.

    You can do this while retaining the power of custom canvas drawing by creating and layering multiple canvases in the same HTML page (using CSS absolute positioning and z-index). As seen in this performance test, moving 20 sprites via CSS is significantly faster than trying to do it all yourself on a single canvas.

Flickering?

You wrote:

If I have to keep redrawing the background after clearRect the canvas will flicker when theres say 10 circles moving in that area.

That has never been my experience. Can you provide a small example showing this ‘flicker’ problem you claim will occur (please specify OS, browser, and version that you experience this on)? Here are two comments by prominent browser developers noting that neither Firefox nor Safari should ever show any flickering.

Leave a Comment