use std::cell::RefCell; use std::rc::Rc; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; fn window() -> web_sys::Window { web_sys::window().expect("no global `window` exists") } fn request_animation_frame(f: &Closure) { window() .request_animation_frame(f.as_ref().unchecked_ref()) .expect("should register `requestAnimationFrame` OK"); } fn document() -> web_sys::Document { window() .document() .expect("should have a document on window") } fn body() -> web_sys::HtmlElement { document().body().expect("document should have a body") } // This function is automatically invoked after the wasm module is instantiated. #[wasm_bindgen(start)] pub fn run() -> Result<(), JsValue> { let f = Rc::new(RefCell::new(None)); let g = f.clone(); { let mut i = 0; *g.borrow_mut() = Some(Closure::wrap(Box::new(move || { if i > 300 { body().set_text_content(Some("All done!")); // Drop our handle to this closure so that it will get cleaned // up once we return. let _ = f.borrow_mut().take(); return; } // Set the body's text content to how many times this // requestAnimationFrame callback has fired. i += 1; let text = format!("requestAnimationFrame has been called {} times.", i); body().set_text_content(Some(&text)); // Schedule ourself for another requestAnimationFrame callback. request_animation_frame(f.borrow().as_ref().unwrap()); }) as Box)); } request_animation_frame(g.borrow().as_ref().unwrap()); Ok(()) }