Extend p5.js function

I’d like to be able to extend the functionality of built-in p5.js functions, keeping the same name but adding some additional code. I don’t want to create my own version of p5.js, since maintaining that will be a pain. I think this is possible but can’t quite get my head around how to make it happen.

Let’s say I want to add the <canvas> dashed line functionality. Normally, I’d call line() like this:

line(x1,y1, x2,y2);

But I’d like to add optional arguments for dashed lines (the dash spacing and offset):

line(x1,y1, x2,y2, [10,5], 5);

I can make a function called line2() that would look like this:

function line2(x1,y1, x2,y2, dash, offset) {
  if (dash !== undefined) {
    drawingContext.setLineDash(dash);
    if (offset !== undefined) {
      drawingContext.setDashOffset = offset;
    }
  }
  line(x1,y1, x2,y2);
}

But this means I have to call line2() instead of line(). Not a huge deal but messy. Ideally, I’d like to create my own function called line() that just like the one above and calls the original line() inside it after changing the canvas settings. I’ve found a couple of SO posts that seem to point to this, but I can’t get them to work or they are meant for methods in classes.

Might not be possible but any pointers would be great! This is meant especially for my students, so switching to global mode or complicated hacks are probably more confusing than just creating a line2() function.

Method p5::line() is overloaded w/ 4 parameters for 2D & 6 parameters for 3D:
p5js.org/reference/#/p5/line

So my advice is to choose some other method name, for example dashedLine(), instead of overloading line() even more.

Library p5*js is itself a huge class named p5.

Therefore we can easily extend it by appending methods to its prototype{} object.

For example, the file adjustFrameSize.js appends 3 new methods to p5’s prototype{}: adjustFrameSize(), getDocWidth() & getDocHeight().

A 2nd example below appends method getVersion() to the library p5*js:

Given p5*js already got methods which control how line() is drawn, such as strokeWeight(), strokeJoin() & strokeCap(); a much better approach would be, instead of changing the original method p5::line(), creating a new 1 called p5::strokeMode() which would enable/disable dashed lines for all line() calls.

3 Likes

Thanks! I didn’t think about the 3D options, so you’re right it would probably get hairy trying to add more for 2D. Your suggestion about strokeMode() is nice though! In thise case, my only options would be to create a local function, roll my own version of p5, or submit a PR, right?

You can place it in some separate file which would be loaded within the “index.html” file after loading “p5.js”, just like I did in both my linked sketches.