To detail my comment above, you could do something like this:
var xOffset = 0;
// time delay vars
// current time "snapshot" (imagine pressing the lap time button)
var time;
// the interval to wait between time "snapshots": 2s (2000 milliseconds) in this case
var wait = 2000;
function setup() {
createCanvas(300, 300);
//store the current time
time = millis();
}
function draw() {
background(220);
//check if the difference between now and the previously stored time
// is greater than the wait interval
if(millis() - time >= wait){
console.log(wait, "ms passed");
//if it is, do something
xOffset = xOffset + 1.5;
//also update the stored time
time = millis();
}
circle(xOffset, 150, 60);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
I'm not sure what the main purpose of the delay is:
- is it to slow things down for debugging purposes
- is to go into a series a states (e.g. ball moves up for 2s, then right
2s, etc.),
- is to animate/smoothly interpolate between two positions within a given
time ?
Maybe something else completely ?
If you simply want to slow things down, perhaps it might be simpler to adjust the frameRate()
:
var xOffset = 0;
function setup() {
createCanvas(300, 300);
// update 1 frame every two seconds => 0.5 fps
frameRate(0.5);
}
function draw() {
background(220);
xOffset = xOffset + 1.5;
circle(xOffset, 150, 60);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
Processing still has a delay()
function, but p5.js doesn't.
Personally I'm not a fan of blocking behaviour like this and prefer the millis()
options even though it's more verbose. That being said, if the program/demo you write is super simple delay()
might just be enough.
Even if delay()
is missing you could use js setTimeout()
with a Promise
, but that's getting into more advanced JS as Paul already mentioned:
var xOffset = 0;
function setup() {
createCanvas(300, 300);
// prevent p5's default draw() updates
noLoop();
}
function draw() {
background(220);
xOffset = xOffset + 1.5;
circle(xOffset, 150, 60);
// wait 2s then call draw() manually
delay(2000).then(draw);
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
Now, if you want to create a smooth animation from a start x offset to an end offset in a set amount of seconds you'd need a different approach.
You can find a p5.js example at the of this answer:
var startTime;
var duration = 2000;
var startValue = 0;
var endValue = 300;
var currentValue = startValue;
function setup(){
createCanvas(300, 300);
textAlign(RIGHT);
startTime = millis();
}
function draw(){
background(255);
moveCircle();
drawCircle();
}
function drawCircle() {
circle(currentValue, 150, 60);
}
function moveCircle(){
var progress = (float)(millis()-startTime)/duration;//millis()-startTime = difference in time from start until now
if(progress < 1.0) currentValue = startValue + (endValue * progress);//the current value is the final value scaled/multiplied by the ratio between the current duration of the update and the total duration
}
function mousePressed(){//reset value and time
currentValue = startValue;
startTime = millis();
}
function keyPressed(){//update duration
if(key == '-') if(duration > 0) duration -= 100;
if(key == '=' || key == '+') duration += 100;
console.log("duration: " + duration);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
And if you're comfortable using external libraries you could simply use a tweening library such as gsap:
var x = 0;
function setup(){
createCanvas(300, 300);
// animate "this" global object's x property to 300 in 2 seconds
gsap.to(this, {x: 300, duration: 2});
}
function draw(){
background(255);
circle(x, 150, 60);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/gsap.min.js"></script>
Notice the animation has a bit of easing (default ease out) which could be nice.