1

I want to make a JavaScript animation take 5 seconds to complete using requestAnimationFrame().

I don't want a strict and precise timing, so anything close to 5 seconds is OK and I want my code to be simple and readable, so solutions like this won't work for me.

My question is, is it safe to assume most browsers render the page at 60 fps? i.e. if I want my animation to take 5 seconds to complete, I'll divide it to 60 * 5 = 300 steps and with each call of function draw() using requestAnimationFrame(), draw the next step of animation. (Given the fact the animation is pretty simple, just moving a colored div around.)

By the way, I can't use jQuery.

Edit: Let me rephrase the question this way: Do all browsers 'normally' try to render the page at 60 fps? I want to know if Chrome for example renders at 75 fps or Firefox renders at 70 fps.

(Normal condition: CPU isn't highly loaded, RAM is not full, there are no storage failures, room is properly ventilated and nobody tries to throw my laptop out the window.)

Community
  • 1
  • 1
Behdad
  • 941
  • 12
  • 23
  • 1
    No it's very unsafe even. You have no idea how the JavaScript engine is performing. Even on lower programming languages you can't really dictate FPS precisely as CPU/GPU cycles always bump a little based on the overal system load. –  Mar 22 '15 at 09:00
  • 'Little' bumps don't matter to me. As long as the rendering rate remains between 55 and 65 fps, it's ok. Also, I don't care about some extreme conditions (such as very high CPU load). Assume I'm running my code in a normal condition with a good browser. – Behdad Mar 22 '15 at 09:10
  • 4
    If you're *assuming* a stable system, you just need to make sure you cap your FPS cycle on 60fps. If you don't cap it, it will just go faster and faster until it burns all resources. The nuance you put on "I just want it to stay between 55-60fps"; that's an issue. There are 1001 factors that might cause a JavaScript engine to drop it's FPS rate. Even CSS/HTML redraws can cause such strain on the browser that it will drop the JS-engine's performance. Just please keep in mind that you can't dictate a computer's performance, only ask it to abide if possible. –  Mar 22 '15 at 09:16
  • Everything higher than 25 fps will be recognized as continous move (unless you're a spider). What is the reason for forcing 60 fps? – Axel Amthor Mar 22 '15 at 09:42
  • @AxelAmthor I just want to control the time it takes my animation to complete. I just wanted to know whether I can safely assume the frame rate is normally around 60 fps. – Behdad Mar 22 '15 at 09:44
  • You can't control both number of frames and time, see comments. As you don't stream (which would give the ability to the renderer to skip frames), all iterations need to be executed. Thus, the time depends on the renderers speed. Or, you give a certain maximum time and the number of frames shown is left to the renderer. – Axel Amthor Mar 22 '15 at 09:52

4 Answers4

2

Relying on 60 frames per second is very unsafe, because the browser isn't always in the same conditions, and even if it tries to render the page at the maximum fps possible, there's always a chance of the processor/cpu/gpu being busy doing something else, causing the FPS to drop down.

If you want to rely on FPS (although I wouldn't suggest you so), you should first detect the current fps, and adjust the speed of your animation frame per frame. Here's an example:

var lastCall, fps;

function detectFps() {
    var delta;

    if (lastCall) {
        delta = (Date.now() - lastCall)/1000;
        lastCall = Date.now();
        fps = 1/delta;
    } else {
        lastCall = Date.now();
        fps = 0;
    }
}

function myFunc() {
    detectFps();

    // Calculate the speed using the var fps
    // Animate...

    requestAnimationFrame(myFunc);
}

detectFps(); // Initialize fps
requestAnimationFrame(myFunc); // Start your animation
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • I used your code to measure the average frame rate for calling `draw()` 100 times, and during about 15-20 runs, minimum average frame rate was 59.3 fps, and maximum average was 61.5 fps. (Using Safari 8.0.4), and this is totally ok for me. Why should I still measure the exact frame rate which I don't need?! (Although, as far as I know, this method doesn't take the time to execute the code itself into account, so it's not really accurate.) – Behdad Mar 22 '15 at 11:11
  • You should still measure the exact frame rate, because on older machines the frame rate drops drastically down (even under 20fps). Try to run an heavy program (e.g. a video rendering software) and open your browser at the same time, you'll see what I'm talking about. – Marco Bonelli Mar 22 '15 at 11:16
  • I said in an earlier comment that everything is normal (low CPU load, good browser, ...) but already edited my question to reflect this. – Behdad Mar 22 '15 at 11:25
  • @Behdad so your script will run ONLY on your PC? – Marco Bonelli Mar 22 '15 at 11:56
  • No, but how is it relevant to the question? Shouldn't a browser try to do the same thing on every machine it's run? BTW, I run my code on Chrome 41 and although I got an average of 68 fps sometimes, but it's not a problem and I still think Chrome _tries_ to render the page at 60 fps. – Behdad Mar 22 '15 at 12:08
  • 1
    @Behdad If your code doesn't run only on your machine, then you **cannot** trust the FPS to be 60. Period. You're asking if it is safe to assume 60fps for rendering, and the answer is **no**. You cannot say *"everything is normal"* because you do not know anything of the PCs that your code is going to run on. – Marco Bonelli Mar 22 '15 at 12:13
2

It depends on the GPU and monitor combination. I have a good GPU and a 120 hertz monitor, so it renders at 120 fps. During the render, If I move to 60 hertz monitor, it will max out at 60 fps.

Another factor, that happens in some browsers/OS, is the iGPU being used instead of the discrete gpu.

Mário
  • 1,603
  • 14
  • 24
0

As already stated by others, it isn't.

But if you need to end your animation in approximately 5 seconds and it's not crucial not to miss any frames in the animation, you can use the old setTimeout() way. That way you can miss a target by a few milliseconds, and some of the frames in your animation will be skipped (not rendered) because of the fps mismatch, but this can be a "good enough" solution, especially if your animation is simple as you state it is, there's a chance that users won't even see the glitch.

Zemljoradnik
  • 2,672
  • 2
  • 18
  • 24
  • Thanks for the answer, but I must use `requestAnimationFrame()`, so using `setTimeout()` is off the table. – Behdad Mar 22 '15 at 11:13
0

It's not safe to assume everyone can handle animation.

People will have different needs.

A lot of common animations, and common web design practices, give me awful migraines, so I set my browser to 1 frame per second to kill the animation without causing too much fast flashing.

Marja E
  • 21
  • 6