sooj – Scope

Hover Flap (Zoetrope)

Inspired to use the traditional “squash and stretch” animated motion, I simulated a hovering motion of a a circular flap. This was a resultant of experimentation using mainly cosine and sine curves to achieve not only the ball’s traveling, but also its squashing and stretching motion. After first getting the ball to move up and down, I gave a shadow underneath to add some dimension. As a result, that made the ball look like a thin, flap object that hovers on the ground. This activity allowed me to get a better grasp of how the map function can be utilized to control ranges of motion.

Here is the PDF file: sooj-scope

Code (Template Provided by Prof. Golan Levin)

 
// Processing Template for Zoetrope toy by Eye Think
// https://www.amazon.com/Zoetrope-Animation-Toy-Victorian-Illusion/dp/B007VM9HZO/
// Developed for Processing 3.3.6 * http://processing.org
// 24 January 2018 * Golan Levin 
 
// See information about Processing PDF export at: 
// https://processing.org/reference/libraries/pdf/index.html
// PDF generated by Processing can be opened in Adobe Illustrator.
import processing.pdf.*;
boolean bRecordingPDF = false;
 
float inch = 72; 
float paperStripWidth = inch * 12.625;
float paperStripHeight = inch * 1.3125;
float overlapMargin = inch * 0.4375;
float artAreaWidth = paperStripWidth - overlapMargin;
float artAreaHeight = paperStripHeight;
 
final int nFrames = 11; 
int myFrameCount = 0;
int exportFrameCount = 0; 
boolean bAnimate = true; 
boolean bExportFrameImages = false;
 
//-------------------------------------------------------
void setup() {
  size(1224, 792); // 17x11" at 72DPI
  frameRate(10);
  smooth();
} 
 
//-------------------------------------------------------
void draw() {
  background(240); 
  if (bRecordingPDF) {
    beginRecord(PDF, "zoetrope-output.pdf");
  }
 
  // Do all the drawing. 
  pushMatrix(); 
  translate(width/2, height/2);
  translate(0-paperStripWidth/2, 0-paperStripHeight/2); 
 
  drawCutLines(); 
  drawGuides(); 
  drawAllFrames();
  popMatrix();
 
  if (bExportFrameImages) {
    // If activated, export .PNG frames 
    if (exportFrameCount < nFrames) { String filename = "frame_" + nf((exportFrameCount%nFrames), 3) + ".png"; saveFrame("frames/" + filename); println("Saved: " + filename); exportFrameCount++; if (exportFrameCount >= nFrames) {
        bExportFrameImages = false;
        exportFrameCount = 0;
      }
    }
  }
 
  if (bRecordingPDF) {
    endRecord();
    bRecordingPDF = false;
  }
}
 
 
//-------------------------------------------------------
void keyPressed() {
  switch (key) {
  case ' ': 
    // Press spacebar to pause/unpause the animation. 
    bAnimate = !bAnimate;
    break;
 
  case 'p': 
  case 'P':
    // Press 'p' to export a PDF for the Zoetrope. 17x11" paper!
    bRecordingPDF = true; 
    break;
 
  case 'f': 
  case 'F': 
    // Press 'f' to export .png Frames (to make an animated .GIF)
    myFrameCount = 0; 
    exportFrameCount = 0; 
    bExportFrameImages = true;
    bAnimate = true; 
    break;
  }
}
 
//-------------------------------------------------------
void drawCutLines() {
  fill(0); 
  textAlign(CENTER, BOTTOM); 
  text("Hover Flap", paperStripWidth/2, -20); 
 
  stroke(0); 
  strokeWeight(1.0);
  noFill(); 
  if (!bRecordingPDF) {
    fill(255);
  }
  rect(0, 0, paperStripWidth, paperStripHeight);
}
 
//-------------------------------------------------------
void drawGuides() {
  // This function draws the guidelines. 
  // Don't draw these when we're exporting the PDF. 
  if (!bRecordingPDF) {
    float frameSpacing = artAreaWidth / nFrames;
 
    stroke(128); 
    strokeWeight(0.2);
    for (int i=0; i<nFrames; i++) {
      pushMatrix();
      translate(i * frameSpacing, 0);
      rect(0, 0, frameSpacing, artAreaHeight); 
      popMatrix();
    }
  }
}
 
//-------------------------------------------------------
void drawAllFrames() {
  for (int i=0; i<nFrames; i++) {
 
    float frameSpacing = artAreaWidth / nFrames;
 
    pushMatrix();
    translate((i + 0.5) * frameSpacing, 0);
 
    int whichFrame = i; 
    if (bAnimate) {
      whichFrame = (i+myFrameCount)%nFrames;
    }
    drawArtFrame (whichFrame); 
    popMatrix();
  }
  myFrameCount++;
}
 
//-------------------------------------------------------
void drawArtFrame (int whichFrame) { 
  fill(255); 
  noStroke(); 
 
//variables needed
  float percent = map(whichFrame, 0, nFrames, 0,1); 
  float shadow_default = 80;
  float shadow_value = (((255-shadow_default)/(whichFrame+1)) * 0.5 * cos(percent*PI));
  float shadow_diam = map(-cos(percent*TWO_PI), -1, 1, artAreaHeight*0.20, artAreaHeight*0.40); 
 
  float shadowx = 0;
  float shadowy = artAreaHeight * 0.75;
 
  float margin = 20;
  float flapx = (artAreaHeight * 0.2) - margin;
  float flapy = (artAreaHeight * 0.5) * sin(percent*PI)+margin;
  float flapw = 30* (sin(percent*PI)+0.2);
  float flaph = 30* (cos(percent/1.5*PI)+0.2);
 
//draw the shadow
  fill(shadow_default + shadow_value);
  noStroke();
  ellipse(shadowx, shadowy, shadow_diam, shadow_diam*0.5); 
 
//draw the hover
  fill(120);
  ellipse(flapx, flapy, flapw, flaph);
}