error calling a method in instance mode

I'm trying to call a p5 method using [instanceobject].method(). I'm receiving an "undefined error. What am I doing wrong (or maybe what I'm trying to do isn't possible??). Error is on last line of code below.

var s = function(sketch){  
    var gray = 0;   
    sketch.setup = function() {         
        sketch.createCanvas(200, 200);  
        sketch.ellipse(sketch.width/2, sketch.height/2, 100, 100);  
    };  
    sketch.draw = function() {  
    };        
};
var p5_0 = new p5(s,"m-canvas-shape");
var p5_1 = new p5(s,"m-canvas-gd");  
//this line generates an error:
//"Cannot read property 'clearRect' of undefined"
p5_1.clear();
Tagged:

Comments

  • Thanks for the formatting link

  • Warning: I know little about P5.js itself...

    You mention clearRect in the comment, and I see clear()...

    Basically, the error means that p5_1 is not defined, I suppose it is because p5 doesn't find the "m-canvas-gd" id in your HTML file. (I am guessing, actually, what this second parameter is... Actually, I can't find this constructor after a quick search on the site.)

  • Actually, I can't find this constructor after a quick search on the site.

    Found that in this link: https://github.com/lmccart/p5.js/wiki/Instantiation-Cases
    Unfortunately the order of parameters there is WRONG! @-)
    It says p5(node, s);. But it's the opposite as we can see from its source below:
    var p5 = function(sketch, node, sync) {
    https://github.com/lmccart/p5.js/blob/master/src/core/core.js#L38
    Nevertheless, var p5_0 = new p5(s,"m-canvas-shape"); should work if "m-canvas-shape" exists.

  • Philho and GoToLoop: Thanks for your feedback.

    I finally tried something a little different and so far it appears to be doing what I want it to. I'm not sure if p5 is intended to be used this way, so if somebody has some other ideas, I'm def open to suggestions: (old man trying to learn new technology)

        var s = function(sketch){  
            var gray = 0;   
            sketch.setup = function() {         
                sketch.createCanvas(200, 200);  
                //other setup code
                var obj = new complexGraph(sketch);
            };  
            sketch.draw = function() {  
            };        
    
        };
        var p5_0 = new p5(s,"m-canvas-shape");
    
        function complexGraph(sketch) {
            sketch.clear();
            //code to create shapes using p5
            sketch.ellipse(100,100,50,100);
            etc.
        }
    
  • edited February 2015

    Hmm... There are some points I haven't completely got:

    • That var obj = new complexGraph(sketch);
    • Variable obj is declared local to setup(). Therefore it's inaccessible elsewhere.
    • complexGraph() doesn't seem a class constructor. So why the new?
    • Having the other functions, besides setup() & draw(), outside the sketch is a good idea.
    • However, they're not aware of any variables declared inside the defined sketch.
    • If any external function happens to need them, they gotta be passed as arguments to it.
    • Another tip, sketch is too long a name to be typed in all the time.
    • A 1-character name is more comfortable for such usage. For example: s. :D

    Take a look at this tweaked version: B-)

    const sketch = function(s) {
      var gray = 0;
    
      s.setup = function() {
        s.createCanvas(200, 200);
        s.frameRate(60).smooth();
        s.ellipseMode(CENTER);
      };
    
      s.draw = function() {
        complexGraph(s, gray);
      };
    };
    
    p5(sketch, 'm-canvas-shape');
    p5(sketch, 'm-canvas-gd');
    
    function complexGraph(s, c) {
      s.clear();
      s.fill(c);
      s.ellipse(s.width>>1, s.height>>1, s.width>>2, s.height>>1);
    }
    
  • GoToLoop, thanks for the input.

    re: using objects. I probably didn't provide enough info in my previous post. (Also, I have a c# background and it's probably influencing my approach to js.) What I'm trying to do is:

    1. Display a shape in the canvas (e.g. complexGraph or other pre-defined shape)
    2. User has input controls to modify properties of the shape.
    3. User can save the modified shape to a "sketch".  A sketch in my logic is  just an array of shapes, e.g.
    sketch = [];
    sketch[0] = complexGraph (with properties modified by user)
    sketch[1] = some-other-shape
    etc.
    4.  sketch will be displayed by drawing each shape in the sketch array,
    5.  user can modify existing shapes in the sketch, also add, delete, etc.
    
    Originally, I instantiated the complexGraph obj outside of the "s" function.  But I was having problems associating the obj with a specific canvas.
    e.g.
    //create two canvases
    var p5_0 = new p5(s,"m-canvas-shape");
    var p5_1 = new p5(s,"m-canvas-gd");  
    //instantiate shape object, modify properties, etc
    obj = new complexGraph()
    //I just wasn't sure how to pass a canvas reference into the object. I couldn't get the following to work, but maybe I need to re-think my whole approach to this.
    obj = new complexGraph(p5_0);
    
  • edited February 2015
    • Dunno if I grasp exactly what you're trying to do. ^#(^
    • All Processing framework flavors favors 1-canvas approach.
    • In "Java Mode", canvas is an app window. In "p5*js" it is a region inside the web page.
    • Rather than instantiating many sketches to get that many canvas, we have 1 big canvas and various PGraphics.
    • We can draw over a PGraphics/p5.Graphics w/o affecting the others.
    • We can also save() them separately: http://p5js.org/reference/#/p5/save
    • Then we stamp them over the main canvas via image() function within draw().
    • http://processing.org/reference/PGraphics.html / http://p5js.org/reference/#/p5/createGraphics
    • So I wonder if this simpler approach would be enough for your case? :-??
    • Multiple sketches are more appropriate for when we want diff. programs running at the same time.
  • Yes, I had been using just one canvas and swapping objects in and out for editing, etc. It was working well for the most. But I was having some problems thinking through the idea of saving /restoring images to the canvas. So, thanks for the lead on the graphics. I remember reading it, but it must not have sunk in. (The concrete in my head is getting fairly thick. :) )

  • edited February 2015
    • Glad that p5.Graphics meets your needs! :D
    • Remember that w/ 1 instance we don't need to prefix everything w/ s. or sketch..
    • Thus it's much less verbose and easier! :-bd

    const BG = 0100, FGA = [0xff, 0, 0], FGB = [0, 0, 0xff];
    const FPS = 10, QTY = 2, A = 0, B = 1;
    const graphs = Array(QTY);
    
    function setup() {
      createCanvas(800, 600) //.parent('m-canvas-shape');
      frameRate(FPS).smooth().imageMode(CORNER);
    
      for (var i = 0; i != QTY; ++i)
        (graphs[i] = createGraphics(width>>1, height))
          .ellipseMode(CENTER).strokeWeight(2).stroke(0);
    }
    
    function draw() {
      background(BG);
      complexGraph(graphs[A], FGA), complexGraph(graphs[B], FGB);
      image(graphs[A], 0, 0), image(graphs[B], width>>1, 0);
    }
    
    function mousePressed() {
      var idx = mouseButton == LEFT? A : B;
      save(graphs[idx], 'canvas' + idx
        + '.[' + nf(frameCount, 4) + '].jpg');
    }
    
    function complexGraph(pg, c) {
      pg.background(0);
      pg.fill(c);
      pg.ellipse(pg.width>>1, pg.height>>1, pg.width>>2, pg.height>>1);
    }
    
  • Thanks much. This is very helpful.

  • Should I mark this discussion as "answered"?? Or does somebody else do that??

  • edited February 2015

    In order to mark as "answered", the thread gotta be of type "Question" instead of "Discussion".
    Unfortunately after some recent upgrade fixes, that feature seemed to have disappeared! =(

  • Finally got my head wrapped-around your code example above. I think it's going to work out really well. Opens a lot of new avenues. I'm so excited I'll probably have problems falling asleep tonight!

Sign In or Register to comment.