问题
I am using an npm, webpack, babel environment to write an application with p5.js. To be able to have the sketch as a module, I have the sketch in instance mode and import the library and add-ons as modules:
import p5 from 'p5';
import 'p5/lib/addons/p5.sound';
import 'p5/lib/addons/p5.dom';
Then I load them to the window inside my sketch:
const sketch = (p5) => {
window.p5 = p5;
...
}
new p5(sketch);
When I try to use:
amp = new p5.Amplitude()
I get a 'p5.Amplitude is not a constructor' error. My prediction is that there is a conflict between naming the library p5 on the window and using the constructors from the library that use p5.something like p5.Amplitude, p5.Vector, p5.Soundfile. I have not been able to find a workaround to using these objects or constructors within instance mode. I am however able to use the methods from these objects that do not require a constructor. For example, loadSound()
is a method of p5.Soundfile. The following works:
sound = p5.loadSound('assets/sound.wav)
but when I try console.log(p5.SoundFile)
I get undefined.
I am lost!
回答1:
I'm not a JavaScript expert, but your syntax doesn't match the syntax on the instance mode page.
Specifically, what are you doing here?
const sketch = (p5) => {
window.p5 = p5;
...
}
new p5(sketch);
Compare that to the syntax on the instance mode page:
var sketch = function (p) {
var gray = 0;
p.setup = function () {
p.createCanvas(600, 400);
};
p.draw = function () {
p.background(gray);
p.rect(p.width/2, p.height/2, 200, 200);
};
p.mousePressed = function () {
gray = (gray + 16) % 256;
};
};
new p5(sketch);
It looks like your code is redefining the p5
variable, which is going to cause the kinds of problems you're seeing. I would rewrite your code to no longer redefine the p5
variable, and use the syntax from the instance mode page instead:
var sketch = function(p) {
//your code here
//but don't change the p5 variable!
}
new p5(sketch);
回答2:
You're correct that you're overwriting the p5
class provided by the library with the instance that's provided to your code upon construction.
This should work:
import p5 from 'p5';
import 'p5/lib/addons/p5.sound';
const sketch = (p5) => {
window.myp5 = p5;
p5.setup = () => {
//whatever
};
p5.draw = draw;
}
function draw() {
//methods hang off the instance:
const mysound = myp5.loadSound("/path/to/sound.mp3");
//constructors hang off the class:
const amp = new p5.Amplitude()
}
new p5(sketch);
Note that myp5
is available to the draw function because of the assignment at the beginning of the sketch
function. Also note that you shouldn't need to import the addons.
回答3:
I think I figured out our problems. You need to use p5.sound library from version 0.9.0 and place it in your project's directory. I explain more fully in my answer here:
How to import and utilize P5.Sound in Vue?
来源:https://stackoverflow.com/questions/39693208/using-p5-sound-js-in-instance-mode-p5-amplitude-not-a-constructor