13

I use Atom Editor. I want to make 20 seconds GIF with my canvas. saveFrames() has a limitation(I guess). It enables to save .png files to short gifs(3-5 seconds), even if I type saveFrames("aa","png",15,22);

I discovered CCapture.js but I could not find any code example to export canvas.

It does not have to be exported as GIF; but I want to at least save .png snaps of my animation in canvas limitlessly. How can I do it?

My animation code in p5.js:

var x = 0;
var speed = 10;
var d1 = 100;
var d2 = 100;

function setup() {
  createCanvas(600, 400);
  background(0);
  //saveFrames("aa","png",15,22);
}

function draw() {
  stroke(random(100, 255), 0, random(100, 190));
  strokeWeight(1.5);
  ellipse(x, 100, d1, d1);
  x = x + speed;
  d1 = d1 - 0.6;
  
  if (x > width || x < 0) {
    speed = speed * -1;
    fill(speed * 51);
  }
  
  ellipse(x, 300, d1, d1);
  ellipse(x, 200, 50, 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/p5.min.js"></script>
ggorlen
  • 44,755
  • 7
  • 76
  • 106
Zeki Akyol
  • 193
  • 1
  • 1
  • 10

3 Answers3

14

I've been working on a new library which supports GIF exports, p5.createLoop.

This will run the sketch and then render a GIF at the same frame rate.


function setup() {
  createCanvas(600, 400);
  background(0);
  frameRate(22)
  createLoop({duration:15,gif:true})
}

Here's a codePen with the full example. It'll take about two minutes and is over 50MB, totally worth it

chantey
  • 4,252
  • 1
  • 35
  • 40
5

After a full day of research, surprizingly, I found a video uploaded youtube 2 weeks ago: CCapture Video

Dont forget that CCapture exports (gif size=canvas sizex2).

Zeki Akyol
  • 193
  • 1
  • 1
  • 10
2

>= 1.5.0

P5 has saveGif as of 1.5.0, which lets you write n seconds or frames to a downloadable gif. See the docs for usage.


< 1.5.0

I want to at least save .png snaps of my animation in canvas limitlessly. How can I do it?

You can do this directly in p5.js using save(`${name}.png`) after each frame you want to snap. This normally pops a dialog prompt asking you where you want to save the file, but you can disable this in browsers (as of 2021) so the images get automatically sent to the default download location.

For example, in Chrome (Version 92.0.4515.159 at the time of writing this post), navigate to chrome://settings/downloads and disable "Ask where to save each file before downloading":

toggling save prompt for downloads in chrome settings

With the prompt disabled, I found that p5.js's default framerate was too high for the browser to keep up with the downloads, so I added frameRate(4); to setup so that only 4 frames run per second. You can speed this up a bit depending on your needs and compute power, but some throttling helped give me a clean, sequential download of each of the frames into separate PNGs.

Clearly, this procedure isn't at all user-friendly (or particularly elegant). It's intended for turning your sketches into gifs yourself rather than an interface feature of a public-facing website. That said, the process does open up ideas for interactivity using buttons and other triggers for controlling the next frame to export in a creative way. You could use a button to start/stop the animation, for example, or programmatically determine specific conditions to emit the next frame.

Here's the two relevant lines added to your sketch. You'll want to run this locally rather than as a Stack snippet, which runs in a sandboxed frame that won't have download access:

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js">
  </script>
</head>
<body>
<script>
var x = 0;
var speed = 10;
var d1 = 100;
var d2 = 100;

function setup() {
  createCanvas(600, 400);
  background(0);
  frameRate(4); // <-- feel free to adjust
}

function draw() {
  stroke(random(100, 255), 0, random(100, 190));
  strokeWeight(1.5);
  ellipse(x, 100, d1, d1);
  x = x + speed;
  d1 = d1 - 0.6;
  
  if (x > width || x < 0) {
    speed = speed * -1;
    fill(speed * 51);
  }
  
  ellipse(x, 300, d1, d1);
  ellipse(x, 200, 50, 50);

  save(`frame_${frameCount}.png`); // <--
}
</script>
</body>
</html>

Once you have the frames downloaded, you can use your favorite PNG -> GIF creator. I used ffmpeg as described here: ffmpeg -f image2 -framerate 60 -i frame_%d.png -loop 0 out.gif.

Here's the result on the first few frames of your sketch (scaled down 50% with ffmpeg's -vf scale=300x200 flag to keep bandwidth for this page reasonable):

animated gif result from p5.js

ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • Also, there's a new library https://github.com/tapioca24/p5.capture but I haven't tried it yet. – ggorlen Nov 16 '22 at 20:39