Using p5.sound.js in instance mode: 'p5.Amplitude() not a constructor'

冷暖自知 提交于 2020-05-27 02:34:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!