sweet_web/dom_utils/
animation_frame.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
use std::cell::RefCell;
use std::rc::Rc;
use wasm_bindgen::prelude::*;
use web_sys::window;

pub struct AnimationFrame(pub Rc<RefCell<i32>>);


impl AnimationFrame {
	pub fn new<F>(mut on_frame: F) -> Self
	where
		F: FnMut() + 'static,
	{
		let f = Rc::new(RefCell::new(None));
		let handle = Rc::new(RefCell::new(0));
		let handle2 = handle.clone();
		let f2 = f.clone();
		*f2.borrow_mut() = Some(Closure::new(move || {
			on_frame();
			*handle2.borrow_mut() =
				request_animation_frame(f.borrow().as_ref().unwrap());
		}));
		*handle.borrow_mut() =
			request_animation_frame(f2.borrow().as_ref().unwrap());
		Self(handle)
	}
	pub fn forget(self) { *self.0.borrow_mut() = i32::MAX; }
}

impl Drop for AnimationFrame {
	fn drop(&mut self) {
		window()
			.unwrap()
			.cancel_animation_frame(*self.0.borrow())
			.expect("failed to request animation frame");
	}
}

fn request_animation_frame(f: &Closure<dyn FnMut()>) -> i32 {
	window()
		.unwrap()
		.request_animation_frame(f.as_ref().unchecked_ref())
		.expect("failed to request animation frame")
}