-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
utility crate: requestAnimationFrame #1
Comments
A couple more things which I think would be useful:
The above was pioneered by dominator, but it is absolutely not tied to dominator at all, so it can easily be put into a separate crate. |
@Pauan are you interested in making a strawman API proposal / draft PR for some of this? |
FWIW, when I said "debouncing rAF", this is the kind of thing I was thinking of: https://github.com/fitzgen/dodrio/blob/master/src/vdom.rs#L599-L625 |
@fitzgen I don't think that I'd like to give this a try. Here's my design idea: Low-level APIuse gloo::ani_frames::Animation;
let af: AnimationIndex<_> = Animation::request_frame(|| { ... });
Animation::cancel_frame(af); Higher-level APIstruct T; // zero-sized type to distinguish animations
// create and start a requestAnimationFrame() loop!
// use Animation::<T>::paused() if you don't want to start it
let mut ani = Animation::<T>::new();
// add closure that is executed on every frame:
ani.add(|state| { ... });
// closures can be removed (only once, because AnimationIndex isn't Copy):
let index: AnimationIndex<T> = ani.add(|_| { ... });
ani.remove(index);
ani.pause(); // pauses the animation loop, using cancelAnimationFrame()
ani.once(); // requests one frame, if it's paused
ani.start(); // starts the animation loop, if it's paused
std::mem::drop(ani); // cancels the animation
// or
ani.forget(); // leaks the memory Higher-level API using futuresstruct T;
let mut ani: AnimationStream<T, &AnimationState> = Animation::stream(); // or paused_stream()
// add closure that is executed on every frame:
ani.add(|state| { ... });
// or
let ani = ani.map(|state| { ... }); Please tell me what you think! This is roughly how I would implement the higher-level API: pub struct Animation<C> {
state: AnimationState,
next_index: AnimationIndex<C>,
callbacks: Vec<(AnimationIndex<C>, Box<dyn FnMut(AnimationState)>)>,
// this could be done with a HashMap, but I think we want deterministic iteration order
}
pub enum AnimationState {
Paused,
Running(i64),
RunningOnce(i64),
}
pub struct AnimationIndex<C> {
index: i64,
_marker: PhantomData<C>,
} |
If there is not an existing promise, then an animation frame is scheduled that will resolve the promise, and the promise is saved. If there is an existing promise, then it is re-used and no new animation frame is scheduled. Thus the |
For the low-level API, I would expect something very similar to the
Is this the |
The state isn't user-defined, it's one of The struct T;
struct U;
let mut first = Animation::<T>::new();
let mut second = Animation::<U>::new();
let ix = first.add(|_| { ... });
second.remove(ix); // expected AnimationIndex<U>, found AnimationIndex<T> Instead of T and U, you could also write I'm trying to implement the whole thing ATM and struggling with the borrow checker. I fear I'll have to use a Here is my helper function. It compiles, but when I try to use it, I get all sorts of errors because of fn request_af<F: FnOnce() + 'static>(callback: F) -> i32 {
web_sys::window().unwrap_throw()
.request_animation_frame(Closure::once(callback).as_ref().unchecked_ref())
.unwrap_throw()
} |
Yes, if you want looping in Rust, that is necessary. If the looping is done in JS it isn't necessary, but then you need a local Nit: it should be |
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
1. and 4. were implemented in #126 |
We should have an idiomatic Rust utility crate for working with
requestAnimationFrame
requestAnimationFrame
loop (reusing the same function)requestAnimationFrame
sThe text was updated successfully, but these errors were encountered: