We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm having some scope issues when I attempt to use p5.js with Browserify.
I have browserify-shim transforming global:p5 to a p5 variable I can require, which I'm doing. Most methods work great if I have a structure like this:
var p5 = require('p5');
var newp5 = new p5(function(sketch) {
sketch.setup = function() {
img = sketch.loadImage('/path/to/img');
}
}, 'dom-elem');
The problem I'm encountering is that certain methods, i.e. the methods that seem to only work when called via dot notation, don't work inside Browserify. So, for example, where I might normally use:
x = 100;
y = 90;
img.get(x,y);
to get pixel data for those coordinates in the image, I can't when using Browserify - I get an "undefined" error. I'm sure this is just an issue of scope - the dot notation must be stringifying some variable along the way, but I can't figure out the correct syntax.
Answers
Ah, so I figured this out - it's not a scope issue at all, but rather an issue with the time it takes to load the image from within Browserify vs from without. Moving all my functionality inside the loadImage success callback fixed the issue:
works like a champ.
Dunno much about browserify and other similar JS loaders.
But AFAIK, when we don't pass a "sketch" function to p5's constructor, it assumes it's in "global" mode and copies everything to JS' window:
https://GitHub.com/processing/p5.js/blob/master/src/core/core.js#L441
The problem as you noticed, that code block is hardwired to
window[p]
.Perhaps you should try your luck there and request some new p5's constructor object parameter to replace default window: [-O< https://github.com/processing/p5.js/issues
Mention this forum thread so they have a better idea what's being asked. :-\"
Oh, I thought you were trying to emulate "global mode" via browserify w/o actually use the regular "instance mode".
Seems like you were just avoiding creating even 1 single variable in the global scope.
Just know that we don't need any variables in order to to call p5's constructor.
Just a simple
new p5( function(p) { } )
is enough to ignite it. No browserify is needed! :-@Yeah, I'm already using browserify, and I need all my site's JS to be in browserify so I'm copying the window.p5 object into browserify's closure which is why I have to pass a variable in the constructor - otherwise none of the methods work at all. Initially I couldn't figure out why my proof of concept worked great but the same code inside browserify didn't, and I thought it was a scope issue but it turns out that loadImage takes longer to execute inside browserify's closure and so my img variable was undefined. Moving all the code to be executed to inside the loadImage success callback fixed the issue.
Since you were asking about browserify, I haven't paid attention you were calling loadImage() inside setup() w/o passing a callback to it: b-( http://p5js.org/reference/#/p5/loadImage
Framework p5js provides a preload() callback so we can load resources w/o passing callback parameters to them: *-:) http://p5js.org/reference/#/p5/preload
In short, your "bug" had nothing to do w/ browserify but lacking of callbacks or preload().
In some cases, loadImage() can execute its task fast enough that it ends up working w/o a callback.
But that it's unpredictable behavior and we shouldn't rely on it! [-X