javascriptanimationrotationreal-timeflower

how to control flower animation?


let angle = 0
let mic; 
let fft;

function setup() {
  createCanvas(400, 400);
  mic = new p5.AudioIn(); //AUDIO SETTING
  mic.start();
  
  fft = new p5.FFT();
  fft.setInput(mic);
}


function draw() {
  background(220);
  
  petals();
  noStroke(); 
  fill(255);
  ellipse(200, 200, 100, 100); // the center of flower 
  
  function petals() { 
    push()
    translate(200, 200); // flower leaves
     rotate(angle);
    noStroke();
    const colors = ['magenta','red', 'orange','#7fff00','#0f0','#0ff','blue','#bf49ff'];
    let waveform = fft.waveform();
    
    for (let i=0; i<8; i++) {
      let y = 100 -  waveform[i]*100;   //i want those flower leaves to rotate responds to mic
      let color = colors[i];
      fill(color)
      ellipse(100, 0, 200, 60)
      rotate(radians(45));
     angle = angle +0.003
    }
    pop()

  }
}

//I want my leaves to rotate in response to the loudness of real-time sound input from the microphone. I think I should use pff but... it doesn't work. Please help me TT


Solution

  • Below is a design with a fake calculation transforming FFT output to a rotational rate. (real mic input won't run in snippets)

    The point is to: (1) demonstrate how to rotate the drawing, and (b) show how untangle the FFT math and the graphics.

    EDIT

    I tried the p5 sound library for the first time. Some things to note: (1) it won't work in stack overflow snippets, since the snippet can't access the client mic. (2) remember to import the p5 sound add-on, shown in the html below, (3) if you just want total amplitude, there's no need for FFT, just get the mic level from the p5 mic. (4) I made up a function that works ok on my local machine, clipping the low and high amplitudes (though 1.0 is probably the max output by default).

    let mic;
    let rotation = 0;
    
    function setup() {
      createCanvas(400, 400);
      mic = new p5.AudioIn();
      mic.start();
      userStartAudio();
    }
    
    function rotationalRateForMicLevel(micLevel) {
      // in my experiment, low mic levels are ~0.01, high levels ~1.0;
      micLevel = Math.min(1.0, Math.max(0.5, micLevel));
      return radians(15) * micLevel
    }
    
    function petals() { //flower leaves -> I wanna fill them with rainbow colors each in shortly
      push()
      translate(200, 200);
    
      const micLevel = mic.getLevel();
      const rotationalRate = rotationalRateForMicLevel(micLevel)
      rotation += rotationalRate;
      rotate(rotation);
      
      noStroke();
      const colors = ['red', 'yellow', 'blue', 'green'];
      for (let i = 0; i < 8; i++) {
        let color = colors[i % 4];
        fill(color)
        ellipse(100, 0, 250, 60)
        rotate(radians(45));
      }
      pop()
    }
    
    function draw() {
      background(220);
      petals();
      noStroke(); //the center of flower = white circle
      fill(255);
      ellipse(200, 200, 130, 130);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/addons/p5.sound.js"></script>