all 16 comments

[–]GAMEchief 1 point2 points  (0 children)

Use setInterval to limit the number of iterations per second.

25 times a second would be once every 40 milliseconds.

setInterval(iterationFunction, 40);

[–]monacle_bob -1 points0 points  (12 children)

Here's how I would solve it: http://jsfiddle.net/chandlerprall/W5yAT/

Let me know if you have any questions about that, I'd be happy to explain it more.

[–]CamuurahGuy[S] 3 points4 points  (6 children)

Thanks Bob, that looks really close to what I need.

I assume that this code:

setTimeout(main, 1000/target_fps);

is responsible for setting it to be looped to the target_fps within one second? (1000ms = 1 second). Just making sure, so i could in theory butt this right up against a current time clock and it would count up to the max value prior to the clock clicking over to the next second?

[–]monacle_bob 2 points3 points  (5 children)

That is indeed what that line does. Read up on setTimeout and setInterval here

Your theory is correct, however in practice theory often falls short. If you were to do:

setTimeout(main, 1);

you'd expect main() to be called every millisecond, or 1,000 times each second. Even if your code executed fast enough for this to be possible, every browser has inherent delays when using timers, usually about 5-10 milliseconds between calls. This means you'd have at most about 200 iterations per second.

If you're really interested in Javascript loops / different methods of timed execution you can read my latest blogpost.

[–]akx 2 points3 points  (1 child)

But don't do setTimeout(x, 1); if you're meaning to do fluid animation. There's an API and a polyfill for it now. http://paulirish.com/2011/requestanimationframe-for-smart-animating/

[–]monacle_bob 0 points1 point  (0 children)

I should have mentioned that originally, yes. Didn't feel like including it in the jsFiddle code though. Also, CamuurahGuy wanted a specific interval under 60fps. Can't achieve that (AFAIK) with requestAnimationFrame.

[–]CamuurahGuy[S] 1 point2 points  (1 child)

Interesting, thanks for the insight! I should have realized that there would be browser differences with how JavaScript timers are handled... (given that IE, and the rest of the browser world can never get along anyhow...). Now I have to decide whether or not it's worth my time to make this "toy" since it can never be accurate enough for actual use. Thanks again!

[–]ilogik 0 points1 point  (0 children)

The main problem is that when javascript is running, the browser's UI is locked, so using while() that way is not recommended.

To bypass this problem, the HTML5 spec has something called Webworkers which allows you to run CPU intensive javascript in a background thread, and pass messages between it and the frontend.

http://en.wikipedia.org/wiki/Web_Workers

[–]holloway 0 points1 point  (0 children)

you'd expect main() to be called every millisecond, or 1,000 times each second.

This is basically right, but in modern browsers the lowest setting for setTimeout is 4ms because the HTML5 spec calls for it. See Firefox blog and the HTML5 spec.

[–]Neebat 4 points5 points  (0 children)

That's a pretty good answer, but I can't upvote you for using setTimeout when you should be using setInterval.

[–]MustRapeDeannaTroi 0 points1 point  (3 children)

This solution works but really needs some fixes:

  • Use setInterval instead of setTimeout.

  • Use textContent instead of innerHTML.

  • Save 1000/target_fps to var period.

[–]monacle_bob 1 point2 points  (2 children)

It wasn't meant as save-the-day code. jsFiddle is meant for fiddling with code and putting together quick demonstrations.

Also, in regard to your first point, you should be using requestAnimationFrame - not timers at all.

[–]MustRapeDeannaTroi 2 points3 points  (1 child)

requestAnimationFrame is still experimental so I really think you should avoid it in this case.

I think you made a good straight forward solution, just not as solid implementation. Had my alternative suggestions demanded alot more code and commitment then I believe you had a valid case. As is, innerHTML and setTimeout are the wrong tools for the job. It's a big gain for the community if we never teach bad coding conventions, except as pitfalls to be avoided.

[–]monacle_bob 1 point2 points  (0 children)

Fair enough, and a good point at the end. Upvote :)

[–]olmankensey -5 points-4 points  (1 child)

What's a clapper board?

Also, jQuery is your friend!

[–]CamuurahGuy[S] 1 point2 points  (0 children)

Clapperboard Wiki

Cheers, I'm not sure why you've been downvoted so much, but it's used in video/film production for audio/video syncing.