Draw() Does not Recognize P5 Functions Called from Within an Eternal Prototype

In my web project I am using p5.js to create a sketch. I have included in my project two other javascript files with each containing a prototype. here is what these external prototype looks like:

gridBlock:

var gridBlock = function(x, y) {
  this.xLoc = x;
  this.yLoc = y;
}

gridBlock.prototype.getXloc = function() {
  return this.xLoc;
}

gridBlock.prototype.setXloc = function(newXloc) {
  this.xLoc = newXloc;
}

gridBlock.prototype.getYloc = function() {
  return this.yLoc;
}

gridBlock.prototype.setYloc = function(newYloc) {
  this.yLoc = newYloc;
}

grid:

 var grid = function(xStart, yStart, gWidth, gHight, blockWidth) {
   this.xStart = xStart;
   this.yStart = yStart;
   this.gWidth = gWidth;
   this.gHight = gHight;
   this.blockWH = blockWidth; // width and hight of a grid block

   this.numRows = this.gWidth / this.blockWH;
   this.numCols = this.gHight / this.blockWH;

   this.blocks = new Array(this.numRows);
   for (i = 0; i < this.numRows; i++) {
     this.blocks[i] = new Array(this.numCols);
   }

   for (i = 0; i < this.numRows; i++) {
     for (j = 0; j < this.numCols; j++) {
       this.blocks[i][j] = new gridBlock(this.xStart + i * this.blockWH, this.yStart + j * this.blockWH);
     }
   }
 }

/*
  strokWeight = in pixels
  strokeColor = 'red', 50, color(10,20,10)
  blockColor = 'red', 50, color(10,20,10)
*/
 grid.prototype.drawGrid = function(strokeWeight, strokeColor, blockColor) {
   for (i = 0; i < this.numRows; i++) {
     for (j = 0; j < this.numCols; j++) {
       fill(blockColor);  // ERROR
       strokeWeight(strokeWeight); 
       stroke(strokeColor);
       rect(this.blocks[i][j].getXloc(), this.blocks[i][j].getYloc(), this.blockWH, this.blockWH);
     }
   }
 }

in my sketch.js file, I create an instance of grid, then I call drawGrid() to draw the grid from within the draw function in sketch.js:

var mySketch = function (s) {

  var myCanvas;
  var myGrid;

  s.preload = function () {

  };

  s.setup = function () {
    var xWidth = 800;
    var yHight = 600;

    myCanvas = s.createCanvas(xWidth, yHight);

    myGrid = new grid(10, 100, 200, 200, 50);

    s.imageMode(s.CENTER);
  };

  s.draw = function () {

    s.background(0, 102, 153);

    myGrid.drawGrid(1,'red','black');

  };

};

var mySketch_one = new p5(mySketch, 'myContainer2');

When I run my project, I get the following error: TypeError: fill is not a function.

this happends at the third line of my grid.prototype.drawGrid method. (line 31)

Can somebody help me to figure this out.

I appreciate your help!

Tagged:

Answers

  • edited September 2015
    • Your 2 classes are defined outside p5's sketch.
    • Therefore they can't invoke any p5's API, but only those few which happen to be static.
    • p5's fill() method isn't static. Thus we need the p5 instance's reference in order to invoke it.
    • That's why you need to request p5's reference as an extra constructor's parameter.
    • And rely on it for any p5's API member accesses! :-B
  • @GoToLoop: Thanks for the information!

    I am new to both p5.js and the JavaScript. Can you give me an example on how to request p5's reference as an extra constructor's parameter?

  • edited September 2015 Answer ✓

    That's the same technique any Java Mode 3rd-party library does.
    And the same approach used in your own sketch, where parameter s holds sketch's reference.
    You just need to pass that very same reference to any external classes needing to access p5's API:

    function grid(sketch, xStart, yStart, gWidth, gHeight, blockWidth) {
      this.p = sketch;
      // ...
    }
    
    grid.prototype.drawGrid = function(strokeWeight, strokeColor, blockColor) {
      // ...
      this.p.fill(blockColor);
      // ...
    }
    
    var myGrid;
    s.setup = function() {
      // ...
      myGrid = new grid(this, 10, 100, 200, 200, 50);
      // ...
    }
    
  • Thank you so much!

Sign In or Register to comment.