Comment effacer la toile pour redessiner

Après avoir expérimenté des opérations composites et dessiné des images sur le canevas, j'essaie maintenant de supprimer des images et de les composer. Comment dois-je faire?

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

808
demandé sur Sohaib Mohammed 2010-01-26 23:50:42

20 réponses

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

context.clearRect(0, 0, canvas.width, canvas.height);
1004
répondu Pentium10 2018-04-13 11:22:28

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

C'est le moyen le plus rapide et le plus descriptif d'effacer toute la toile.

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

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

Traiter les coordonnées transformées

Si vous avez modifié la matrice de transformation (par exemple en utilisant scale, rotate, ou translate) alors context.clearRect(0,0,canvas.width,canvas.height) n'effacera 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 un canevas 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 les cas que vous dessinerez beaucoup plus que vous ne le faites 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
669
répondu Prestaul 2015-03-30 19:19:00

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

context.beginPath();

Sinon les lignes ne seront pas effacées.

194
répondu trembl 2011-01-13 07:12:09

D'autres ont déjà fait un excellent travail en répondant à la question mais si une simple méthode clear() sur l'objet context vous serait utile (c'était pour moi), c'est l'implémentation que j'utilise basée sur les 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();
    }           
};

Utilisation:

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
};
109
répondu JonathanK 2013-03-29 05:17:35
  • Chrome répond bien à: {[2] } 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, seulement les formes, les images et autres objets, sauf si vous utilisez également la solution de @John Allsopp de changer d'abord la largeur.

Donc, si vous avez un canevas et un contexte créés comme ceci:

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

, Vous pouvez utiliser une méthode comme ceci:

function clearCanvas(context, canvas) {
  context.clearRect(0, 0, canvas.width, canvas.height);
  var w = canvas.width;
  canvas.width = 1;
  canvas.width = w;
}
33
répondu grenade 2010-11-03 10:02:07

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

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
19
répondu Vishwas 2014-01-10 04:54:14

Il y a une tonne de bonnes réponses ici. une autre note est que parfois il est amusant de ne nettoyer que partiellement la toile. c'est-à-dire" effacer " l'image précédente au lieu de l'effacer complètement. cela peut donner de beaux effets de sentiers.

C'est facile. supposons que votre couleur d'arrière-plan 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
répondu orion elenzil 2012-05-04 04:36:42

C'est 2018 et il n'y a toujours pas de méthode native pour effacer complètement le canevas pour le redessiner. clearRect() n'efface pas complètement le canevas. Les dessins de type Non-remplissage ne sont pas effacés (par exemple. rect())

1.De complètement clair toile indépendamment de la façon dont vous dessinez:

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

Avantages: préserve strokeStyle, fillStyle etc.; Pas de décalage;

Inconvénients: inutile si vous utilisez déjà beginPath avant de dessiner quoi que ce soit

2.Utilisation de la largeur / hauteur hack:

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

Ou

context.canvas.height = context.canvas.height;

Avantages: fonctionne avec IE Inconvénients: réinitialise strokeStyle, fillStyle en noir; Laggy;

Je me demandais pourquoi une solution native n'existe pas. En fait, clearRect() est considéré comme la solution à ligne unique car la plupart des utilisateurs font beginPath() avant de dessiner un nouveau chemin. Bien que beginPath ne soit utilisé que lors du dessin de lignes et pas de chemin fermé comme rect().

C'est la raison pour laquelle la réponse acceptée n'a pas résolu mon problème et j'ai fini par perdre des heures essayer différents hacks. Maudire mozilla

6
répondu sziraqui 2018-06-29 06:24:00

Dans webkit, vous devez définir la largeur d'une valeur différente, alors vous pouvez revenir à la valeur initiale

4
répondu John Allsopp 2010-08-02 04:50:02

J'ai trouvé que dans tous les navigateurs que je teste, le moyen le plus rapide est de remplir réellement avec du blanc, ou quelle que soit la couleur que vous souhaitez. 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
répondu John Page 2013-03-25 22:29:13
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
répondu Imagine Breaker 2014-04-11 11:39:15

Cela a fonctionné pour mon pieChart dans le graphique.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
répondu Sanal S 2016-02-26 12:36:33

Un moyen rapide est de faire

canvas.width = canvas.width

Idk comment ça marche mais ça marche!

4
répondu Jacob Morris 2018-05-08 16:56:54

Moyen le plus rapide:

canvas = document.getElementById("canvas");
c = canvas.getContext("2d");

//... some drawing here

i = c.createImageData(canvas.width, canvas.height);
c.putImageData(i, 0, 0); // clear context by putting empty image data
2
répondu elser 2012-08-13 18:32:05

C'est ce que j'utilise, indépendamment des limites et des transformations matricielles:

function clearCanvas(canvas) {
  const ctx = canvas.getContext('2d');
  ctx.save();
  ctx.globalCompositeOperation = 'copy';
  ctx.strokeStyle = 'transparent';
  ctx.beginPath();
  ctx.lineTo(0, 0);
  ctx.stroke();
  ctx.restore();
}

Fondamentalement, il enregistre l'état actuel du contexte, et dessine un pixel transparent avec copy comme globalCompositeOperation. Ensuite, restaure l'état de contexte précédent.

2
répondu superruzafa 2018-05-28 15:34:46

Un simple, mais pas très lisible est d'écrire ceci:

var canvas = document.getElementId('canvas');

// after doing some rendering

canvas.width = canvas.width;  // clear the whole canvas
1
répondu Chang 2017-08-24 21:34:50
context.clearRect(0,0,w,h)   

Remplissez le rectangle donné avec des valeurs RGBA:
0 0 0 0 : avec Chrome
0 0 0 255: avec FF & Safari

Mais

context.clearRect(0,0,w,h);    
context.fillStyle = 'rgba(0,0,0,1)';  
context.fillRect(0,0,w,h);  

Laissez le rectangle rempli de
0 0 0 255
peu importe le navigateur !

0
répondu Philippe Oceangermanique 2016-12-12 09:53:44

Si vous utilisez clearRect seulement, si vous l'avez dans un formulaire pour soumettre votre dessin, vous obtiendrez un submit à la place de la compensation, ou peut-être qu'il peut être effacé d'abord, puis télécharger un dessin vide, donc vous devrez ajouter un preventDefault au début de la fonction:

   function clearCanvas(canvas,ctx) {
        event.preventDefault();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }


<input type="button" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">

J'espère que ça aide quelqu'un.

0
répondu JoelBonetR 2017-01-10 18:14:56
Context.clearRect(starting width, starting height, ending width, ending height);

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

0
répondu Gavin T 2017-09-30 16:00:04

Ce sont tous d'excellents exemples de la façon dont vous effacez un canevas standard, mais si vous utilisez paperjs, cela fonctionnera:

Définir une variable globale en JavaScript:

var clearCanvas = false;

À partir de votre PaperScript, définissez:

function onFrame(event){
    if(clearCanvas && project.activeLayer.hasChildren()){
        project.activeLayer.removeChildren();
        clearCanvas = false;
    }
}

Maintenant, partout où vous définissez clearCanvas sur true, il effacera tous les éléments de l'écran.

-1
répondu Robert Ogle 2012-07-21 03:03:19