14

I have put text on an image in a <canvas> tag (the text was taken from an input box).

Now if I put a new text on the <canvas>, it is imposed on the previous text. How do I clear the existing text on the canvas before putting in the new text?

I have tried resetting the canvas by assigning canvas.width but the text stays on. Any help people?

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
redGREENblue
  • 3,076
  • 8
  • 39
  • 57

7 Answers7

10

If you know you're going to be adding and removing text a lot, it might make sense to keep track of the old text. Then you could just use this:

context.fillStyle = '#ffffff'; // or whatever color the background is.
context.fillText(oldText, xCoordinate, yCoordinate);
context.fillStyle = '#000000'; // or whatever color the text should be.
context.fillText(newText, xCoordinate, yCoordinate);

This way you don't have to redraw the whole canvas every time.

Skunkwaffle
  • 596
  • 4
  • 18
7

You use context.clearRect(), but first you have to figure out the rectangle to clear. This is based off a number of factors, such as the size of the text and the textAlign property of the canvas context when the text was originally drawn. The code below would be for the draw method of a object that draws text into a canvas context, as such it has properties for x, y, text size, horizontal alignment etc. Note that we always store the last piece of text drawn so we can clear an appropriately sized rectangle when the value is next changed.

this.draw = function() {
  var metrics = this.ctx.measureText(this.lastValue),
      rect = {
        x: 0,
        y: this.y - this.textSize / 2,
        width: metrics.width,
        height: this.textSize,
      };
  
  switch(this.hAlign) {
    case 'center':
      rect.x = this.x - metrics.width / 2;
      break;
    case 'left':
      rect.x = this.x;
      break; 
    case 'right':
      rect.x = this.x - metrics.width;
      break;
  }

  this.ctx.clearRect(rect.x, rect.y, rect.width, rect.height);

  this.ctx.font = this.weight + ' ' + this.textSize + ' ' + this.font;
  this.ctx.textAlign = this.hAlign;
  this.ctx.fillText(this.value, this.x, this.y);
  this.lastValue = this.value;
}
Eonasdan
  • 7,563
  • 8
  • 55
  • 82
charlie roberts
  • 1,659
  • 2
  • 13
  • 7
3

If you can't clear other drawings in the same area of the text, another solution is to have two canvas, one over the other:

<div style="position: relative;">
   <canvas id="static" width="1350" height="540" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
   <canvas id="dynamic" width="1350" height="540" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
</div>      

Then you can use the first for static drawings that don't need to be removed, and the other one with dynamic drawings. In your case you can put the text in the dynamic canvas and remove it with clearRect before drawing again.

context.clearRect(0, 0, canvas.width, canvas.height);   
MazarD
  • 2,759
  • 2
  • 22
  • 33
3

You need to use clearRect(x, y, w, h); More details at MDC

Divya Manian
  • 1,927
  • 11
  • 16
0

I'm not sure about how to clear the text off the image before you put the next piece of text.

If the background of the canvas is constant; and your only changing the text you could layer two canvas elements. The background, and a transparent top layer for text that can be removed and a new one inserted when you want to update the text.

NickSlash
  • 4,758
  • 3
  • 21
  • 38
  • Thank u I do believe this is the correct approach for removing some of the need for continuous clearing and re-drawing. More info here: https://stackoverflow.com/questions/3008635/html5-canvas-element-multiple-layers – Andrew Dec 08 '17 at 18:16
-1

not sure if it would work, but you could try redrawing the text in the background color

joshtronic
  • 381
  • 3
  • 9
-1

Here is the best approach and it worked for me. Clear function is just to clear the recaptcha. So just call this function when you refresh.

    <!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <link rel='stylesheet' type='text/css' media='screen' href='main.css'>
    <script src='main.js'></script>
</head>
<body>
<h4>Canvas</h4><canvas width="200" height="100" id="cnv1"></canvas><br/>
<button id="clear_cnv">Clear</button> - <button id="setnr_cnv">Set Nr</button>
<script type="text/javascript">
// <![CDATA[
// function to clear the canvas ( https://coursesweb.net/ )
// cnv = the object with the canvas element
function clearCanvas(cnv) {
  var ctx = cnv.getContext('2d');     // gets reference to canvas context
  ctx.beginPath();    // clear existing drawing paths
  ctx.save();         // store the current transformation matrix

  // Use the identity matrix while clearing the canvas
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.clearRect(0, 0, cnv.width, cnv.height);

  ctx.restore();        // restore the transform
}

// sets and adds a random number in canvas
// cnv = the object with the canvas element
function  addNrCnv(cnv) {
  // gets a random number between 1 and 100
  var nr =  Math.floor(Math.random() * 100 + 1);

  var ctx = cnv.getContext('2d');     // gets reference to canvas context

  // create text with the number in canvas (sets text color, font type and size)
  ctx.fillStyle = '#00f';
  ctx.font = 'italic 38px sans-serif';
  ctx.fillText(nr, 80, 64);
}

// get a reference to the <canvas> tag
var cnv1 = document.getElementById('cnv1');

// register onclick event for #clear_cnv button to call the clearCanvas()
document.getElementById('clear_cnv').onclick = function() { clearCanvas(cnv1); }

// register onclick event for #setnr_cnv button to call the addNrCnv()
document.getElementById('setnr_cnv').onclick = function() { addNrCnv(cnv1); }
// ]]>
</script>
</body>
</html>