Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

method to set the global frame function #802

Open
wants to merge 1 commit into from

2 participants

@javisantana

No description provided.

@mbostock
Owner

I don't see a strong reason to support this over the existing d3.timer(function), which you can use to run once by having the callback function return true. Using the native method would be slightly faster, but outside of D3's API, so it's not D3's responsibility to expose the polyfill.

I suppose one way we could do this is to move requestAnimationFrame to the compat directory (as we do with Date.now), and then you could just rely on window.requestAnimationFrame being polyfilled by D3, and use that directly.

@javisantana

our main reason is to be able to slow down all the animations. Sometimes you dont need the animations run at 60fps so changing the frame function allows to run slower (and save some CPU). This is basically the use case we have now, we have lots of animations done with transition method and we'd like to slow down.

I can't see how moving requestAnimationFrame to compat would help, I would have to "patch" window.requestAnimationFrame before load D3, I could do the same right now (but it is not very elegant)

@mbostock
Owner

Sorry, I thought you were trying to get the requestAnimationFrame function, not set it.

@javisantana

I do not want to set requestAnimationFrame function, I'd like to be able to overwrite "d3_timer_frame" function with some custom function in order to control the animations pace (without having to patch requestAnimationFrame before load d3)

I put the getter because that pattern is used in d3 code not to use d3_timer_frame function directly which does not make any sense in case you want to do your custom animations (you should use timer as you pointed before)

@mbostock
Owner

I'd like to be able to overwrite "d3_timer_frame" function

Sorry for my imprecise wording, but that's what I meant.

Is this an issue for all browsers? Or is it primarily an issue for browsers that don't support requestAnimationFrame? Because browsers that do support requestAnimationFrame tend to be fairly efficient. (For example, they never callback more frequently than 60Hz, and they pause animation when in background tabs.)

I guess my related question would be: how are you going to change the implementation of requestAnimationFrame to slow down the animation? You can't request a slower callback, but I suppose you could drop every other frame? Or are you going to replace requestAnimationFrame with a slower setTimeout? (In which case you could achieve this by patching requestAnimationFrame rather than D3, though I could see that being undesirable in certain circumstances.)

@mbostock
Owner

Also, related, if it helps: sometimes in the extreme cases (rendering thousands of nodes) I find it helpful to use a mixture of Canvas and SVG. For example, you can use Canvas to render shapes, and then have an SVG overlay for interaction and axes where D3's data-joins are helpful.

@javisantana

guess my related question would be: how are you going to change the implementation of requestAnimationFrame to slow down the animation? You can't request a slower callback, but I suppose you could drop every other frame? Or are you going to replace requestAnimationFrame with a slower setTimeout?

Yes, I'd like to replace requestAnimationFrame with a slower timeout. The animation I'm running does not need to run at 60fps and d3 does not provide a way to control the animations.

One way to do that is to replace requestAnimationframe but in my opinion this is not the best way, d3 should provide something like my pull request to control the animations.

I know i can code my own animation using timer function and skip some frames to archieve the desired FPS but I'd like to use then transition features of d3 but I cant control framerate.

So your proposal is to do:

window.requestAnmationFrame = function(c) { setTimeout(c, DESIRED_T) }
// load d3 library

Is there another way to do this without doing this hack?

Also, related, if it helps: sometimes in the extreme cases (rendering thousands of nodes) I find it helpful to use a mixture of Canvas and SVG. For example, you can use Canvas to render shapes, and then have an SVG overlay for interaction and axes where D3's data-joins are helpful.

Yep, my problem is not performance here, my "problem" is that I dont want to run the animatiom at 60fps (why all the animations need to run at 60fps?) because It does not need to be updated at 60fps and I can save some CPU.

Thanks for your time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 7, 2012
  1. @javisantana
This page is out of date. Refresh to see the latest.
Showing with 5 additions and 0 deletions.
  1. +5 −0 src/core/timer.js
View
5 src/core/timer.js
@@ -96,6 +96,11 @@ function d3_timer_flush() {
return then;
}
+d3.timer.frame_function = function(fn) {
+ if (!arguments.length) return d3_timer_frame;
+ d3_timer_frame = fn;
+};
+
var d3_timer_frame = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
Something went wrong with that request. Please try again.