Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erasing previously drawn lines on an HTML5 canvas

Tags:

To play around with HTML5 canvas, I decided to make an app which draws an analogue clockface. Everything's fine, except that old lines don't get erased in the way that I would expect. I've included part of the code below - DrawHands() gets called once a second:

var hoursPoint = new Object(); var minutesPoint = new Object(); var secondsPoint = new Object();  function drawHands() {     var now = new Date();      drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "white", 1);     var seconds = now.getSeconds();     secondsPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * seconds, 0.75 * radius);     drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "black", 1);      drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "white", 3);     var minutes = now.getMinutes();     minutesPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * minutes, 0.75 * radius);     drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "black", 3);      drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "white", 3);     var hours = now.getHours();     if (hours >= 12) { hours -= 12; } // Hours are 0-11     hoursPoint = getOtherEndOfLine(centerX, centerY, (2 * Math.PI / 12 * hours) + (2 * Math.PI / 12 / 60 * minutes), 0.6 * radius);     drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "black", 3); } 

To make sense of the above, there are two helper functions:

  • drawLine(x1, y1, x2, y2, color, thickness)
  • getOtherEndOfLine(x, y, angle, length)

The problem is that while all the hands get drawn as expected in black, they never get erased. I would expect that since the same line is drawn in white (the background colour) it would effectively erase what was previously drawn at that point. But this doesn't seem to be the case.

Anything I'm missing?

like image 495
Saqib Avatar asked Sep 09 '11 17:09

Saqib


People also ask

How do you erase lines in canvas?

To clear the HTML5 Canvas, we can use the clearRect() method to clear the canvas bitmap. This performs much better than other techniques for clearing the canvas, such as resetting the canvas width and height, or destroying the canvas element and then recreating it.

Is there an eraser tool in canvas?

Canva does not have an eraser tool. If you need to erase something, you will need to delete the element entirely and start over.

How do you erase a canvas drawing?

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.


2 Answers

Instead of erasing the things you don't want you can:

  1. save the state of the canvas
  2. draw the things you don't want
  3. restore the canvas to the saved state to 'erase' them

This can be accomplished pretty easily using ImageData:

var canvas = document.querySelector('canvas'),      context = canvas.getContext('2d');    context.fillStyle = 'blue';  context.fillRect(0,0,200,200);    // save the state of  the canvas here  var imageData = context.getImageData(0,0,canvas.width,canvas.height);    // draw a red rectangle that we'll get rid of in a second  context.fillStyle = 'red';  context.fillRect(50,50,100,100);    setTimeout(function () {      // return the canvas to the state right after we drew the blue rect      context.putImageData(imageData, 0, 0);  }, 1000);
<canvas width=200 height=200>
like image 141
mrmcgreg Avatar answered Sep 18 '22 14:09

mrmcgreg


For reasons that I could expand upon, you should consider clearing your canvas and redrawing it entirely unless there are performance or compositing reasons not to.

You want clearRect, something like this:

//clear the canvas so we can draw a fresh clock ctx.clearRect(0, 0, canvasWidth, canvasHeight);  //redraw your clock here /* ... */ 
like image 28
ellisbben Avatar answered Sep 17 '22 14:09

ellisbben