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?