Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

CCapture.jsでp5.jsの作品をgifアニメにする方法

More than 1 year has passed since last update.

p5.jsの公式リファレンスを見ていたら、p5.jsの作品を動画として出力するならばCCapture.jsとかを使えばいいよって書いてありました試してみたところ、ちょっとだけはまったのでまとめておきます。

必要なものは、CCapture.jsとgif.jsです(それとp5.jsも)。

CCpature.jsは/build/CCapture.all.min.jsが、gif.jsは/dist/gif.worker.jsが使用するファイルとなります。

このうちのCCapture.all.min.jsだけをスクリプトタグで読み込んでおきます。

<script src="./js/CCapture.all.min.js"></script>

gif.worker.jsCCapture.all.min.jsがスクリプト内で動的に読み込み処理を行うので、スクリプトタグで読み込んでおく必要はありません。
このときに同一オリジンポリシーを回避するために、htmlファイルが置いてある場所で以下のようにローカルサーバーを立ち上げておきます(これ以外方法でローカルサーバーを立ち上げてももちろん大丈夫です)。

$ python -m SimpleHTTPServer

http://localhost:8000/にアクセスするとhtmlファイルを開くことができます。

CCapture.jsでは以下のような操作により、gifアニメを作成することができます。

// in initialization phase
var capturer = new CCapture({format: 'gif', workersPath: './js/', verbose: true});
capturer.start();

// in rendering loop
captuerer.capture(canvas);

// to finish recording
capturer.stop();
capturer.save();

CCaptuerクラスのコンストラクタに渡すオブジェクトのうちworkersPathgif.worker.jsが置いてあるディレクトリへのパスを指定するものです。
verboseオプションは必ずしも必要ではありませんが、あるとコンソールに処理の進捗が出力されるので、進行具合がわかりやすくなります。
CCapture#captureメソッドの引数にはcanvas要素を渡します。

p5.jscreateCanvasでcanvasを作成した場合、canvas要素は以下の方法で取得できます。

var p5Canvas = createCanvas(500, 500);
var canvas = canvas.canvas;

(p5.jsの公式リファレンスにはcreateCanvasの返り値はHTMLCanvasElementと書かれていますが、実際にはp5.Renderer2Dクラスのオブジェクトが返り値になっています)

実際にp5.jsでCCapture.jsを使用したソースコードは以下のようになります。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Sample to making anmation gif for p5.js by CCapture.js</title>
  </head>
  <body>
    <script src="./js/p5.js"></script>
    <script src="./js/CCapture.all.min.js"></script>
    <script>
      var loopFrame = 180;
      var capturer = new CCapture({format: 'gif', workersPath: './js/', verbose: true});
      var canvas;

      function setup() {
        var p5Canvas = createCanvas(500, 500);
        canvas = p5Canvas.canvas;
        rectMode(CENTER);
        noStroke();
        colorMode(HSB, 360, 100, 100);
        capturer.start();
      }

      function draw() {
        background(0);
        var t = (frameCount % loopFrame) / loopFrame;
        for (var w = 0; w <= width; w += 20) {
          for (var h = 0; h <= height; h += 20) {
            var d = sqrt(sq(w - width / 2) + sq(h - height / 2));
            var size = lerp(5, 10, sin(d * 0.1 + t * TWO_PI * 2.0) * 0.5 + 0.5);
            fill(t * 360, 100, 100);
            rect(w, h, size, size);
          }
        }
        if (frameCount < loopFrame) {
          capturer.capture(canvas);
        } else if (frameCount === loopFrame) {
          capturer.stop();
          capturer.save();
        }
      }
    </script>
  </body>
</html>

作成されるgifアニメはこんな感じです。
result.gif

aa_debdeb
Engineer, Creative Coder。Dentsu Craft Tokyo所属。
https://twitter.com/aa_debdeb
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