Eloquent Javascript: DOM Animation snippet

227 views Asked by At

I'm trying to understand everything that is happening in this little code example in Eloquent Javascript: The Document Object Model (Chapter 13), but I'm not clear on where exactly the value for "time" is being passed into the animate() function before the function itself gets passed into requestAnimationFrame(). What exactly am I missing here?

<p style="text-align: center">
  <img src="img/cat.png" style="position: relative">
</p>

<script>
  var cat = document.querySelector("img");
  var angle = 0, lastTime = null;
  function animate(time) {
    if (lastTime != null)
      angle += (time - lastTime) * 0.001;
    lastTime = time;
    cat.style.top = (Math.sin(angle) * 20) + "px";
    cat.style.left = (Math.cos(angle) * 200) + "px";
    requestAnimationFrame(animate);
  }
  requestAnimationFrame(animate);
</script>
2

There are 2 answers

1
taxicala On BEST ANSWER

When you execute this line: requestAnimationFrame(animate);, the function animate will be called inside requestAnimationFrame and will get the time variable passed as an argument. Something like this (narrowed and rough):

function requestAnimationFrame(callback) {
    var time = getTime();
    callback(time); //Where callback is your `animate` function
};

Of course that requestAnimationFrame does not look at all like the function above, but this is just to illustrate where time comes from.

As per the documentation:

The callback method is passed a single argument, a DOMHighResTimeStamp, which indicates the current time when callbacks queued by requestAnimationFrame begin to fire. Multiple callbacks in a single frame, therefore, each receive the same timestamp even though time has passed during the computation of every previous callback's workload. This timestamp is a decimal number, in milliseconds, but with a minimal precision of 1ms (1000 µs).

Read more here: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

2
The Spooniest On

It's not being passed in beforehand.

The line function animate(time) { doesn't call anything: instead, it creates a function named animate, which takes in a single argument called time.

The specification for requestAnimationFrame states that the callback always gets passed a single argument, which equals the number of milliseconds (or fractions thereof) since the page first loaded. So time doesn't get passed in before the function gets passed to requestAnimationFrame: instead, it gets passed in every time requestAnimationFrame sets up its call to the callback.