知っている人は知っている方法だと思いますが、実際にやってみたのでメモ。

※ デモの画像はこちらからお借りしました。特にライセンスが記述されていなかったのですが、問題があれば差し替えます。

ライブラリは jsgif というのを使わせて頂きました。

手順はライブラリを読み込み、画像をひとコマ分ずつ canvas にロード、ライブラリに追加。終わったらバイナリから gif ファイルを生成、という感じ。

もう少し詳しい解説は以下。

  1. LZWEncoder.js NeuQuant.js GIFEncoder.js を読み込む
  2. 適切なサイズの canvas を用意
  3. GIFEncoder からエンコーダを作る
    var encoder = new GIFEncoder();
  4. アニメーションの時間間隔などを encoder に設定
    encoder.setRepeat(0);
    encoder.setDelay(100);
    encoder.setSize(120, 120);
  5. 一コマずつ書き始める
    encoder.start();
    1. canvas に絵を書く
      canvas.drawImage(img);
    2. encoder に canvas のコンテキストを追加することで一コマを追加
      encoder.addFrame(ctx);
  6. 書き込み終了
    encoder.finish()
  7. encoder からバイナリを吐き出して、Blobを作る
    var bin = new Uint8Array(encoder.stream().bin);
    var blob = new Blob([bin.buffer], {type: ‘image/gif’});
  8. Blob から URL を作って表示 (revoke を忘れずに)
    var url = URL.createObjectURL(blob);  
    var image = new Image();
    image.src = url;
    image.onload = function() {
    URL.revokeObjectURL(url);
    };

デモはこの辺に。

※ このデモは Firefox 推奨です。Chrome では img.onload で実際に画像が読み込まれ ない場合があるというバ グのせいで、アニ メーションが一部抜けたりしてしまいます。画像を読み込むのに Ajax を使うなどの回避 方法はあるのですが、このデモでは可読性を優先して画像を src から読み込む方法を採 りました。ただ、僕のコードにバグがある可能性もあるので、その場合はこっそり教え て下さい :)

こっそりじゃないけど Google+ で教えてもらいまし た。完全に僕の勘違いで した。お恥ずかしい・・・。

ソースコードはこちら

参考: