1
var video;
var snapshots = [];
var readyCheck = false;
var button;

function setup() {
    createCanvas(800, 600);
    background(0);
    video = createCapture(VIDEO, ready);
    video.size(200, 150);
}

function ready() {
    readyCheck = true;
    console.log('work');
}

function draw() {
    var w = 200;
    var h = 150;
    var x = 0;
    var y = 0;

    if (readyCheck) {
        for (var i = 0; i < 100; i++) {
            // use setTimeout() to wait for 2 seconds
            setTimeout(function() {
                snapshots[i] = video.get();
                image(snapshots[i],x, y);
                x += w;
                if (x >= width) {
                    x = 0;
                    y += h;
                }
            }, 2000);
        }
    }
}

my purpose is taking pictures from the webcam after specific time. So I use the setTimeout() in JS. I expect pictures will appear on the canvas every 2 seconds in a row.

when entering the for part, the code will wait 2 seconds and capture the image from webcam and display it.

but my situation is that all the picture appear on the canvas at the same time.

SoulerTsai
  • 87
  • 2
  • 10

1 Answers1

3

You need to take a step back and understand how the draw() function and the setTimeout() functions work.

  • The draw() function is automatically called 60 times per second. You can adjust this by calling the frameRate() function or the noLoop() function. More info is available in the reference.

  • The setTimeout() function sets up a callback function that is automatically called after some duration, in your case 2 seconds.

So, what your code is doing is setting up 100 callback functions that will all fire in 2 seconds- and it's doing this 60 times per second! So in 1 second, you'll have 6000 functions that will start firing 2 seconds later! This is almost definitely not what you want.

P5.js already has its own timing mechanism in the draw() function that's called 60 times per second, so it seems a little weird to use the setTimeout() function inside P5.js code. Instead, you should probably set up your own timing using the frameCount variable or the millis() function.

Here's an example that shows a random color every second:

function setup() { 
  createCanvas(200, 200);
} 

function draw() { 
  if(frameCount % 60 == 0){
   background(random(256), random(256), random(256));
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.min.js"></script>

This code uses the frameCount variable and the % modulus operator to check whether 60 frames have passed, and if so, it sets the background to a random color. You'll want to do something similar.

Like I said above, more info about all of this can be found in the reference.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • Thanks for your answer! It helps a lot !!! But my confusion still exists. my thought is that when entering the for loop, the `setTimeout()` is triggered, then wait for 2 seconds, drawing the pictures and entering another next step in the for loop, and waiting for 2 seconds, then next pictures. on and on. why you said it will be all triggered at the same time? thanks you~ – SoulerTsai Aug 03 '17 at 00:21
  • 1
    @SoulerTsai Please read the documentation on the `setTimeout()` function, as it doesn't work at all like what you're describing. – Kevin Workman Aug 03 '17 at 00:57
  • Ok, I know what I misunderstood. At first I thought `setTimeout()` is more like delay, so I think it will some kind of "waiting". But I am wrong in the end. – SoulerTsai Aug 03 '17 at 07:19