casher-Scope

Since I am still new to Javascript/p5.js, I didn't totally understand what the code in the template meant when I began this assignment. As a result, most of my design is from experimentation. I started out by writing some groups of statements similar to the template's, and then I just started changing values of variables and parameters, testing the limits of the application. I spent a long time perfecting everything so it looked aesthetic.

There's not much else to explain, but I love the way it turned out! And I am pleased with the effort I put in because now I definitely better understand how the code works.

/*
// 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 bRecordingPNG = false;
 
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;
 
//-------------------------------------------------------
function setup() {
  createCanvas(792, 612); // 11x8.5" at 72DPI
  frameRate(20);
  smooth();
} 
 
 
//-------------------------------------------------------
function draw() {
  background(255); 
 
  // Do all the drawing. 
  push(); 
  translate(width/2, height/2);
  drawCutLines(); 
  //drawGuides(); 
  drawAllFrames();
  pop();
 
 
  if (bRecordingPNG) {
    saveCanvas('myPraxinoscope.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 Praxinoscope.
    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
        saveFrames('Praxinoscope_', 'png', recordDuration, recordFramerate); 
        bExportFrameImages = false;
      }
 
      break;
  }
}
 
//-------------------------------------------------------
function drawCutLines() {
  fill(0); 
  textAlign(CENTER, BOTTOM); 
  text("Praxinoscope Template", 0, 0-diamCutOuter/2-6); 
 
  stroke(0); 
  strokeWeight(1.0);
 
  noFill(); 
  if (!bRecordingPNG) {
    fill(255); 
  }
  ellipse(0, 0, diamCutOuter, diamCutOuter);
 
  noFill(); 
  if (!bRecordingPNG) {
    fill(240); 
  }
  ellipse(0, 0, diamCutInner, diamCutInner);
 
  noFill(); 
  ellipse(diamCutOuter/2 - holeDx, 0-holeDy, holeD, holeD); 
 
  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 (!bRecordingPNG) {
 
    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 ) { 
 
  //ellipses
  fill(random(0, 255), random(150,200), random(200,230));
  stroke(255);
  strokeWeight(2);
  for (var i = 0; i < nFrames; i++)
  {
    var t = map(whichFrame, 1, nFrames, 1, i*.38);
  	var diam = map(cos(t*TWO_PI*.22), -1, 1, -i*8, i*8);
  	ellipse(0,i*7-10,diam*.7,diam*0.4);
  }
 
  //lines
  p1 = -45;
  p2 = 70;
  p3 = -0;
  p4 = 54;
  stroke(100);
  strokeWeight(1.2);
  line2 = map(whichFrame, -1, 1, -50, 50);
  for (var i = 0; i < nFrames; i++) {
    line(p1+8*whichFrame,p2,p3,p4);
  }
 
  //triangles
  var p1x = 50;
  var p1y = -25;
  var p2x = 60;
  var p2y = -60;
  var p3x = -40;
  var p3y = -10;
  strokeWeight(2);
  stroke(255);
  for (var i = 0; i < nFrames; i++) {
    fill(25*whichFrame);
    triangle(p1x/(whichFrame*-1)-10, p1y-40, p2x/(whichFrame**2)+20, p2y+20, p3x+whichFrame*10, p3y);
    fill(30*whichFrame);
    triangle(p1x/(whichFrame*2)-3, p1y-30, p2x/(whichFrame)+20, p2y+20, p3x+whichFrame*-2+15, p3y);
  }
 
  //circles
  var p1 = -50;
  var p2 = 0;
  noFill();
  stroke(50);
  strokeWeight(1);
  for (var i = 0; i < nFrames-4; i+=2) {
    stroke(2**whichFrame);
    ellipse(p1-whichFrame*5, p2+20, 10, 10);
    p1 = 0;
    p2 = 0;
  }
}