Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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はいいですね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした