Iframes + multiple sketches + webstorage api


#1

I’m designing a psychology experiment that uses two very different sketches.

  • I only want one to be seen at a time.
  • Sketch #1 implements a sequencer using the p5.sound library, a single button, and a slider
  • Sketch #2 displays buttons strewn all across a much larger canvas, and you must click on them in order.
  • Once you click the done button on Sketch#1, Sketch #2 should appear.
  • Response data from both must be combined and sent to a text file on a server.

I realize that Instantiation can help me, but it seems awfully complicated, to me at least. So, I was thinking I’d use iFrames as was suggested in this related link

https://discourse.processing.org/t/best-strategy-to-run-multiple-p5-sketches-on-a-page/216?u=mark

I have many questions, and could spend another 17 hours trying to find answers, but I’m hoping you folks could point me in the right direction a bit sooner. Here they are:

  1. What is the code to hide or show an iFrame? Can code within an iframe cause the iframe to be hidden?

  2. I need to be able to combine data that is collected by the two sketches before I save it to my server. I’m not a database guy – this will be a simple text file. I think that the web storage api would be the best way to hold onto the data from sketch #1 while sketch #2 is at work. Yes? Can anyone give me a quick example of how that works, would I save the data from within the sketch, or outside. I’ve never used Web Storage.

  3. Does instantiation offer me any advantages over the iframe approach?

  4. Are html elements (buttons, sliders) created within an instance actually part of the instance? If I hide the instance, those elements will still be showing, right?

  5. Related to this, one of the sketches relies on the p5.sound library. Would I even need to include that within the instantiation? I’m confused what stuff should go inside the instantiated sketch, and what stays outside. For example, when I have to use lines like the one below (starting with “var kickPhrase”) in my sketch, I’m just not sure how to do that in the instance mode:

var s = function( sketch ) {
....
....
....
  sketch.setup = function() {
      var kickPhrase  = new p5.Phrase('kick', playKick, kickPat); 
      ...
  }
}

Where the heck would the “sketch” prefix go in the line starting with var? Or does it at all?

I apologize for the many questions. If I could only see more examples of instantiation than the one that p5.js uses (it simply draws a box), I might be more inclined to go this way. Help!

Thanks,
Mark


#2

I’d encourage you to check out the p5.SceneManager. It seems to be built for exactly what you’re trying to accomplish with sequencing sketches together

as for storage, if you use scene manager, you can keep the important things in the global scope and then send them off to the server as needed or use something like store.js to keep it in web storage (or whatever the users browser supports) and then offload that to the server as need be


#3

Thanks bmoren.

I agree that p5.SceneManager does look exactly like what I need, but I’m having the same issue with almost no documentation. They give one example, but it’s just not enough for me to really translate into a working project. Also, at the bottom of the scenemanager.js file it can use prototypes, but I only have a cursory knowledge of those, despite watching Dan Schiffman’s wonderful videos on the topic. I don’t really understand how they are used or beneficial.

Has anyone else used scenemanager who would be willing to share examples?

  • Mark

#4

Hi Mark,

here are some tips:

Basically what the scene manager is doing is packaging up each of you’re sketches into their own entities. so you could do a few things to get it working with your existing code.

  1. rename each of your sketch.js files to some thing more descriptive like firstExperiment.js
  2. link to those files in the index.html so you have a single project with each of your sketches linked in but in individual documents. This will let you keep the files seperate but use them all together. (I find this is easier for organization, although if its confusing you could keep everything in one file.)
  3. create a new sketch.js and link it to index.html
  4. in the new sketch.js create a new scenemanager instance like they do in the documentation:
function Intro()
{
    this.setup = function() {
    }

    this.draw = function() {
    }

    this.keyPressed = function() {
        // switch the scene
      if(key == 'A'|| key == 'a'){
        this.sceneManager.showScene( firstExperiment );
      }else if (key == 'B' || key == 'b'){
        this.sceneManager.showScene( secondExperiment );
      }
    }
}

What this code is going to do is look for the keypress and then look for a scene named firstExeperiment if we press the A key or secondExperiment if we press the B key. more on how to define those scenes coming up.

Ok now to set up each scene.

  1. open firstExperiment.js
  2. change the structure so it reflects the scene structure
function firstExperiment()
{
    this.setup = function() {
//all of the first experiment setup code
    }

    this.draw = function() {
//all of the first experiment draw code
    }
}

now you’ve created a scene. and the main scenemanager above can switch to it if you press the A key. if that works, then implement on the second experiment, etc.

One big thing to watch out for is you’re variables. if you leave them in the global scope and you have variables like let x = 500 in both of you’re scenes you’re going to run into issues of having those variables overwritten by eachother. you might do 1 of two things.

  1. make sure no variables share a name across all of the scenes.
  2. use more local / scene specific variables
function firstExperiment()
{
  //define scene specific variables
  this.x = 500
  this.y = 500
  this.h = 300
  this.w = 500

    this.setup = function() {
      //all of the first experiment setup code
    }

    this.draw = function() {
      //all of the first experiment draw code
      //use scene specific variables.
      rect(this.x,this.y,this.h,this.w)
    }
}

one final note is that you dont need to make use of prototypes to use this thing afaik. you should be able to set it up how they describe on the main readme just as re-packaging each of you’re sketches as scene classes.

happy coding!
b.

ps. sorry for any errors, I’ve not had any coffee yet :upside_down_face:


#5

bmoren,

Thanks for all of this. I haven’t had time to work through it all yet, but it’s much appreciated. I’m sure I’ll be back in a week or two with more questions.

Cheers,
Mark