Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Ask Question
I created an animation using
requestAnimationFrame
. Works fine in Windows Chrome and IE; Safari (tested Safari 6 and 7) breaks. It turns out that rAF get a
DOMHighResTimestamp
rather than a
Date
timestamp. That's all fine and good, and what I expected, as it's now part of the spec. However, as far as I've been able to find, there's no way to get the current
DOMHighResTimestamp
(i.e.
window.performance
is not available, even with a prefix). So if I create the start time as a
Date
timestamp, it behaves radically wrong when I try to determine progress within the rAF callback (very small negative numbers).
If you look at
this
JSBin on Safari, it won't animate at all.
In
this
JBin, I've made a change to "skip" the first frame (where the
time
parameter is
undefined
), so that
startTime
gets set to the
time
parameter on the next frame. Seems to work, but skipping a frame seems a bit crappy.
Is there some way to get the current
DOMHighResTimestamp
in Safari, given the lack of
window.performance
? Or alternately, force rAF into some sort of legacy mode that forces it to get a Date timestamp instead?
Does anyone know why Safari has this inconsistency, where it provides the parameter in a format that you can't get at any other way?
Performance.now() is only a recommendation as of now.
https://developer.mozilla.org/en-US/docs/Web/API/Performance.now()
I can only assume it's a matter of time before it's official, seeing as how everyone but Safari has it built in.
Besides that fact use this to your advantage. Since you know requestAnimationFrame returns a DOMHighResTimestamp use that for your timing.
Game.start = function(timestamp){
if(timestamp){
this.time = timestamp;
requestAnimationFrame(Game.loop);
}else{
requestAnimationFrame(Game.start);
Game.loop = function(timestamp){
Game.tick(timestamp);
... your code
requestAnimationFrame(Game.loop);
Game.tick = function(timestamp) {
this.delta = timestamp - this.time;
this.time = timestamp;
What I do here, is call Game.start which will begin the loop (I've run into situations where the timestamp was undefined so we try until we get something valid). Once we get that we have our base time and since RAF is going to return a timestamp our tick function never has to call Date.now or performance.now as long as we pass it the timestamp returned by requestAnimationFrame.
–
–
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.