Skip to content

Instantly share code, notes, and snippets.

@somaholiday
Last active October 4, 2020 19:51
Show Gist options
  • Save somaholiday/af9fc6f8eabc033dcab28b1d6fcad22c to your computer and use it in GitHub Desktop.
Save somaholiday/af9fc6f8eabc033dcab28b1d6fcad22c to your computer and use it in GitHub Desktop.
Processing Template for Creating Looping Animated GIFs (with many thanks to beesandbombs)
/*
This file is slightly adapted from the template used by beesandbombs (https://gist.github.com/beesandbombs)
Many thanks to him for sharing his work with the rest of us!
*/
void drawFPS() {
if (frameCount % 30 == 0) {
surface.setTitle(this.getClass().getName() + " | FPS : " + nf(frameRate, 2, 2) + " | Runtime: " + frameCount + " | t: " + nf(t, 1, 5));
}
}
void drawMouseT() {
surface.setTitle(this.getClass().getName() + " | t(mouse) : " + nf(t, 1, 5));
}
String getTimestamp() {
return year() + nf(month(), 2) + nf(day(), 2) + "-" + nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2);
}
String getTimeDuration(int ms) {
int sec = floor(ms / 1000.);
int min = floor(sec / 60.);
sec = sec % 60;
return min + "m" + nf(sec, 2) + "s";
}
void center() {
translate(width * 0.5, height * 0.5);
}
void uncenter() {
translate(-width * 0.5, -height * 0.5);
}
float mapsin(float param, float min, float max) {
return map(sin(param), -1, 1, min, max);
}
float mapcos(float param, float min, float max) {
return map(cos(param), -1, 1, min, max);
}
//////////////////////////////////////////////////////////////////////////////
int[][] result;
float t;
int start;
int nfl; // str(numFrames).length()
float ease(float p) {
return 3*p*p - 2*p*p*p;
}
float ease(float p, float g) {
if (p < 0.5)
return 0.5 * pow(2*p, g);
else
return 1 - 0.5 * pow(2*(1 - p), g);
}
float mn = .5*sqrt(3);
/*******
SETUP()
******/
void setup() {
size(1000, 1000);
setup_();
result = new int[width*height][3];
if (state == State.RECORD) {
println("RECORDING");
println("numFrames: ", numFrames);
println("samplesPerFrame:", samplesPerFrame);
println("shutterAngle: ", shutterAngle);
start = millis();
nfl = str(numFrames).length();
}
}
/******
DRAW()
*****/
void draw() {
switch(state) {
case RECORD: {
int frame = frameCount;
///////////
// sampling
for (int i=0; i<width*height; i++)
for (int a=0; a<3; a++)
result[i][a] = 0;
for (int sa=0; sa<samplesPerFrame; sa++) {
t = map(frame-1 + sa*shutterAngle/samplesPerFrame, 0, numFrames, 0, 1);
draw_();
loadPixels();
for (int i=0; i<pixels.length; i++) {
result[i][0] += pixels[i] >> 16 & 0xff;
result[i][1] += pixels[i] >> 8 & 0xff;
result[i][2] += pixels[i] & 0xff;
}
}
loadPixels();
for (int i=0; i<pixels.length; i++)
pixels[i] = 0xff << 24 |
int(result[i][0]*1.0/samplesPerFrame) << 16 |
int(result[i][1]*1.0/samplesPerFrame) << 8 |
int(result[i][2]*1.0/samplesPerFrame);
updatePixels();
// sampling
///////////
saveFrame("f###.png");
// status report every ten frames
if (frameCount % 10 == 0) {
println("frame", nf(frame, nfl), "/", numFrames, "•", nf(frame/float(numFrames) * 100, 3, 2), "% •", getTimeDuration(millis() - start));
}
if (frame==numFrames) {
println("~ completed in", getTimeDuration(millis() - start), "~");
exit();
}
break;
}
case MOUSE: {
t = mouseX*1.0/width;
draw_();
drawMouseT();
break;
}
case PREVIEW:
default: {
t = (millis()/(60.0*numFrames))%1;
draw_();
drawFPS();
}
}
}
enum State {
RECORD,
PREVIEW,
MOUSE
}
//////////////////////////////////////////////////////////////////////////////
/* DO YOUR WORK BELOW THIS LINE */
//////////////////////////////////////////////////////////////////////////////
// the number of frames your loop should be
int numFrames = 120;
// the number of samples per frame to take for motion blur
int samplesPerFrame = 8;
// the distance between samples to be considered for motion blur
float shutterAngle = .6;
/*
Uncomment the State you want to run in:
RECORD
outputs the sketch into a collection of individual frame files
suitable for stitching together in a tool like gifsicle or ffmpeg
PREVIEW
runs the sketch like normal, looping over and over
MOUSE
allows you to scrub through the loop by moving your mouse horizontally
*/
//State state = State.RECORD;
State state = State.PREVIEW;
//State state = State.MOUSE;
//////////////////////////////////////////////////////////////////////////////
void setup_() {
// do your setup here
// NOTE that Processing 3 enforces that you
// call size() ONLY in the normal setup() above
}
void draw_() {
// do your draw here
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment