Presentation in processing? Is my idea doable?

Hi,

Me and a co-worker are about to make a presentation of a project that’s almost completed. Its a change in layout in production flow in a factory.

Since we cant have a “grand opening” cause of the pandemic we are doing a demonstration on Wats done and I had an idea of making this presentation a bit more interactive than just a video och a report.

I am looking in to the possibility to make the presentation in WordPress but I also want to check with you programming gurus if this maybe possible in Processing?

I have a drawn image in this link on my vision on the flow of the presentation: https://imgbb.com/2yJsJ5t

I’m thinking like this
When I open the processing file I see a map of the factory from above. The map have some points marked out where I am able to click with the mouse.
If I click with the mouse on one of these point a “zoom in” animation starts so I feel like im traveling down to the building.
Here, I want a transition there the image fades out to all white and the page with the specific info based on where I clicked comes fading in from all white.

Also… I need video to play on the info pages…

I have no idea if this is doable in Processing and if it is, its above my skill level in programming so I would really appreciate some code examples to get me started.

My plan is to release the presentation 1st of april. We are documenting the videos and images for the presentation next week.

It would be awesome if we could use processing as a tool for this. Way cooler that sending a web page around :wink:

Hi! I did give some talks with slides made with Processing before

However it’s not “easy” in a sense that basically you need to build your own framework by yourself. If your goal is to include Processing sketches in your slides, presentation with Processing would be a great idea, but the interactive slides you proposed may need extensive development.

p5.js can be more powerful for transition effects because you can make use of HTML/CSS animations. But you still need to code a lot. Maybe looking into existing platforms like prezi would be more helpful as the first step.

4 Likes

Hi,

As @micuat said, this is exactly that :

Processing gives you all the building blocks if you want to code your own animation and transition framework in order to display text, videos, images…

It’s doable but it’s going to take time.

On the other side, you have the full power of the web technologies in order to display interactive slides and perform complex animations. You might want to look at https://revealjs.com/ which is a HTML presentation framework where you can integrate JavaScript and p5js for example!

3 Likes

Interesting

Maybe even MS PowerPoint can do this. Depends how you want to deploy the presentation (web or usb-stick or server or …)

When you try to do this in processing, a lot of ideas will come up (you haven’t thought of before) so you have to alter the framework and the data which would be VERY hard.

For example, have a Back button, additional movies and images on a page, start and stop button for the movie etc.

Also, 1st of April is very close…

Chrisir

First Sketch

Having said that, here is a first Sketch :

// Presentation in processing
// https://discourse.processing.org/t/presentation-in-processing-is-my-idea-doable/28489

// with help from micuat from the forum - https://discourse.processing.org/t/how-to-zoom-into-an-image-but-at-a-certain-point-with-scale/28510 

// constants
final color RED = color(255, 0, 0); 
final color GREEN = color(0, 255, 0); 
final color BLUE = color(0, 0, 255); 

final int timerMax = 4300; 

final int FAST_BACK_BUTTON = -10; 

// states 
final int stateNormal     = 0; // constants
final int stateAnimation1 = 1; 
final int stateAnimation2 = 2;
final int stateAnimation3 = 3; 
int state = stateNormal; // current 

//screens
ArrayList<Page> pages = new ArrayList(); 

// page number 
int currentPageNumber  = 0;
int previousPageNumber = 0; 

// for animation the page transition (for state == stateAnimation)
int currentPageNumberTarget = 0; // the new page after the animation is done 
float scaleForAnimation = 1; 
int timer=0; 
PVector animationPoint; // HotSpot the animation zooms to  

int alphaForFading=0; 

float hw; 

// -------------------------------------------------------

void setup() {
  size(800, 800);

  hw=width/2;

  // set basics 
  textAlign(CENTER, CENTER); 
  ellipseMode(CENTER);
  imageMode(CENTER); 

  // MAKE PAGES ***
  makePages();
} // func 

void draw() {
  background(0);

  switch(state) {

  case stateNormal:
    // normal page view 
    showPage(); 
    break;

  case stateAnimation1:
    // The Zoom in-animation 
    animation();    
    break;

  case stateAnimation2:
    // go to white  
    scaleForAnimation = 5;  // map(millis()-timer, 30, timerMax, 1, 5);

    pushMatrix(); 
    translate(hw, hw); 
    scale(scaleForAnimation, scaleForAnimation); 
    translate(-animationPoint.x, -animationPoint.y); 
    Page currentPage = pages.get(currentPageNumber);
    currentPage.displayForAnimation();
    popMatrix(); 

    fill(255, alphaForFading);
    noStroke();
    rect(0, 0, 
      width, height);
    alphaForFading+=5;
    if (alphaForFading>=256) {
      state=stateAnimation3;
      previousPageNumber=currentPageNumber; 
      currentPageNumber=currentPageNumberTarget;
    }
    break;

  case stateAnimation3:
    // go from white to next page 
    showPage(); 

    fill(255, alphaForFading);
    noStroke();
    rect(0, 0, 
      width, height);
    alphaForFading--;
    if (alphaForFading<=0) {
      state=stateNormal;
    }//if
    break;
    //
  }//switch
  //
}//func draw()

//--------------------------------------------------------------------------
// Tools

void makePages() {
  // called once from setup
  // Init all 
  Page newPage = new Page("page1.png");  // page 0 
  newPage.hotSpots.add(new HotSpot( new PVector(171, 327), 1, RED, "Roof: PAGE 1"  ));
  newPage.hotSpots.add(new HotSpot( new PVector(411, 330), 2, BLUE, "PAGE 2"   ));
  pages.add(newPage);
  //
  newPage = new Page("page2.jpg");    // page 1
  newPage.hotSpots.add(new HotSpot( new PVector(511, 230), FAST_BACK_BUTTON, RED, "Back"    ));
  newPage.hotSpots.add(new HotSpot( new PVector(111, 330), 2, RED, "Page 2"    ));
  pages.add(newPage);
  //
  newPage = new Page("page3.png");    // page 2
  newPage.hotSpots.add(new HotSpot( new PVector(81, 130), 0, RED, "Hall" ));
  newPage.hotSpots.add(new HotSpot( new PVector(411, 110), 3, RED, "Outside"  ));
  pages.add(newPage);
}//func 

void showPage() {
  // show page
  //
  // show page number 
  fill(GREEN); 
  text("PAGE " + currentPageNumber, 
    width/2, height-22);
  //
  // show page
  // if the index is too high?
  if (currentPageNumber>=pages.size()) {
    // error
    fill(255);
    text("Unknown page.\n\nHit BACKSPACE for page 1", 
      300, 300);
  } else {
    // valid index 
    Page currentPage = pages.get(currentPageNumber);
    currentPage.display();
  }//else
}//func 

void animation() {
  // run animation
  scaleForAnimation = map(millis()-timer, 30, timerMax, 1, 5);

  pushMatrix(); 
  translate(hw, hw); 
  scale(scaleForAnimation, scaleForAnimation); 
  translate(-animationPoint.x, -animationPoint.y); 
  Page currentPage = pages.get(currentPageNumber);
  currentPage.displayForAnimation();
  popMatrix(); 

  // timer over?
  if (millis()-timer > timerMax) {
    // END animation 1
    state=stateAnimation2;
  }//if
}//func 

//--------------------------------------------------------------------------
// Inputs 

void mousePressed() {
  //
  // if the index is too high 
  if (currentPageNumber>=pages.size()) {
    // error
    return;//leave
  }//if

  Page currentPage = pages.get(currentPageNumber);
  currentPage.mouse();
}//func

void keyPressed() {
  //
  switch(key) {
  case BACKSPACE: 
    currentPageNumber=previousPageNumber;
    break;

  case ESC:
    currentPageNumber=0; // go Home
    key=0; // kill ESC 
    break; 
    //
  }//switch
}//func 

// ========================================================================

class Page {

  // main image 
  PImage img;

  // hotspots, can be a few per page
  ArrayList<HotSpot> hotSpots = new ArrayList();

  //constr
  Page(String imgName_ ) {
    img = loadImage(imgName_);
    if (img==null) {
      println("Image not found: "+imgName_);
      exit();
      return;
    }
    img.resize(width-44, 0);   // preserve ratio
  }//constr

  void display() {
    image(img, width/2, height/2);

    for (HotSpot hs : hotSpots) {
      hs.display();
    }
  }//method

  void displayForAnimation() {
    //image(img, 0, 0);
    image(img, width/2, height/2);
  }//method

  void mouse() {
    // check my Hot Spots 
    for (HotSpot hs : hotSpots) {
      if (hs.mouse()) 
        return;
    }//for
  }//method
  //
} // class 

// ========================================================================

class HotSpot {

  PVector where;
  int target; 
  color colHotSpot; 
  String textHotSpot; 

  // constr 
  HotSpot(PVector pvW_, 
    int target_, 
    color col_, 
    String textHotSpot_) {
    //
    where  = pvW_.copy();
    target = target_;
    colHotSpot=col_;
    textHotSpot=textHotSpot_;
  }// constr 

  void display() {
    noFill();
    stroke(colHotSpot);
    for (int i=0; i<5; i++) {
      float rad=i*9+7; 
      ellipse(where.x, where.y, rad, rad);
    }

    fill(colHotSpot); 
    text(textHotSpot, 
      where.x, where.y+31);
  }//method

  boolean mouse() {
    // When THIS HotSpot has been clicked we act 
    if (dist(mouseX, mouseY, where.x, where.y) < 40) {
      // init animation
      scaleForAnimation = 1; 
      animationPoint=where.copy(); 
      currentPageNumberTarget=target;
      if (target==-10) {
        currentPageNumberTarget=previousPageNumber;
        currentPageNumber=previousPageNumber;
        return true; // Hit
      }

      state = stateAnimation1; 
      timer=millis(); 
      return true; // Hit
    }//if
    return false; // no match
  }//method
  //
}//class
//

4 Likes

That’s awesome!. But when you say VERY hard I guess I wont try to make my presentation in processing this time…

However!. This sketch is saved and it really showed me a new side of processing (as processing and programming seem to have a lot of sides) so I will take some time and really jump down this rabbit hole.

Thank you!

2 Likes

great…

1 Like

I personally like prezi

1 Like

My thought too.
It allows you to do exactly what you described really simply!

2 Likes

simplified version of the above

//
// Presentation in processing
// https://discourse.processing.org/t/presentation-in-processing-is-my-idea-doable/28489

// with help from micuat from the forum - https://discourse.processing.org/t/how-to-zoom-into-an-image-but-at-a-certain-point-with-scale/28510 

// constants
final color RED = color(255, 0, 0); 
final color GREEN = color(0, 255, 0); 
final color BLUE = color(0, 0, 255); 

final int timerMax = 1300; 

final int FAST_BACK_BUTTON = -10; 

// states 
final int stateNormal     = 0; // constants
final int stateAnimation1 = 1; 
final int stateAnimation2 = 2;
int state = stateNormal; // current 

//screens
ArrayList<Page> pages = new ArrayList(); 

// page number 
int currentPageNumber  = 0;
int previousPageNumber = 0; 

// for animation the page transition (for state == stateAnimation)
int currentPageNumberTarget = 0; // the new page after the animation is done 
float scaleForAnimation = 1; 
int timer=0; 
PVector animationPoint; // HotSpot the animation zooms to  

float widthHalf; 

// -------------------------------------------------------

void setup() {
  size(800, 800);

  widthHalf = width/2;

  // set basics 
  textAlign(CENTER, CENTER); 
  ellipseMode(CENTER);
  imageMode(CENTER); 

  // MAKE PAGES ***
  makePages();
} // func 

void draw() {
  background(0);

  switch(state) {

  case stateNormal:
    // normal page view 
    showPage(); 
    break;

  case stateAnimation1:
    // The Zoom in-animation 
    animation();    
    break;

  case stateAnimation2:
    // reset 
    state=stateNormal;
    previousPageNumber=currentPageNumber; 
    currentPageNumber=currentPageNumberTarget;
    break;

    //
  }//switch
  //
}//func draw()

//--------------------------------------------------------------------------
// Tools

void makePages() {
  // called once from setup
  // Init all 
  Page newPage = new Page("page1.png");  // page 0 
  newPage.hotSpots.add(new HotSpot( new PVector(171, 327), 1, RED, "Roof: PAGE 1"  ));
  newPage.hotSpots.add(new HotSpot( new PVector(411, 330), 2, BLUE, "PAGE 2"   ));
  pages.add(newPage);
  //
  newPage = new Page("page2.jpg");    // page 1
  newPage.hotSpots.add(new HotSpot( new PVector(511, 230), FAST_BACK_BUTTON, RED, "Back"    ));
  newPage.hotSpots.add(new HotSpot( new PVector(111, 330), 2, RED, "Page 2"    ));
  pages.add(newPage);
  //
  newPage = new Page("page3.png");    // page 2
  newPage.hotSpots.add(new HotSpot( new PVector(81, 130), 0, RED, "Hall" ));
  newPage.hotSpots.add(new HotSpot( new PVector(411, 110), 3, RED, "Outside"  ));
  pages.add(newPage);
}//func 

void showPage() {
  // show page
  //
  // show page number 
  fill(GREEN); 
  text("PAGE " + currentPageNumber, 
    width/2, height-22);
  //
  // show page
  // if the index is too high?
  if (currentPageNumber>=pages.size()) {
    // error
    fill(255);
    text("Unknown page.\n\nHit BACKSPACE for page 1", 
      300, 300);
  } else {
    // valid index 
    Page currentPage = pages.get(currentPageNumber);
    currentPage.display(); // THE CORE of this function
  }//else
} //func 

void animation() {
  // run animation
  scaleForAnimation = map(millis()-timer, 30, timerMax, 1, 5);

  pushMatrix(); 
  translate(widthHalf, widthHalf); 
  scale(scaleForAnimation, scaleForAnimation); 
  translate(-animationPoint.x, -animationPoint.y); 
  Page currentPage = pages.get(currentPageNumber);
  currentPage.displayForAnimation();
  popMatrix(); 

  // timer over?
  if (millis()-timer > timerMax) {
    // END animation 1
    state=stateAnimation2;
  }//if
}//func 

//--------------------------------------------------------------------------
// Inputs 

void mousePressed() {
  //
  // if the index is too high 
  if (currentPageNumber>=pages.size()) {
    // error
    return;//leave
  }//if

  Page currentPage = pages.get(currentPageNumber);
  currentPage.mouse();
}//func

void keyPressed() {
  //
  switch(key) {
  case BACKSPACE: 
    currentPageNumber=previousPageNumber;
    break;

  case ESC:
    currentPageNumber=0; // go Home
    key=0; // kill ESC 
    break; 
    //
  }//switch
}//func 

// ========================================================================

class Page {

  // main image 
  PImage img;

  // hotspots, can be a few per page
  ArrayList<HotSpot> hotSpots = new ArrayList();

  //constr
  Page(String imgName_) {
    img = loadImage(imgName_);
    if (img==null) {
      println("Image not found: "+imgName_+ "  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
      exit();
      return;
    }
    img.resize(width-44, 0);   // preserve ratio
  }//constr

  void display() {
    image(img, width/2, height/2);

    for (HotSpot hs : hotSpots) {
      hs.display();
    }
  }//method

  void displayForAnimation() {
    image(img, width/2, height/2);
  }//method

  void mouse() {
    // check my Hot Spots 
    for (HotSpot hs : hotSpots) {
      if (hs.mouse()) 
        return;
    }//for
  }//method
  //
} // class 

// ========================================================================

class HotSpot {

  PVector where;
  int target; 
  color colHotSpot; 
  String textHotSpot; 

  // constr 
  HotSpot(PVector pvW_, 
    int target_, 
    color col_, 
    String textHotSpot_) {
    //
    where  = pvW_.copy();
    target = target_;
    colHotSpot=col_;
    textHotSpot=textHotSpot_;
  }// constr 

  void display() {
    noFill();
    stroke(colHotSpot);
    for (int i=0; i<5; i++) {
      float rad=i*9+7; 
      ellipse(where.x, where.y, rad, rad);
    }

    fill(colHotSpot); 
    text(textHotSpot, 
      where.x, where.y+31);
  }//method

  boolean mouse() {
    // When THIS HotSpot has been clicked we act 
    if (dist(mouseX, mouseY, where.x, where.y) < 40) {
      // init animation
      scaleForAnimation = 1; 
      animationPoint=where.copy(); 
      currentPageNumberTarget=target;
      if (target==-10) {
        currentPageNumberTarget=previousPageNumber;
        currentPageNumber=previousPageNumber;
        return true; // Hit
      }

      state = stateAnimation1; 
      timer=millis(); 
      return true; // Hit
    }//if
    return false; // no match
  }//method
  //
}//class
//
//

1 Like

You should take at look at Soby by Jeremy Laviole.

I just remember this presentation made with p5.js from a processing hangout last year

1 Like