wake-up-neo.com

So löschen Sie die Zeichenfläche für das erneute Zeichnen

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

Ich muss die Leinwand löschen, um andere Bilder neu zu zeichnen. Dies kann eine Weile dauern, daher denke ich nicht, dass das Zeichnen eines neuen Rechtecks ​​jedes Mal die effizienteste Option ist.

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

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

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

Dies ist die schnellste und aussagekräftigste Methode, um die gesamte Leinwand zu löschen.

Verwenden Sie nicht: canvas.width = canvas.width;

Das Zurücksetzen von canvas.width setzt alle Zeichenbereichszustände zurück (z. B. Transformationen, Linienbreite, Strichstil usw.), ist sehr langsam (im Vergleich zu clearRect), funktioniert nicht in allen Browsern und beschreibt nicht, was Sie sind eigentlich versuchen zu tun.

Umgang mit transformierten Koordinaten

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

Die Lösung? Setzen Sie die Transformationsmatrix vor dem Löschen des Erstellungsbereichs 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();

Edit: Ich habe gerade ein Profil erstellt und (in Chrome) ist es ungefähr 10% schneller, eine Leinwand mit 300 x 150 (Standardgröße) zu löschen, ohne die Transformation zurückzusetzen. Mit zunehmender Größe Ihrer Leinwand sinkt dieser Unterschied.

Das ist schon relativ unbedeutend, aber in den meisten Fällen werden Sie erheblich mehr zeichnen als Sie klären, und ich glaube, dass dieser Leistungsunterschied irrelevant ist.

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

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

context.beginPath();

Andernfalls werden die Zeilen nicht gelöscht.

212
trembl

Andere haben die Frage bereits hervorragend beantwortet, aber wenn eine einfache Methode clear() für das Kontextobjekt für Sie nützlich wäre (für mich), ist dies die Implementierung, die ich basierend auf den Antworten hier 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();
    }           
};

Verwendungszweck:

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
};
115
JonathanK
  • Chrome reagiert gut auf: context.clearRect ( x , y , w , h ); wie von @ Pentium10 vorgeschlagen, aber IE9 scheint diese Anweisung vollständig zu ignorieren.
  • IE9 scheint zu reagieren auf: canvas.width = canvas.width;, löscht jedoch keine Linien, nur Formen, Bilder und andere Objekte, es sei denn, Sie verwenden auch die @ John Allsopp-Lösung, bei der Sie zuerst die Breite ändern.

Wenn Sie also eine Arbeitsfläche und einen Kontext haben, die wie folgt erstellt wurden:

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

Sie können eine Methode wie diese verwenden:

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

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

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

Dies ist 2018 und es gibt noch keine native Methode, um die Zeichenfläche für das Neuzeichnen vollständig zu löschen. clearRect()nicht löscht die Leinwand vollständig. Zeichnungen ohne Füllung werden nicht gelöscht (z. B. rect())

1.Um vollständig die Leinwand zu löschen, unabhängig davon, wie Sie zeichnen:

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

Vorteile: Erhält strokeStyle, fillStyle usw .; Keine Verzögerung;

Nachteile: Unnötig, wenn Sie beginPath bereits verwenden, bevor Sie etwas zeichnen

2. Mit der Breite/Höhe Hack:

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

OR

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

Vorteile: Funktioniert mit IE Nachteile: Setzt strokeStyle und fillStyle auf schwarz zurück. Laggy;

Ich habe mich gefragt, warum es keine native Lösung gibt. Tatsächlich wird clearRect() als einzeilige Lösung angesehen, da die meisten Benutzer beginPath() ausführen, bevor sie einen neuen Pfad zeichnen. BeginPath darf jedoch nur zum Zeichnen von Linien und nicht zum Schließen von Pfaden wie rect(). verwendet werden.

Dies ist der Grund, warum die akzeptierte Antwort mein Problem nicht löste und ich Stunden damit verschwendete, verschiedene Hacks auszuprobieren. Verfluche dich Mozilla

18
sziraqui

hier gibt es eine Menge guter Antworten. Eine weitere Anmerkung ist, dass es manchmal Spaß macht, die Leinwand nur teilweise zu löschen. Das heißt, das vorherige Bild wird "ausgeblendet", anstatt es vollständig zu löschen. Dies kann zu schönen Spureneffekten führen.

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);
14
orion elenzil

Ein schneller Weg ist zu tun

canvas.width = canvas.width

Idk wie es funktioniert, aber es funktioniert!

8
Jacob Morris

Ich habe festgestellt, dass in allen Browsern, die ich teste, der schnellste Weg darin besteht, Rect mit Weiß oder einer beliebigen Farbe zu füllen. Ich habe einen sehr großen Monitor und im Vollbildmodus ist der clearRect quälend langsam, aber der 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
John Page

Dies funktionierte für mein pieChart in 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
Sanal S

Dies ist, was ich unabhängig von Grenzen und Matrixtransformationen benutze:

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

Grundsätzlich wird der aktuelle Status des Kontexts gespeichert und ein transparentes Pixel mit copy als globalCompositeOperation gezeichnet. Stellt dann den vorherigen Kontextstatus wieder her.

4
superruzafa
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
Imagine Breaker

im Webkit müssen Sie die Breite auf einen anderen Wert einstellen. Anschließend können Sie sie auf den ursprünglichen Wert zurücksetzen

4
John Allsopp

Ein einfacher, aber nicht sehr lesbarer Weg ist, dies zu schreiben:

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

// after doing some rendering

canvas.width = canvas.width;  // clear the whole canvas
2
Chang

Ich benutze immer

cxt.fillStyle = "rgb(255, 255, 255)";
cxt.fillRect(0, 0, canvas.width, canvas.height);
1
GameMaster1928
Context.clearRect(starting width, starting height, ending width, ending height);

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

0
Gavin T

schnellste Weg:

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
0
elser
context.clearRect(0,0,w,h)   

füllen Sie das angegebene Rechteck mit RGBA-Werten:
0 0 0 0: mit Chrome
0 0 0 255: mit FF & Safari

Aber

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

lass das Rechteck mit
0 0 0 255
egal im Browser!

Wenn Sie nur clearRect verwenden und es in einem Formular zur Übermittlung Ihrer Zeichnung haben, erhalten Sie stattdessen eine Übermittlung der Löschung, oder es kann zuerst gelöscht und dann eine leere Zeichnung hochgeladen werden, sodass Sie eine hinzufügen müssen preventDefault am Anfang der Funktion:

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

Hoffe es hilft jemandem.

0
JoelBonetR