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
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.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 20clearRect()
calls and 20drawImage()
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.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.
How to clear the canvas for redrawing
Given that canvas
is a canvas element or an OffscreenCanvas
object, use clearRect
:
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
How to clear rectangle on Image in Canvas
Canvas doesn't work that way. It's a single layer, its also transparent by default. So with that in mind, you might be able to achieve what you want by simply giving the canvas element a CSS background. That way anything you draw on top of that background can easily be removed and the background will show through.
#backed-canvas{
background-image: url(http://www.placebear.com/300/200);
}
JSFiddle example: https://jsfiddle.net/yLf5erut/
How to erase on canvas without erasing background
There are a few ways you can go about this.
I'd recommend putting the image as the canvas's CSS "background-image". Then draw on the canvas as normal.
When you want to save the Canvas as an image, you will need to do a sequence of events:
- Create an in-memory canvas just as big as your normal canvas. Call it can2
ctx2.drawImage(can1, 0, 0)
// paint first canvas onto new canvasctx.clearRect(0, 0, width, height)
// clear first canvasctx.drawImage(background, 0, 0)
// draw image on first canvasctx.drawImage(can2, 0, 0)
// draw the (saved) first canvas back to itself
This will let you have the best of both worlds.
clearRect produces white box (not removes set colors)
You have one context: .getContext('2d')
returns the CanvasRenderingContext2D
for the canvas. It does not create new contexts. So, when you cx2.clearRect(0,0,300,300);
you're also clearing cx1
because, well, it's the same context.
If you want separate "layers" you need to create separate <canvas>
's and position them on top of each other.
JavaFX: how to clear a drawing without affecting background
You can't do this with one canvas.
Canvas only store the result of your painting operation.
This is the interest of the canvas you can stroke million times the same line and it will only store and represent the result and doesn't consume more memory.
So you if you need to draw Something over your chart you should put an other canvas over the chart and draw on the second canvas.
difference between clear and fill a rectangle with background color in canvas
If you don't clear it first, you'll be drawing on top of what was previously there. If you not using any transparencies, maybe this is OK.
Another difference is that clearRect() doesn't use a white background. it uses a transparent one.
Make canvas background have a transparent rect
You are right, but you can draw a shape with a hole to clip the canvas.
let ctx = c.getContext("2d");c.width = 300;c.height=300;ctx.fillStyle = "gold";
ctx.beginPath();ctx.moveTo(0,150);ctx.lineTo(0,300);ctx.lineTo(300,300);ctx.lineTo(300,0);ctx.lineTo(0,0);ctx.lineTo(0,150);ctx.lineTo(50,150);ctx.lineTo(50,50);ctx.lineTo(250,50);ctx.lineTo(250,250);ctx.lineTo(50,250);ctx.lineTo(50,150);ctx.closePath();
ctx.clip();
ctx.beginPath();ctx.fillRect(0,0,300,300);
div,canvas { width: 300px; height: 300px; position: absolute; border: 1px solid; top: 0; left: 0;}div { background: black;}
p { line-height: 300px; text-align: center; color:white;}
<div><p>The Div</p></div><canvas id="c"></canvas>
Related Topics
Special Character Not Displaying as Expected
How to Add HTML Code to Jsf Facesmessage
How to Change One Word Color of Placeholder
Background-Color of Body Tag Applied to The Whole HTML
Do You Need to Close Meta and Link Tags in HTML
Default Width/Height of an Iframe
CSS 100% Height with Absolute Positioning Top 0 Bottom 0
How to Use Z-Index with Relative Positioning
Webgl - Wait for Texture to Load
How to Prevent Browser from Caching Form Fields
How to Put Img Inline with Text
Does Svg Xmlns Attribute Value Requires Protocol? Can It Be Https or Relative
Google Maps Height 100% of Div Parent
Prevent Floated Divs from Wrapping to New Line
How to Put a Space Character Before Option Text in a HTML Select Element