4

I need to pass in an additional argument when invoking a new p5 instance in instance mode.

I want to be able to do this:

var x = 50;

var sketch = function(p5){

  p5.setup = function(x){
    // Canvas setup etc
    rect(x,40,40,40)
  }
}

new p5(sketch, x)

Right now, it's showing as undefined, which leads me to believe that new p5 can only ever take one argument. Is there a method available that allows me to pass in additional arguments to an instance, without hacking p5?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Modermo
  • 1,852
  • 2
  • 25
  • 46

3 Answers3

8

Yeah, you can't just add random parameters to the p5 object like that. Also note that the p5 constructor and the setup() function are two entirely different things. You call the constructor, and the P5.js library calls the setup() function for you.

I'm really not sure what you're trying to do. Why don't you just get rid of the x parameter (which is undefined) and reference the top-level x variable (which is 50)?

You might be able to do something slightly goofy, like this:

function defineSketch(x){

  return function(sketch){
    sketch.setup = function(){
      // Canvas setup etc
      rect(x,40,40,40)
    }
  }
}

And then you could do:

var mySketch = defineSketch(100);
new p5(mySketch);

That's pretty gross though.

Edit: You can also do this:

var s = function( sketch ) {

  sketch.setup = function() {
    sketch.createCanvas(200, 200);
  };

  sketch.draw = function() {
    sketch.background(0);
    sketch.rect(sketch.x, sketch.y, 50, 50);
  };
};

var myp5 = new p5(s);
myp5.x = 75;
myp5.y = 25;

This works because sketch is the instance of p5 that you create. So you can add properties to the p5 instance, which is passed into your sketch function.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • Because I want to be able to do something like `new p5(sketch, 50)` OR `new p5(sketch(50))`. Essentially, I want to be able to call a new instance and pass in a custom argument. – Modermo Sep 19 '17 at 03:04
  • Hey, yeah I saw it after I responded :) Your response is actually how I've pulled it off (great minds), and I agree, it's convoluted. I was just hoping there was an alternative. – Modermo Sep 19 '17 at 03:06
  • @Modermo I found a (slightly weird) option. Check out my newest edit. – Kevin Workman Sep 19 '17 at 03:46
  • Neat find. I suppose that works because the you're actually assigning a property to the `myp5` object after instantiation, and `sketch.setup` is reading from that. This is from the top of my head though, I could be wrong here. – Modermo Sep 19 '17 at 04:01
  • @Modermo I think it works because `sketch` is the instance of `p5` that you create. So you can add properties to the `p5` instance, which is then passed into your sketch function when the P5.js library runs. – Kevin Workman Sep 19 '17 at 04:16
  • There it is. Thanks for your help :) – Modermo Sep 19 '17 at 05:08
  • @Modermo No problem. Thanks for the interesting question. – Kevin Workman Sep 19 '17 at 05:14
1

To summarize @KevinWorkman's answer, you can't pass additional arguments to new p5() or expect p5.setup to have additional parameters, but you can use closures:

var x = 50;

var sketch = function(p5) {

  p5.setup = function() {
    // Canvas setup etc
    rect(x, 40, 40, 40);
  };
};

new p5(sketch);

The x variable will be still accessible in the p5.setup function.

If you change x before calling new p5(sketch), new value will be used to draw the rectangle.

Kinrany
  • 99
  • 1
  • 9
1

A way to pass data to the sketch is to add the data to the canvas wrapper element and read it in the sketch function.

const sketch = (s) => {
  let x;


  s.setup = () => {
    x = s._userNode.config.x;
  }
}

const element = document.querySelector('#canvas-wrapper');
element.config = {x: 50};
new p5(sketch, element);
sp0nje
  • 11
  • 2