Verwenden von Web Workers zum Zeichnen mit nativen Canvas-Funktionen
Es möglich ist, senden Sie eine CanvasPixelArray
erhältlich über getImageData
zu einer worker-Skript, und lassen Sie den worker-Skript manipulieren die Pixel im hintergrund-thread, und schließlich nach der manipulierten pixel-array zurück.
Aber ich bin mit native canvas-Zeichenfunktionen, wie drawImage
. Die drawImage
Anrufe sind derzeit die Blockierung der UI-thread. Dies bewirkt, dass langsame Neuzeichnen von buttons, und eine deutliche Verzögerung beim klicken auf eine Schaltfläche, um nur ein paar Nachteile. (Edit: Eine kleine Verbesserung können jetzt erreicht werden mit ctx.imageSmoothingEnabled = false
zumindest auf WebKit mit der webkit
Präfix.)
Ich würde gerne verschieben Sie die Zeichnung aus dem Haupt-thread in einen hintergrund-thread mit Web-worker. Aber ich weiß nicht zu sein scheinen in der Lage zu senden, die Leinwand und den Rahmen für den Arbeitnehmer.
Habe ich dieser Hinweis auf MDN:
Hinweis: Wie üblich, hintergrund-threads—einschließlich der Arbeitnehmer—nicht das DOM manipulieren. Wenn die Maßnahmen, die hintergrund-thread müssen auch änderungen der DOM, Sie sollten das veröffentlichen von Nachrichten zurück, um Ihre Schöpfer zu tun, die Arbeit.
Aber ich möchte verlassen die DOM -, als -, ist; ich möchte einfach Dinge zeichne auf ein canvas-element. Ist das möglich, oder sind Web-Arbeiter wirklich nur berechnen darf und nicht zum zeichnen?
(Oder ist es vielleicht möglich, Sie zu verwenden, Funktionen wie drawImage
zu manipulieren CanvasPixelArray
statt der Zeichnung auf eine Leinwand?)
InformationsquelleAutor der Frage pimvdb | 2011-11-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
[Gemeinschaft edit: Diese Antwort war geschrieben und angenommen in 2011. Andere Technologien entstanden sind (oder entstehen), was es erlaubt, Web-worker und Leinwand zu co-existieren, besser zu sein; der Leser sollte sich bewusst sein, alle Antworten auf dieser Seite neben dieser Antwort.]
Kann nicht übergeben werden ein canvas-Objekt oder canvas-Kontext an einen worker-thread, weil die Leinwand ist Teil des DOM.
InformationsquelleAutor der Antwort John Watson
[Bearbeiten ~5 Jahre später: einige dieser beginnt sich zu ändern, und es gibt neue web-Plattform-Funktionen, die eigentlich erlauben rendering auf eine Leinwand, von einem Arbeiter! Finden Sie in diesem blog für mehr info: https://hacks.mozilla.org/2016/01/webgl-off-the-main-thread/ - der rest der Antwort ist vorgesehen für 2011-era Informationen ;)]
Web-worker kann nur berechnet werden, nicht ändern Sie den DOM oder machen Aufrufe zum zeichnen auf eine Leinwand. Aber wie Sie sagen, Sie können ein array von Pixeln in einen web-worker, um es zu verarbeiten es und senden Sie es zurück. Da das asynchrone sehe ich nicht, warum dazu führen würde, dass jede Verlangsamung der UI-thread, es sei denn, Sie absichtlich zu blockieren, bis die web-worker reagiert (was Sie nicht sollte).
So scheint es seltsam, dass Ihr
drawImage
Anrufe einnehmen, so lange es Auswirkungen auf die UI. Die meisten Leinwände sind hardware-beschleunigte diesen Tagen, so dass Sie überspringen sollen gut zusammen. Meine Vermutung ist, dass Sie zeichnen, über ein web-worker, um eine canvas-pixel-array jeden framedie effektiv bedeutet, dass Sie software-rendering die Leinwand in javascript. Javascript ist immer noch viel zu langsam, um dies zu tun - auch C++ software-Renderer sind eine Art von langsam, das ist der Grund, warum die hardware-Beschleunigung ist wichtig. So können Sie machen etwas, um ein canvas-pixel-array in einen web-worker einmalund dann, wenn Sie Ihre Ergebnis-cache es in einerImage
einmalund zeichnen Sie dann, dassImage
auf der Leinwand so viel wie Sie möchten. Das sollte doch wirklich schnell.Edit: vielleicht möchten Sie sich in WebGL, wo Sie schreiben, fragment-Shader, die sind effektiv zu wenig Programme zu Prozess-pixel-Effekte. Sie laufen komplett auf der Grafikkarte, somit sind Sie blöd fallen.
InformationsquelleAutor der Antwort AshleysBrain
Können Sie nach der
ImageData
auf die Web-Worker, die zum senden der manipuliertenImageData
zurück an den Aufrufer (Main-UI-thread).E. g.:
Erstellen eines Web-Worker:
Post die
ImageData
erstellt von der Leinwand auf die Web-Worker:Tun
ImageData
manipulation in Web-Worker und schicken Sie es zurück zum Haupt-thread:Setzen die manipulierten
ImageData
auf der Leinwand in der Main-thread:InformationsquelleAutor der Antwort Osi
Gibt es eine neue API, dies zu tun (derzeit nur unterstützt in Firefox, wenn Sie die eine pref).
Sehen https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas und
https://hacks.mozilla.org/2016/01/webgl-off-the-main-thread/.
InformationsquelleAutor der Antwort Marco