xxxxxxxxxx
231
// p5.js Template for Zoetrope toy by Eye Think
// https://www.amazon.com/Zoetrope-Animation-Toy-Victorian-Illusion/dp/B007VM9HZO/
// Processing version: https://github.com/golanlevin/ZoetropeTemplate/
// 6 September 2018 * Golan Levin
var bRecordingPNG = false;
var inch = 72;
var paperStripWidth = inch * 12.625;
var paperStripHeight = inch * 1.3125;
var overlapMargin = inch * 0.4375;
var artAreaWidth = paperStripWidth - overlapMargin;
var artAreaHeight = paperStripHeight;
var nFrames = 11;
var myFrameCount = 0;
var exportFrameCount = 0;
var bAnimate = true;
var bExportFrameImages = false;
//-------------------------------------------------------
function setup() {
createCanvas(1224, 792); // 17x11" at 72DPI
frameRate(20);
smooth();
}
//-------------------------------------------------------
function draw() {
background(240);
// Do all the drawing.
push();
translate(width / 2, height / 2);
translate(0 - paperStripWidth / 2, 0 - paperStripHeight / 2);
drawCutLines();
drawGuides();
drawAllFrames();
pop();
if (bRecordingPNG) {
saveCanvas('myZoetrope.png', 'png');
bRecordingPNG = false;
}
}
//-------------------------------------------------------
function keyPressed() {
switch (key) {
case ' ':
// Press spacebar to pause/unpause the animation.
bAnimate = !bAnimate;
break;
case 'p':
case 'P':
// Press 'p' to export a PNG for the Zoetrope.
// Note: This is for 17x11" paper!
bRecordingPNG = true;
break;
case 'f':
case 'F':
// Press 'f' to export multiple frames
// (in order to make an animated .GIF)
// such as with http://gifmaker.me/
myFrameCount = 0;
exportFrameCount = 0;
bExportFrameImages = true;
bAnimate = true;
if (bExportFrameImages) {
var recordFramerate = 1.0;
var recordDuration = nFrames * 1.01;
frameRate(recordFramerate); // 1 FPS baby
// (filename, extension, duration, framerate, [callback])
saveFrames('Zoetrope_', 'png', recordDuration, recordFramerate);
bExportFrameImages = false;
}
break;
}
}
//-------------------------------------------------------
function drawCutLines() {
fill(0);
textAlign(CENTER, BOTTOM);
text("EyeThink Zoetrope Template", paperStripWidth / 2, -20);
stroke(0);
strokeWeight(1.0);
noFill();
if (!bRecordingPNG) {
fill(255);
}
rect(0, 0, paperStripWidth, paperStripHeight);
}
//-------------------------------------------------------
function drawGuides() {
// This function draws the guidelines.
// Don't draw these when we're exporting the PDF.
if (!bRecordingPNG) {
var frameSpacing = artAreaWidth / nFrames;
stroke(128);
strokeWeight(0.2);
for (var i = 0; i < nFrames; i++) {
push();
translate(i * frameSpacing, 0);
rect(0, 0, frameSpacing, artAreaHeight);
pop();
}
}
}
//-------------------------------------------------------
function drawAllFrames() {
for (var i = 0; i < nFrames; i++) {
var frameSpacing = artAreaWidth / nFrames;
push();
translate((i + 0.5) * frameSpacing, 0);
var whichFrame = i;
if (bAnimate) {
whichFrame = (i + myFrameCount) % nFrames;
}
drawArtFrame(whichFrame);
// drawArtFrameAlternate (whichFrame);
pop();
}
myFrameCount++;
}
//-------------------------------------------------------
function drawArtFrame(whichFrame) {
// Draw the artwork for a generic frame of the Zoetrope,
// given the framenumber (whichFrame) out of nFrames.
// Draw the frame number
fill(0);
noStroke();
textAlign(CENTER, CENTER);
text(whichFrame, 0, artAreaHeight * 0.22);
// Draw a pulsating ellipse
noFill();
stroke(0);
strokeWeight(1);
var t = map(whichFrame, 0, nFrames, 0, 1);
var diam = map(cos(t * TWO_PI), -1, 1, artAreaHeight * 0.20, artAreaHeight * 0.40);
ellipse(0, artAreaHeight * 0.22, diam, diam * 0.75);
// Draw some expanding boxes, centered on the local origin
var nBoxes = 3;
for (var i = 0; i < nBoxes; i++) {
var F = ((whichFrame + i * nFrames) / (1.0 * nBoxes)) % nFrames;
var rs = map(F, 0, nFrames - 1, 0, artAreaHeight * 0.20);
var rx = 0;
var ry = artAreaHeight * 0.5;
var rg = map(F, 0, nFrames, 0, 255);
stroke(rg);
strokeWeight(1.0);
rect(rx - rs / 2, ry - rs / 2, rs, rs);
}
// Draw some rotating spokes
var nSpokes = 7;
var spokeRadius = artAreaHeight * 0.10;
for (var i = 0; i < nSpokes; i++) {
var cx = 0;
var cy = artAreaHeight * 0.80;
var u = 0 - map(whichFrame + i * nFrames, 0, nFrames * nSpokes, 0, 1);
var sx = cx + spokeRadius * cos(u * TWO_PI);
var sy = cy + spokeRadius * sin(u * TWO_PI);
stroke(0);
strokeWeight(1);
line(cx, cy, sx, sy);
}
}
//-------------------------------------------------------
function drawArtFrameAlternate(whichFrame) {
// An alternate drawing test.
// Draw a falling object.
var chuteHeight = artAreaHeight * 0.85;
push();
translate(0, (artAreaHeight - chuteHeight) / 2.0);
// Draw a little splat on the frame when it hits the ground.
if (whichFrame == (nFrames - 1)) {
stroke(0, 0, 0);
strokeWeight(0.5);
var nL = 10;
for (var i = 0; i < nL; i++) {
var a = HALF_PI + map(i, 0, nL - 1, 0, TWO_PI);
var cx = 12 * cos(a);
var cy = 10 * sin(a);
var dx = 16 * cos(a);
var dy = 13 * sin(a);
line(cx, (chuteHeight - 5) + cy, dx, (chuteHeight - 5) + dy);
}
}
// Draw a little box frame
fill(255);
stroke(0, 0, 0);
strokeWeight(1);
rect(-5, 0, 10, chuteHeight);
// Make the puck accelerate downward
var t = map(whichFrame, 0, nFrames - 1, 0, 1);
var t2 = pow(t, 2.0);
var rh = 8 + whichFrame * 0.5; // wee stretch
var ry = map(t2, 0, 1, 0, chuteHeight - rh);
noStroke();
fill(0, 0, 0);
rect(-5, ry, 10, rh);
pop();
}