sweet_web/dom_utils/
animation_frame.rs1use std::cell::RefCell;
2use std::rc::Rc;
3use wasm_bindgen::prelude::*;
4use web_sys::window;
5
6pub struct AnimationFrame(pub Rc<RefCell<i32>>);
7
8
9impl AnimationFrame {
10 pub fn new<F>(mut on_frame: F) -> Self
11 where
12 F: FnMut() + 'static,
13 {
14 let f = Rc::new(RefCell::new(None));
15 let handle = Rc::new(RefCell::new(0));
16 let handle2 = handle.clone();
17 let f2 = f.clone();
18 *f2.borrow_mut() = Some(Closure::new(move || {
19 on_frame();
20 *handle2.borrow_mut() =
21 request_animation_frame(f.borrow().as_ref().unwrap());
22 }));
23 *handle.borrow_mut() =
24 request_animation_frame(f2.borrow().as_ref().unwrap());
25 Self(handle)
26 }
27 pub fn forget(self) { *self.0.borrow_mut() = i32::MAX; }
28}
29
30impl Drop for AnimationFrame {
31 fn drop(&mut self) {
32 window()
33 .unwrap()
34 .cancel_animation_frame(*self.0.borrow())
35 .expect("failed to request animation frame");
36 }
37}
38
39fn request_animation_frame(f: &Closure<dyn FnMut()>) -> i32 {
40 window()
41 .unwrap()
42 .request_animation_frame(f.as_ref().unchecked_ref())
43 .expect("failed to request animation frame")
44}