Frage So löschen Sie den Canvas für das Neuzeichnen


Nach dem Experimentieren mit Composite-Operationen und dem Zeichnen von Bildern auf der Leinwand versuche ich nun, Bilder und Compositing zu entfernen. Wie mache ich das?

Ich muss die Leinwand leeren, um andere Bilder neu zu zeichnen; Das kann eine Weile dauern, deshalb denke ich nicht, dass das Zeichnen eines neuen Rechtecks ​​jedes Mal die effizienteste Option sein wird.


787
2018-01-26 20:50


Ursprung


Antworten:


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

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

971
2018-01-26 20:52



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

Dies ist die schnellste und anschaulichste Methode zum Löschen der gesamten Arbeitsfläche.

Verwende nicht: canvas.width = canvas.width;

Zurücksetzen canvas.width setzt alle Canvas-Zustände zurück (z. B. Transformationen, lineWidth, strokeStyle usw.), ist sehr langsam (im Vergleich zu clearRect), funktioniert nicht in allen Browsern und beschreibt nicht, was Sie tatsächlich tun.

Umgang mit transformierten Koordinaten

Wenn Sie die Transformationsmatrix geändert haben (z. B. mit scale, rotate, oder translate) dann context.clearRect(0,0,canvas.width,canvas.height) wird wahrscheinlich nicht den gesamten sichtbaren Teil des Canvas löschen.

Die Lösung? Setzen Sie die Transformationsmatrix vor dem Löschen der Arbeitsfläche zurück:

// 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();

Bearbeiten: Ich habe gerade ein Profiling durchgeführt und (in Chrome) ist es etwa 10% schneller, eine Leinwand im Format 300x150 (Standardgröße) zu löschen, ohne die Transformation zurückzusetzen. Wenn die Größe Ihrer Leinwand zunimmt, sinkt dieser Unterschied.

Das ist schon relativ unbedeutend, aber in den meisten Fällen werden Sie wesentlich mehr ziehen, als Sie löschen, und ich glaube, dass dieser Leistungsunterschied irrelevant ist.

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

661
2017-07-17 05:06



Wenn Sie Linien zeichnen, stellen Sie sicher, dass Sie nicht vergessen:

context.beginPath();

Andernfalls werden die Zeilen nicht gelöscht.


189
2018-01-13 07:12



Andere haben bereits eine ausgezeichnete Arbeit geleistet, um die Frage zu beantworten, aber wenn eine einfache clear() Methode für das Context-Objekt wäre nützlich für Sie (es war für mich), das ist die Implementierung, die ich hier basierend auf Antworten verwende:

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

Verwendung:

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 reagiert gut auf: context.clearRect ( x , y , w , h ); wie von @ Pentium10 vorgeschlagen, aber IE9 scheint diesen Befehl vollständig zu ignorieren.
  • IE9 scheint zu antworten: canvas.width = canvas.width; Es werden jedoch keine Linien, nur Formen, Bilder und andere Objekte gelöscht, es sei denn, Sie verwenden auch die Lösung von John Allsopp, die zuerst die Breite ändert.

Wenn Sie also eine Leinwand und einen Kontext wie folgt erstellen:

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

Sie können eine Methode wie folgt verwenden:

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



Verwenden Sie die clearRect-Methode, indem Sie x, y-Koordinaten sowie Höhe und Breite der Zeichenfläche übergeben. ClearRect löscht die gesamte Arbeitsfläche als:

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

18
2017-11-13 06:08



Es gibt eine Tonne guter Antworten hier. Ein weiterer Hinweis ist, dass es manchmal Spaß macht, die Leinwand nur teilweise zu entfernen. Das heißt, das vorherige Bild wird ausgeblendet, anstatt es vollständig zu löschen. Dies kann schöne Spuren Effekte geben.

es ist einfach. Angenommen, Ihre Hintergrundfarbe ist weiß:

// 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



In Webkit müssen Sie die Breite auf einen anderen Wert einstellen, dann können Sie sie auf den Anfangswert zurücksetzen


4
2017-08-02 04:50



Ich habe festgestellt, dass in allen Browsern, die ich teste, der schnellste Weg ist, tatsächlich mit Weiß zu füllen, oder mit welcher Farbe auch immer Sie möchten. Ich habe einen sehr großen Monitor und im Vollbildmodus ist das clearRect quälend langsam, aber das fillRect ist vernünftig.

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

Der Nachteil ist, dass die Leinwand nicht mehr transparent ist.


4
2018-03-25 22:29