0

i am trying to build some p5.js animation app from a tutorial i found. The tutorial has the code structure below. I want to dynamically change the system variables like topSpeed and others. So i am trying to implement something to the effect of

after 2 seconds set topSpeed to 80

I tried to set global variables like

    var totalframecount = 0
    var topSpeedval = 500
    var lifeSpanval = 1000
    var flowOffsetval = 0
    var directionval = 0
    var forceval = 0
    var flowval = 0

and then use

setInterval(function(){ 

   
      topSpeedval = 90

}, 1000)

the time interval changed the value but the effect of the changed does not show on the canvas. The main code is below

      // This script is dependant on p5.js
    var gui = new dat.GUI({name: 'GUI'});

    var system = {
      text: "HELLO",
      flow: 0,
      topSpeed: 500,
      lifeSpan: 1000,
      flowOffset: 0,
      gravity:{
        direction:90,
        force:0
      }
    };

    var f_b = gui.addFolder('Base');
    f_b.open();
    f_b.add(system, "text")
      .onChange(init)
      f_b.add(system, 'flow', 0, 100);
      f_b.add(system, 'topSpeed', 10, 1000);
      f_b.add(system, 'lifeSpan', 100, 2000);
      f_b.add(system, 'flowOffset', 0, Math.PI*2);

    var f_g = gui.addFolder('Gravity');
    f_g.open();
    f_g.add(system.gravity, "direction").min(0).max(360)
      .onChange(setGravity)
      f_g.add(system.gravity, "force").min(0).max(100)
        .onChange(setGravity)




    let colors = [
      '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5',
      '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4CAF50',
      '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800',
      '#FF5722'
    ];
    class Particle {
      constructor(x, y, size, index) {
        this.base_size = size;
        this.index = index || 0;
        this.spawn = createVector(x, y);
        this.init();
      }
      init() {
        this.size = this.base_size * random(0.5, 1.5);

        this.start = millis();
        this.position = this.spawn.copy();
        this.velocity = createVector(0, 0);
        this.acceleration = createVector(0, 0);
        this.duration = system.lifeSpan * random(0.2,1.2);
        this.drag = random(0.9, 1);
        this.addForce(
          new p5.Vector.fromAngle(random(TWO_PI), random(10))
        );
        this.color = random(colors);

      }
      display() {
        let s = 1;
        if (millis() - this.start < this.duration * 0.1) {
          s = map(millis() - this.start, 0, this.duration * 0.1, 0, 1);
        } else if (millis() - this.start > this.duration * 0.5) {
          s = map(millis() - this.start, this.duration * 0.5, this.duration, 1, 0);
        }
        fill(this.color);
        circle(this.position.x, this.position.y, this.size * s * map(this.velocity.mag(),0,system.topSpeed,0.5,1.2));
      }
      update() {
        this.velocity.add(this.acceleration);
        this.velocity.limit(system.topSpeed);
        this.velocity.mult(this.drag);
        this.position.add(this.velocity.copy().mult(1 / _targetFrameRate));
        this.acceleration.mult(0);
        if (this.position.y > height || millis() - this.start > this.duration) {
          this.init();
        }
      }
      addForce(vector) {
        this.acceleration.add(vector);
      }
    }

    let particles = [], field = [], fieldStep,
      gravity;
    function setGravity(){
      gravity = new p5.Vector.fromAngle(radians(system.gravity.direction),system.gravity.force);
    }
    function setup() {
      createCanvas(windowWidth, windowHeight);
      setGravity();
      init();
      frameRate(60);
      noStroke();
      colorMode(HSL, 100);
    }
    function windowResized() {
      resizeCanvas(windowWidth, windowHeight);
      init();
    }
    function init() {
      clear();
      fill(0);
      textSize(10);
      textStyle(BOLD);
      let text_box_width = min(width, 1200) * 0.8;
      let minSizeW = 12 / textWidth(system.text) * text_box_width;
      textSize(minSizeW);
      text(system.text, width / 2 - text_box_width / 2, height / 2);
      // Scan the canvas searching for black pixels
      // particles will spawn from there :)
      noFill();
      particles = [];
      let step = floor(max(width,height)/min(160,min(width,height)));
      let i = 0;
      for (let x = 0; x < width; x += step) {
        for (let y = 0; y < height; y += step) {

          let target_x = x + step / 2,
            target_y = y + step / 2;
          let alpha = get(target_x, target_y)[3];
          if (alpha > 0.5) {
            particles.push(new Particle(target_x, target_y, step * 3, i));
            i++;
          }
        }
      }
      field = {};
      clear();
      step = fieldStep = floor(max(width,height)/min(20,min(width,height)));
      i = 0;
      for (let x = 0; x < width; x += step) {
        for (let y = 0; y < height; y += step) {
          i++;
          let a = noise(i)*TWO_PI;
          field[`${x}-${y}`] = a;
          translate(x,y);
          rotate(a);
          rect(-step/4,-step/2,step/2,step)
          resetMatrix();
        }
      }

      clear();
    }

    function draw() {
      background(255);
      particles.forEach((particle, i) => {
        particle.addForce(gravity);
        // search field
        particle.addForce(
          new p5.Vector.fromAngle(
            field[`${particle.position.x - (particle.position.x%fieldStep)}-${particle.position.y - (particle.position.y%fieldStep)}`] + system.flowOffset,
            system.flow
          )
        );
        particle.update();
        particle.display();
       });
      }

    function download(url, filename){
        const anchor = document.createElement("a");
        anchor.href = url;
        anchor.download = filename || "download";
        anchor.click();
    };

    HME.createH264MP4Encoder().then(async encoder => {
        encoder.width = canvas.width;
        encoder.height = canvas.height;
        encoder.initialize();
  
        const frames = 100;
        for (let i = 0; i <= frames; ++i) {
          draw(i / frames);
          encoder.addFrameRgba(ctx.getImageData(0, 0, canvas.width, canvas.height).data);
          await new Promise(resolve => window.requestAnimationFrame(resolve));
        }
  
        encoder.finalize();
        const uint8Array = encoder.FS.readFile(encoder.outputFilename);
        download(URL.createObjectURL(new Blob([uint8Array], { type: "video/mp4" })))
        encoder.delete();
      })

How can I dynamically change animation values and have it immediately reload the updated value?

e.iluf
  • 1,389
  • 5
  • 27
  • 69
  • 1
    Are you actually using `var topSpeedval` in your interval callback? If so that is not going to update the global variable, it is only going to create an unused local variable with that value. You need to drop the `var` – Paul Wheeler Apr 18 '22 at 23:39
  • @PaulWheeler i actually did not use var – e.iluf Apr 19 '22 at 01:57
  • 1
    I also don't see any reference to topSpeedval in the "main code." Please update your question with a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), preferably as a [runnable Stack Snippet](https://stackoverflow.com/questions/67410651/how-do-i-include-a-runnable-p5-js-sketch-in-a-stackoverflow-question). – Paul Wheeler Apr 19 '22 at 06:10

0 Answers0