/*
// Template for KidzLabs/4M/Toysmith Animation Praxinoscope
// https://www.amazon.com/4M-3474-Animation-Praxinoscope/dp/B000P02HYC
// https://www.walmart.com/ip/Animation-Praxinoscope-Science-Kits-by-Toysmith-3474/45681503
// Developed for p5.js, September 2018 * Golan Levin
*/
var inch = 72.0;
var diamArtInner = inch * 1.50;
var diamArtOuter = inch * 4.80;
var diamCutInner = inch * 1.41;
var diamCutOuter = inch * 4.875;
var holeDy = inch * 0.23;
var holeDx = inch * 0.20;
var holeD = inch * 0.1;
var nFrames = 10;
var myFrameCount = 0;
var exportFrameCount = 0;
var bAnimate = true;
var bExportFrameImages = false;
var bRecordingSinglePNG = false;
//-------------------------------------------------------
function setup() {
createCanvas(792, 612); // 11x8.5" at 72DPI
frameRate(20);
smooth();
}
//-------------------------------------------------------
function draw() {
background(240);
// Do all the drawing.
push();
translate(width/2, height/2);
drawCutLines();
drawGuides();
drawAllFrames();
pop();
if (bExportFrameImages){
// Note that myFrameCount is incremented elsewhere.
var filename = "myZoetrope_" + nf(myFrameCount,2) + ".png";
saveCanvas(filename, 'png');
if (myFrameCount >= nFrames){
bExportFrameImages = false;
}
}
if (bRecordingSinglePNG) {
saveCanvas('myPraxinoscope.png', 'png');
bRecordingSinglePNG = false;
}
}
//-------------------------------------------------------
function mouseClicked() {
console.log(mouseX, mouseY);
}
function keyPressed() {
switch (key) {
case ' ':
// Press spacebar to pause/unpause the animation.
bAnimate = !bAnimate;
break;
case 'p':
case 'P':
// Press 'p' to export a single PNG for the Zoetrope.
// Note: This is for 17x11" paper!
// Be sure to print at 100%!
bRecordingSinglePNG = 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;
break;
}
}
//-------------------------------------------------------
function drawCutLines() {
fill(0);
textAlign(CENTER, BOTTOM);
text("Praxinoscope Template", 0, 0-diamCutOuter/2-6);
stroke(250);
strokeWeight(1.0);
if (bRecordingSinglePNG) {
fill(0);
}
ellipse(0, 0, diamCutOuter, diamCutOuter);
if (bRecordingSinglePNG) {
fill(0);
}
ellipse(0, 0, diamCutInner, diamCutInner);
fill(255);
ellipse(diamCutOuter/2 - holeDx, 0-holeDy, holeD, holeD);
stroke(240)
line (diamCutInner/2, 0, diamCutOuter/2, 0);
}
//-------------------------------------------------------
function drawGuides() {
// This function draws the guidelines.
// Don't draw these when we're exporting the PNG.
if (!bRecordingSinglePNG) {
noFill();
stroke(128);
strokeWeight(0.2);
ellipse(0, 0, diamArtInner, diamArtInner);
ellipse(0, 0, diamArtOuter, diamArtOuter);
for (var i=0; i<nFrames; i++) {
var angle = map(i, 0, nFrames, 0, TWO_PI);
var pxi = diamArtInner/2 * cos(angle);
var pyi = diamArtInner/2 * sin(angle);
var pxo = diamArtOuter/2 * cos(angle);
var pyo = diamArtOuter/2 * sin(angle);
stroke(128);
strokeWeight(0.2);
line (pxi, pyi, pxo, pyo);
}
// Draw the red wedge outline, highlighting the main view.
// var redWedge = 7; // assuming nFrames = 10
// for (var i=redWedge; i<=(redWedge+1); i++) {
// var angle = map(i, 0, nFrames, 0, TWO_PI);
// var pxi = diamArtInner/2 * cos(angle);
// var pyi = diamArtInner/2 * sin(angle);
// var pxo = diamArtOuter/2 * cos(angle);
// var pyo = diamArtOuter/2 * sin(angle);
// stroke(255, 0, 0);
// strokeWeight(2.0);
// line (pxi, pyi, pxo, pyo);
// }
// noFill();
// stroke(255, 0, 0);
// strokeWeight(2.0);
// var startAngle = redWedge*TWO_PI/nFrames;
// var endAngle = (redWedge+1)*TWO_PI/nFrames;
// arc(0, 0, diamArtInner, diamArtInner, startAngle, endAngle);
// arc(0, 0, diamArtOuter, diamArtOuter, startAngle, endAngle);
for (var i=0; i<nFrames; i++) {
var angle = map(i, 0, nFrames, 0, TWO_PI);
push();
rotate(angle);
var originY = ((diamArtOuter + diamArtInner)/2)/2;
translate(0, 0-originY);
noFill();
stroke(128);
strokeWeight(0.2);
line (-inch/2, 0, inch/2, 0);
line (0, -inch/2, 0, inch/2);
pop();
}
}
}
//-------------------------------------------------------
function drawAllFrames() {
for (var i=0; i<nFrames; i++) {
var angle = map(i, 0, nFrames, 0, TWO_PI);
var originY = ((diamArtOuter + diamArtInner)/2)/2;
push();
rotate(angle);
translate(0, 0-originY);
scale(0.8, 0.8); // feel free to ditch this
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 Praxinoscope,
// given the framenumber (whichFrame) out of nFrames.
// NOTE #1: The "origin" for the frame is in the center of the wedge.
// NOTE #2: Remember that everything will appear upside-down!
// Draw the frame number
fill(0);
noStroke();
textAlign(CENTER, CENTER);
text (whichFrame, 0, -45);
// Draw eyes
fill(255);
stroke(255);
strokeWeight(1);
ellipse(-18, -48, 28,28);
ellipse(18, -48, 28,28);
ellipse(0,-33,15,10);
//draw eye balls
fill(0);
noStroke();
var xAxis = map(whichFrame, 0,nFrames, 0,PI)
arc(sin(xAxis)*16-18-14+6, -48, 12,12,PI/6,(11*PI)/6, PIE);
arc(sin(xAxis)*16-18-14+6+36 , -48, 12,12,PI/6,(11*PI)/6, PIE);
//clock
fill(255);
stroke(255);
rect(-25,-23, 50, 70, 10);
//clock tix
stroke(0);
strokeWeight(2 );
line (0, -13, 0, -18);
line (0, -13, 0, -18);
line (0, 35, 0, 40);
line (-18,12, -13,12);
line (18,12, 13,12);
//whiskers
stroke(255)
line (-20,-30, -45,-35);
line (-20,-25, -45,-20);
line (20,-30, 45,-35);
line (20,-25, 43,-20);
// Draw some rotating spokes
var cx = 0;
var cy = 12;
var u = 0 - map(whichFrame, 0, nFrames, 0, 1);
var sx = cx + 15 * cos(u * TWO_PI);
var sy = cy + 15 * sin(u* TWO_PI);
stroke(0);
line (cx, cy, sx, sy);
var dx = 0;
var dy = 12;
var u2 = 0 - map(whichFrame, 0, nFrames/2, 0, 1);
var vx = dx + 20 * cos(u2 * (TWO_PI+1.2));
var vy = dy + 20 * sin(u2* (TWO_PI+1.2));
stroke(0);
strokeWeight(1);
line (dx, dy, vx, vy);
} |