Question Comment effacer la toile pour redessiner


Après avoir expérimenté des opérations composites et dessiné des images sur la toile, j'essaye maintenant de supprimer les images et le compositing. Comment puis-je faire cela?

J'ai besoin d'effacer la toile pour redessiner d'autres images; Cela peut durer un certain temps, donc je ne pense pas que dessiner un nouveau rectangle à chaque fois sera l'option la plus efficace.


787
2018-01-26 20:50


origine


Réponses:


const context = canvas.getContext('2d');

context.clearRect(0, 0, canvas.width, canvas.height);

971
2018-01-26 20:52



Utilisation: context.clearRect(0, 0, canvas.width, canvas.height);

C'est le moyen le plus rapide et le plus descriptif de vider toute la toile.

Ne pas utiliser: canvas.width = canvas.width;

Réinitialisation canvas.width réinitialise tout l'état du canevas (par exemple, les transformations, lineWidth, strokeStyle, etc.), il est très lent (comparé à clearRect), il ne fonctionne pas dans tous les navigateurs et ne décrit pas ce que vous essayez réellement de faire.

Traiter avec des coordonnées transformées

Si vous avez modifié la matrice de transformation (par exemple en utilisant scale, rotate, ou translate) puis context.clearRect(0,0,canvas.width,canvas.height) ne supprimera probablement pas toute la partie visible de la toile.

La solution? Réinitialiser la matrice de transformation avant d'effacer le canevas:

// Store the current transformation matrix
context.save();

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

// Restore the transform
context.restore();

Modifier: Je viens de faire un profilage et (dans Chrome) il est environ 10% plus rapide d'effacer une toile de 300x150 (taille par défaut) sans réinitialiser la transformation. Comme la taille de votre toile augmente cette différence diminue.

C'est déjà relativement insignifiant, mais dans la plupart des cas, vous tirerez beaucoup plus que ce que vous payez et je crois que cette différence de performance n'est pas pertinente.

100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear

661
2017-07-17 05:06



Si vous dessinez des lignes, assurez-vous de ne pas oublier:

context.beginPath();

Sinon, les lignes ne seront pas effacées.


189
2018-01-13 07:12



D'autres ont déjà fait un excellent travail répondant à la question, mais si un simple clear() La méthode sur l'objet de contexte vous serait utile (c'était à moi), c'est l'implémentation que j'utilise en fonction des réponses ici:

CanvasRenderingContext2D.prototype.clear = 
  CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
    if (preserveTransform) {
      this.save();
      this.setTransform(1, 0, 0, 1, 0, 0);
    }

    this.clearRect(0, 0, this.canvas.width, this.canvas.height);

    if (preserveTransform) {
      this.restore();
    }           
};

Usage:

window.onload = function () {
  var canvas = document.getElementById('canvasId');
  var context = canvas.getContext('2d');

  // do some drawing
  context.clear();

  // do some more drawing
  context.setTransform(-1, 0, 0, 1, 200, 200);
  // do some drawing with the new transform
  context.clear(true);
  // draw more, still using the preserved transform
};

107
2018-03-15 15:05



  • Chrome répond bien à: context.clearRect ( x , y , w , h ); comme suggéré par @ Pentium10 mais IE9 semble ignorer complètement cette instruction.
  • IE9 semble répondre à: canvas.width = canvas.width; mais il ne supprime pas les lignes, mais seulement les formes, les images et autres objets, à moins que vous n'utilisiez la solution de John Allsopp pour modifier la largeur en premier.

Donc, si vous avez une toile et un contexte créé comme ceci:

var canvas = document.getElementById('my-canvas');
var context = canvas.getContext('2d');

Vous pouvez utiliser une méthode comme celle-ci:

function clearCanvas(context, canvas) {
  context.clearRect(0, 0, canvas.width, canvas.height);
  var w = canvas.width;
  canvas.width = 1;
  canvas.width = w;
}

33
2017-11-03 09:48



Utilisez la méthode clearRect en transmettant les coordonnées x, y et la hauteur et la largeur du canevas. ClearRect effacera toute la toile comme:

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);

18
2017-11-13 06:08



il y a une tonne de bonnes réponses ici. Une autre remarque est que parfois il est amusant de ne nettoyer que partiellement la toile. c'est-à-dire "fondu" l'image précédente au lieu de l'effacer complètement. Cela peut donner de beaux effets sur les pistes.

c'est facile. en supposant que votre couleur de fond soit blanche:

// assuming background color = white and "eraseAlpha" is a value from 0 to 1.
myContext.fillStyle = "rgba(255, 255, 255, " + eraseAlpha + ")";
myContext.fillRect(0, 0, w, h);

13
2018-05-04 04:36



dans webkit vous devez définir la largeur à une valeur différente, puis vous pouvez le remettre à la valeur initiale


4
2017-08-02 04:50



J'ai trouvé que dans tous les navigateurs que j'ai testés, le moyen le plus rapide est de remplir en blanc avec n'importe quelle couleur. J'ai un très grand moniteur et en mode plein écran le clearRect est terriblement lent, mais le fillRect est raisonnable.

context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);

L'inconvénient est que la toile n'est plus transparente.


4
2018-03-25 22:29



function clear(context, color)
{
    var tmp = context.fillStyle;
    context.fillStyle = color;
    context.fillRect(0, 0, context.canvas.width, context.canvas.height);
    context.fillStyle = tmp;
}

4
2018-04-11 11:39



Cela a fonctionné pour mon pieChart dans chart.js

<div class="pie_nut" id="pieChartContainer">
    <canvas id="pieChart" height="5" width="6"></canvas> 
</div>

$('#pieChartContainer').html(''); //remove canvas from container
$('#pieChartContainer').html('<canvas id="pieChart" height="5" width="6"></canvas>'); //add it back to the container

4
2018-02-26 12:36