timestamp in callback requestAnimationFrame function

When functions with parameters are called without arguments for those parameters, those parameters are set to undefined. So in that first gameLoop() call, timestamp is going to be undefined - something you don’t want since that will cause your calculations to result in NaN. In fact that first call (and second, for that matter) should not work.

This is how requestAnimationFrame() works. Just like callbacks you send to addEventListener() get called with an Event argument, so too do requestAnimationFrame() callbacks get called with a timestamp argument, at least when the function is called through requestAnimationFrame() and not manually as is the case with the gameLoop() at the bottom.

You can get the value of timestamp using performance.now(), so if you want to simulate that when calling gameLoop() yourself, you can.

gameLoop(performance.now());

Or, you can skip calling it yourself and pass it into requestAnimationFrame() so it will automatically get called with it.

requestAnimationFrame(gameLoop); // instead of gameLoop()