Effacement des lignes dessinées précédemment sur un canevas HTML5

Pour jouer avec la toile HTML5, j'ai décidé de créer une application qui dessine une horloge analogique. Tout va bien, sauf que les anciennes lignes ne sont pas effacées de la manière que je m'attends. J'ai inclus une partie du code ci-dessous: DrawHands () s'appelle une fois par seconde:

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); } 

Pour donner un sens à ce qui précède, il existe deux fonctions d'assistance:

  • DrawLine (x1, y1, x2, y2, couleur, épaisseur)
  • GetOtherEndOfLine (x, y, angle, longueur)

Le problème est que, si toutes les mains sont dessinées comme prévu en noir, elles ne sont jamais effacées. Je m'attends à ce que, puisque la même ligne est dessinée en blanc (la couleur de fond), elle effacerait effectivement ce qui était précédemment tiré à ce moment-là. Mais cela ne semble pas être le cas.

Quelque chose me manque-t-il?

Pour des raisons sur lesquelles je pourrais développer, vous devriez envisager de nettoyer votre canevas et de le redessiner entièrement à moins qu'il n'y ait des raisons de performance ou de composition.

Vous désirez ClearRect , quelque chose comme ceci:

 //clear the canvas so we can draw a fresh clock ctx.clearRect(0, 0, canvasWidth, canvasHeight); //redraw your clock here /* ... */ 

Au lieu d'effacer les choses que vous ne voulez pas, vous pouvez enregistrer l'état de la toile à l'époque avant de dessiner les choses que vous ne voulez pas et de restaurer la toile à cet état pour les effacer.

Cela peut être accompli assez facilement en utilisant ImageData :

 var canvas = document.querySelector('canvas'), context = canvas.getContext('2d'); context.fillStyle = 'blue'; context.fillRect(0,0,10,10); // 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.strokeStyle = 'red'; context.strokeRect(70,70,20,20); setTimeout(function () { // return the canvas to the state right after we drew the blue rect context.putImageData(imageData, 0, 0); }, 1000); 
 <canvas width=100 height=100> 

La raison pour laquelle vous ne pouvez pas simplement redessiner la ligne en blanc et espérer qu'elle efface l'ancienne ligne est parce qu'il pourrait y avoir un anti-aliasing / saignement. Vous remarquerez également qu'une ligne horizontale droite dessinée sur un pixel par rapport à un demi-pixel semble très différente à cause de cela.

Lorsque vous faites vos lignes blanches "effacer", essayez de les dessiner avec une plus grande lineWidth d'environ 3 ou 4. Cela devrait fonctionner pour votre cas.

Vous devez également dessiner toutes les lignes blanches, puis toutes les lignes noires, au cas où elles se croisent.

Un moyen rapide et facile d'effacer une toile est de définir la largeur:

 context.canvas.width = context.canvas.width;