1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Chrome web workerを使ってcanvasで絵を描く。

Last updated at Posted at 2018-10-22

Chrome web workerを使ってcanvasで絵を描く。

※まだChrome69から実装された機能で他のブラウザでは動きません。

動機

描画の高速化を調べて色々ググっていると、MDNにOffscreenCanvasなるメソッドの記事を見つけて、WebWorkerを使えば何とかなるんじゃないかと考えていたのでこの記事はまさにど真ん中の記事でした。

早速実装にとりかかるとWebWorker初実装の私には、コールバックの嵐に見事に心が砕けてしまいました。
そこに救世主・・・・Comlinkが現れました。

Comlinkとは

コールバックやらイベントやらで呼ぶのではなく、その辺をよきに計らってくれてPromiseを返してくれるライブラリです。
コールバックよりは、async-awaitの方が読みやすいかなと使ってみることに。
githubを見てみると「Support OffscreenCanvas (fixes #165)」の文字が、これは期待度が高まります。

早速インストール

npm i comlink
main.js
import * as Comlink from "comlink";
class Main {
    constructor() {
      this.createPng = Comlink.proxy(new Worker("worker.js"));
    }
    async createPng(){
        const instance = await new this.createPng();
        const canvas = document.createElement('canvas');
        const offscreen = canvas.transferControlToOffscreen();
        const url = await instance.createPng(offscreen);
        return url;
    }
    async show() {
       let imageData = await this.createPng(history, date);
       // 実際の描画処理。
    }

}
woker.js
import * as Comlink from "comlink";
class MyClass {
 async createPng(offscreen) {
    let ctx = offscreen.getContext("2d");
    // ・・・描画処理
    // 完成したらpngURLに変換
    //toDataURLメソッドがないので、convertToBlob()で代用。 
    const blob = await offscreen.convertToBlob();
    const p = new Promise ((resove,reason) => {
      const reader = new FileReader();
      reader.onload = () =>{
        let dataUrl = reader.result;
        let base64 = dataUrl.split(',')[1];
        resove("data:image/png;base64, "+base64);
        
      }; 
      reader.readAsDataURL(blob);
    });
    return await p;
 }
}
Comlink.expose(MyClass, self);

動かない。全く動かない。

 インストールしたモジュールをみると、「Support OffscreenCanvas (fixes #165)」で追加された実装がないことが分かりました。
しかたなく、githubからzipを持ってきてファイルを置き換えることに。

動いた!

最初は、canvas と offscreen を使いまわす予定でしたが、ループ処理を入れると、offscreenのところでエラーが発生するので、worker側を呼び出す前に毎回作成するように変更しました。

まとめ

Comlinkはいいですね。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?