How can I integrate an app made with create-react-app with p5.js, with a specific goal to make sound visualization that responds to played sound?

Viewed 35

I have read a good number of related posts, but I feel they are not exactly giving me the required solution.
I want to implement in React, the following p5.js JavaScript code that I have written following this tutorial on YouTube => https://www.youtube.com/watch?v=uk96O7N1Yo0:

let sound;
let fft;
let image;
let particles = [];

function preload() {
  sound = loadSound("sound-path.mp3");
  image = loadImage("image-path.jpg");
}

function setup() {
  createCanvas(windowWidth, windowHeigh);
  angleMode(DEGREES);
  imageMode(CENTER);
  rectMode(CENTER);
  fft = new p5.FFT(0.3);

  image.filter(BLUR, 12);
  noLoop();
}

function draw() {
  background(0);
  stroke(255);
  strokeWeight(3);
  noFill();

  translate(width / 2, height / 2);

  fft.analyze();
  amp = fft.getEnergy(20, 200);

  push();
  if (amp > 230) {
    rotate(random(-0.5, 0.5));
  }

  image(image, 0, 0, width + 100, height + 100);
  pop();

  let alpha = map(amp, 0, 255, 180, 150);
  fill(0, alpha);
  noStroke();
  rect(0, 0, width, height);

  stroke(255);
  strokeWeight(3);
  noFill();

  let wave = fft.waveform();

  for (let t = -1; t <= 1; t += 2) {
    beginShape();
    for (let i = 0; i <= 180; i += 0.5) {
      let index = floor(map(i, 0, 180, 0, wave.length - 1));
      let radius = map(wave[index], -1, 1, 150, 350);

      let x = radius * sin(i) * t;
      let y = radius * cos(i);
      vertex(x, y);
    }
    endShape();
  }

  let particle = new Particle();
  particles.push(particle);

  for (let i = particles.length - 1; i >= 0; i--) {
    if (!particles[i].edges()) {
      particles[i].update(amp > 230);
      particles[i].show();
    } else particles.splice(i, 1);
  }
}

function mouseClicked() {
  if (sound.isPlaying()) {
    sound.pause();
    noLoop();
  } else {
    sound.play();
    loop();
  }
}

// Particles around the Wave
class Particle {
  constructor() {
    this.position = p5.Vector.random2D().mult(250);
    this.velocity = createVector(0, 0);
    this.acceleration = this.position.copy().mult(random(0.0001, 0.00001));
    this.width = random(3, 5);
    this.color = [random(200, 255), random(200, 255), random(200, 255)];
  }

  update(condition) {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    if (condition) {
      this.position.add(this.velocity);
      this.position.add(this.velocity);
      this.position.add(this.velocity);
    }
  }

  edges() {
    if (
      this.position.x < -width / 2 ||
      this.position.x > width / 2 ||
      this.position.y < -height / 2 ||
      this.position.y > height / 2
    )
      return true;
    else return false;
  }

  show() {
    noStroke();
    fill(this.color);
    ellipse(this.position.x, this.position.y, this.width);
  }
}

I have the following component in which I want that implementation of this sound visualization to happen:

import React from "react";
import { FormInput } from "../Forms/Form";
import "./Visualization.css";

const Visualization = () => {
  // TODO: Implement p5.js to create visualization as in the linked video
  const handleChange = () => {
    // Play the selected audio file in that input
  };
  return (
    <div className="visualizer-canvas-container">
      <canvas id="landing-visualizer-canvas"></canvas>
      <audio id="landing-audio-controls" controls />
      <FormInput
        accept="audio/*"
        id="file-upload"
        onChange={handleChange}
        type="file"
      />
    </div>
  );
};

export default Visualization;
0 Answers
Related