>= 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":

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):
