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.
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.clearRect(0, 0, canvas.width, canvas.height);
Dies ist die schnellste und aussagekräftigste Methode, um die gesamte Leinwand zu löschen.
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.
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
Wenn Sie Linien zeichnen, stellen Sie sicher, dass Sie Folgendes nicht vergessen:
context.beginPath();
Andernfalls werden die Zeilen nicht gelöscht.
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
};
context.clearRect ( x , y , w , h );
wie von @ Pentium10 vorgeschlagen, aber IE9 scheint diese Anweisung vollständig zu ignorieren.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;
}
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);
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
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);
Ein schneller Weg ist zu tun
canvas.width = canvas.width
Idk wie es funktioniert, aber es funktioniert!
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.
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
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.
function clear(context, color)
{
var tmp = context.fillStyle;
context.fillStyle = color;
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
context.fillStyle = tmp;
}
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
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
Ich benutze immer
cxt.fillStyle = "rgb(255, 255, 255)";
cxt.fillRect(0, 0, canvas.width, canvas.height);
Context.clearRect(starting width, starting height, ending width, ending height);
Beispiel: context.clearRect(0, 0, canvas.width, canvas.height);
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
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.