How to save your p5.js sketch as a GIF using CCapture.js

I’ve managed to host a CCapture demo sketch online: :star_struck:
https://ThimbleProjects.org/gotoloop/509340
https://ThimbleProjects.org/gotoloop/509340/sketch.js

Important note: the CCapture library demands the file “gif.worker.js” in order to save all of the capture() canvas frames as a “.gif” file! You can grab 1 at the link below: :robot:
http://cdn.JsDelivr.net/npm/gif.js/dist/gif.worker.js

“index.html”:

<!DOCTYPE html>

<meta charset=utf-8>
<meta name=viewport content=width=device-width,initial-scale=1>

<script defer src=https://cdn.JsDelivr.net/npm/ccapture.js></script>

<script defer src=https://cdn.JsDelivr.net/npm/p5></script>
<!--<script defer src=https://cdn.JsDelivr.net/npm/p5/lib/addons/p5.dom.min.js></script>-->
<!--<script defer src=https://cdn.JsDelivr.net/npm/p5/lib/addons/p5.sound.min.js></script>-->

<script defer src=sketch.js></script>

“sketch.js”:

/**
 * CCapture Bouncing Colorful Balls Demo (v1.0)
 * GoToLoop (2018-Jun-26)
 *
 * https://Discourse.Processing.org/t/
 * how-to-save-your-p5-js-sketch-as-a-gif-using-ccapture-js/1264/2
 *
 * https://ThimbleProjects.org/gotoloop/509340
 * http://CodePen.io/GoSubRoutine/pen/KaerGb/right/?editors=101
 *
 * Get the "gif.worker.js" file from:
 * http://cdn.JsDelivr.net/npm/gif.js/dist/gif.worker.js
 */

"use strict";

const NUM = 15, balls = Array(NUM),

      FORMAT = 'gif', WORKERSFOLDER = './',
      VERBOSE = false, DISPLAY = true,
      FPS = 60, FRAMERATE = FPS, FRAMELIMIT = 5 * FPS,

      capturer = new CCapture({
        format: FORMAT, workersPath: WORKERSFOLDER,
        verbose: VERBOSE, display: DISPLAY,
        framerate: FRAMERATE, frameLimit: FRAMELIMIT
      });

let bg;

function setup() {
  createCanvas(400, 400).mousePressed(restart);
  frameRate(FPS).noStroke();

  bg = color(random(0xd0, 0x100), random(0xd0, 0x100), random(0xd0, 0x100));
  for (let i = 0; i < NUM; balls[i++] = new Ball);

  capturer.start();
  console.table(capturer);
}

function draw() {
  background(bg);
  for (const b of balls)  b.display().update();
  capturer.capture(canvas);
}

function restart() {
  bg = color(random(0xd0, 0o400), random(0xd0, 0o400), random(0xd0, 0o400));
  for (const b of balls)  b.initBall();
}

class Ball {
  static get VEL() { delete this.VEL; return this.VEL = 2; }
  static get MIN_RAD() { delete this.MIN_RAD; return this.MIN_RAD = 5; }
  static get MAX_RAD() { delete this.MAX_RAD; return this.MAX_RAD = 30; }

  constructor() {
    this.pos = createVector(), this.vel = createVector();
    this.initBall();
  }

  initBall() {
    const r = this.rad = random(Ball.MIN_RAD, Ball.MAX_RAD), v = Ball.VEL;
    this.pos.set(random(r, width - r), random(r, height - r));
    this.vel.set(random(-v, v), random(-v, v));
    this.c = color('#' + hex(~~random(0x1000), 3));
    return this;
  }

  update() {
    const { pos, rad } = this;
    pos.add(this.vel);
    pos.x > width  - rad | pos.x < rad && (this.vel.x *= -1);
    pos.y > height - rad | pos.y < rad && (this.vel.y *= -1);
    return this;
  }

  display() {
    fill(this.c).ellipse(this.pos.x, this.pos.y, this.rad<<1);
    return this;
  }
}
3 Likes