33

CanvasPixelArray取得した viaをワーカー スクリプトに送信getImageDataし、ワーカー スクリプトがバックグラウンド スレッドでピクセルを操作できるようにし、最終的に操作されたピクセル配列を送り返すことができます。

ただし、ネイティブのキャンバス描画関数を使用していますdrawImagedrawImage呼び出しは現在 UI スレッドをブロックしています。これにより、ボタンの再描画が遅くなり、ボタンをクリックしたときに顕著な遅延が発生します。いくつかの欠点を挙げると. ctx.imageSmoothingEnabled = false(編集:少なくともwebkitプレフィックス付きの WebKit では、小さな改善が実現できるようになりました。)

Web ワーカーを使用して、描画をメイン スレッドからバックグラウンド スレッドに移動したいと考えています。ただし、キャンバスもコンテキストもワーカーに送信できないようです。

私はMDN でこの通知を見つけました:

注: いつものように、ワーカーを含むバックグラウンド スレッドは DOM を操作できません。バックグラウンド スレッドによって実行されるアクションによって DOM が変更される必要がある場合は、作成者にメッセージをポストしてその作業を行う必要があります。

しかし、DOM はそのままにしておきたいと思います。キャンバス要素に物を描きたいだけです。これは可能ですか、それとも Web ワーカーは実際に計算のみが許可され、描画は許可されていませんか?

(または、キャンバスに描画drawImageする代わりに、を操作するような関数を使用することはおそらく可能ですか?)CanvasPixelArray

4

4 に答える 4

42

[~5 年後に編集: 一部は変更され始めており、Worker からキャンバスへのレンダリングを実際に可能にする新しい Web プラットフォーム機能があります! 詳細については、このブログを参照してください

Web ワーカーは計算のみを行うことができ、DOM を変更したり、キャンバスに描画するための呼び出しを行ったりすることはできません。ただし、あなたが言うように、ピクセルの配列をWebワーカーに投稿してそこで処理し、投稿することができます。これは非同期であるため、Web ワーカーが応答するまで意図的にブロックしない限り (そうすべきではありません)、UI スレッドの速度が低下する理由がわかりません。

drawImageそのため、呼び出しに時間がかかりすぎて UI に影響を与えているのは奇妙に思えます。最近のほとんどのキャンバスはハードウェアで高速化されているため、うまくスキップできます。私の推測では、フレームごとに Web ワーカーを介してキャンバス ピクセル配列に描画しているということです。これは事実上、キャンバスを javascript でソフトウェア レンダリングしていることを意味します。Javascript はこれを行うにはまだ遅すぎます。C++ ソフトウェア レンダラーでさえも遅いため、ハードウェア アクセラレーションが重要です。そのため、Web ワーカーのキャンバス ピクセル配列に何かを once レンダリングし、結果を取得したらImage onceにキャッシュし、それImageをキャンバスに好きなだけ描画できます。それはまだ本当に速いはずです。

編集: ピクセル効果を処理するための事実上小さなプログラムであるフラグメント シェーダーを記述できる WebGL を参照することをお勧めします。それらは完全にグラフィックカード上で実行されるため、非常に高速です。

于 2011-11-28T19:21:25.223 に答える
10

[コミュニティ編集: この回答は 2011 年に作成され、承認されました。Web Workers と Canvas をより適切に共存させる可能性のある他のテクノロジが出現しました (または出現しつつあります)。読者は、この回答以外に、このページのすべての回答に注意する必要があります。]

キャンバスは DOM の一部であるため、キャンバス オブジェクトまたはキャンバス コンテキストをワーカー スレッドに渡すことはできません。

于 2011-11-27T21:13:11.727 に答える