Nachdem ich mit zusammengesetzten Operationen experimentiert und Bilder auf die Leinwand gezeichnet habe, 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.
javascript
html
canvas
html5-canvas
composite
Richard
quelle
quelle
clearRect
Sie entweder einen nicht transformierten Kontext haben oder Ihre tatsächlichen Grenzen verfolgen müssen.context.clearRect(0, 0, context.canvas.width, context.canvas.height)
. Es istVerwenden:
context.clearRect(0, 0, canvas.width, canvas.height);
Dies ist der schnellste und aussagekräftigste Weg, um die gesamte Leinwand zu löschen.
Verwende nicht:
canvas.width = canvas.width;
Durch das
canvas.width
Zurücksetzen wird der gesamte Canvas-Status zurückgesetzt (z. B. Transformationen, Zeilenbreite, Strichstil usw.). Dies ist sehr langsam (im Vergleich zu clearRect), funktioniert nicht in allen Browsern und beschreibt nicht, was Sie tatsächlich versuchen.Umgang mit transformierten Koordinaten
Wenn Sie die Transformationsmatrix geändert haben (zB mit
scale
,rotate
odertranslate
) , danncontext.clearRect(0,0,canvas.width,canvas.height)
wird wahrscheinlich nicht den gesamten sichtbaren Teil der Leinwand löschen.Die Lösung? Setzen Sie die Transformationsmatrix zurück, bevor Sie die Zeichenfläche löschen:
Bearbeiten: Ich habe gerade ein Profil erstellt und (in Chrome) ist es ungefähr 10% schneller, eine Leinwand im Format 300 x 150 (Standardgröße) zu löschen, ohne die Transformation zurückzusetzen. Mit zunehmender Größe Ihrer Leinwand nimmt dieser Unterschied ab.
Das ist bereits relativ unbedeutend, aber in den meisten Fällen zeichnen Sie erheblich mehr als Sie löschen, und ich halte diesen Leistungsunterschied für irrelevant.
quelle
canvas
Variablen entfernen können, indem Siectx.canvas
stattdessen verwenden.canvas.width
undcanvas.height
beim Löschen anzuwenden . Ich habe keine numerische Analyse des Laufzeitunterschieds im Vergleich zum Zurücksetzen der Transformation durchgeführt, aber ich vermute, dass dies zu einer etwas besseren Leistung führen würde.Wenn Sie Linien zeichnen, vergessen Sie nicht:
Andernfalls werden die Zeilen nicht gelöscht.
quelle
beginPath
Sie an, wenn Sie einen neuen Weg beginnen , nehmen Sie das nicht an, nur weil Sie Löschen Sie die Leinwand, auf der Sie auch Ihren vorhandenen Pfad löschen möchten! Dies wäre eine schreckliche Praxis und eine rückwärts gerichtete Sichtweise auf das Zeichnen.beginPath
nichts von Ihrer Zeichenfläche, setzt den Pfad zurück, sodass vorherige Pfadeinträge entfernt werden, bevor Sie zeichnen. Sie haben es wahrscheinlich gebraucht, aber als Zeichenvorgang, nicht als Löschvorgang. klar, dann beginPath und zeichne, nicht clear und beginPath, dann zeichne. Ist der Unterschied sinnvoll? Schauen Sie hier für ein Beispiel: w3schools.com/tags/canvas_beginpath.aspAndere haben die Frage bereits hervorragend beantwortet, aber wenn eine einfache
clear()
Methode 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:Verwendungszweck:
quelle
context.clearRect ( x , y , w , h );
wie von @ Pentium10 vorgeschlagen, aber IE9 scheint diese Anweisung vollständig zu ignorieren.canvas.width = canvas.width;
Es werden jedoch keine Linien, sondern nur Formen, Bilder und andere Objekte gelöscht, es sei denn, Sie verwenden auch die Lösung von @John Allsopp, bei der zuerst die Breite geändert wird.Wenn Sie also eine Leinwand und einen Kontext wie folgt erstellt haben:
Sie können eine Methode wie die folgende verwenden:
quelle
context.clearRect(0,0,context.canvas.width,context.canvas.height)
.function clearCanvas(ctx) { ctx.beginPath(); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); }
Dies ist 2018 und es gibt noch keine native Methode, um die Leinwand für das Neuzeichnen vollständig zu löschen.
clearRect()
nicht die Leinwand ganz klar. Nicht ausgefüllte Zeichnungen werden nicht gelöscht (z. B.rect()
)1.Um die Leinwand vollständig zu löschen, unabhängig davon, wie Sie zeichnen:
Vorteile: Erhält StrokeStyle, FillStyle usw.; Keine Verzögerung;
Nachteile: Unnötig, wenn Sie beginPath bereits verwenden, bevor Sie etwas zeichnen
2.Verwenden Sie den Breite / Höhe-Hack:
ODER
Vorteile: Funktioniert mit IE Nachteile: Setzt stroSStyle, fillStyle auf schwarz zurück; Laggy;
Ich habe mich gefragt, warum es keine native Lösung gibt. Wird tatsächlich
clearRect()
als einzeilige Lösung betrachtet, da die meisten Benutzer dies tun,beginPath()
bevor sie einen neuen Pfad zeichnen. Obwohl beginPath nur zum Zeichnen von Linien und nicht für geschlossene Pfade verwendet werden darfrect().
Dies ist der Grund, warum die akzeptierte Antwort mein Problem nicht löste und ich Stunden damit verschwendete, verschiedene Hacks auszuprobieren. Verfluche dich Mozilla
quelle
Verwenden Sie die clearRect-Methode, indem Sie x-, y-Koordinaten sowie Höhe und Breite der Leinwand übergeben. ClearRect löscht die gesamte Leinwand wie folgt:
quelle
Hier gibt es eine Menge guter Antworten. Eine weitere Anmerkung ist, dass es manchmal Spaß macht, die Leinwand nur teilweise zu räumen. Das heißt, das vorherige Bild wird "ausgeblendet", anstatt es vollständig zu löschen. Dies kann schöne Trails-Effekte ergeben.
es ist einfach. Angenommen, Ihre Hintergrundfarbe ist weiß:
quelle
Ein schneller Weg ist zu tun
Idk wie es funktioniert, aber es funktioniert!
quelle
Dies ist, was ich benutze, unabhängig von Grenzen und Matrixtransformationen:
Grundsätzlich wird der aktuelle Status des Kontexts gespeichert und ein transparentes Pixel mit
copy
as gezeichnetglobalCompositeOperation
. Stellt dann den vorherigen Kontextstatus wieder her.quelle
Dies funktionierte für mein pieChart in chart.js
quelle
Ich habe festgestellt, dass in allen Browsern, die ich teste, der schnellste Weg darin besteht, Rect tatsächlich mit Weiß oder einer beliebigen Farbe zu füllen. Ich habe einen sehr großen Monitor und im Vollbildmodus ist clearRect quälend langsam, aber fillRect ist vernünftig.
Der Nachteil ist, dass die Leinwand nicht mehr transparent ist.
quelle
Im Webkit müssen Sie die Breite auf einen anderen Wert einstellen, dann können Sie sie auf den Anfangswert zurücksetzen
quelle
quelle
Eine einfache, aber nicht sehr lesbare Möglichkeit besteht darin, Folgendes zu schreiben:
quelle
Ich benutze immer
quelle
Füllen Sie das angegebene Rechteck mit RGBA-Werten:
0 0 0 0: mit Chrome
0 0 0 255: mit FF & Safari
Aber
Lass das Rechteck mit
0 0 0 255 gefüllt sein,
egal welcher Browser!
quelle
Beispiel:
context.clearRect(0, 0, canvas.width, canvas.height);
quelle
der kürzeste Weg:
quelle
schnellste Weg:
quelle
clearRect
.Wenn Sie clearRect nur verwenden und es in einem Formular zum Senden Ihrer Zeichnung haben, erhalten Sie stattdessen das Senden der Löschung, oder es kann zuerst gelöscht und dann eine leere Zeichnung hochgeladen werden, sodass Sie eine hinzufügen müssen PreventDefault zu Beginn der Funktion:
Hoffe es hilft jemandem.
quelle
Ich benutze das immer
HINWEIS
Die Kombination von clearRect und requestAnimationFrame ermöglicht eine flüssigere Animation, wenn Sie dies wünschen
quelle
Dies sind alles gute Beispiele dafür, wie Sie eine Standard-Leinwand löschen. Wenn Sie jedoch paperjs verwenden, funktioniert dies:
Definieren Sie eine globale Variable in JavaScript:
Definieren Sie in Ihrem PaperScript:
Wo immer Sie clearCanvas auf true setzen, werden alle Elemente vom Bildschirm gelöscht.
quelle