sweet_web/dom_utils/
animation_frame.rs

1use 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}