diff --git a/examples/minimal-web/src/main.rs b/examples/minimal-web/src/main.rs index 38de8d2a..98ae352e 100644 --- a/examples/minimal-web/src/main.rs +++ b/examples/minimal-web/src/main.rs @@ -3,7 +3,7 @@ use error_iter::ErrorIter as _; use log::error; -use pixels::{Pixels, SurfaceTexture}; +use pixels::{PixelsBuilder, SurfaceTexture}; use std::rc::Rc; use winit::dpi::LogicalSize; use winit::event::{Event, WindowEvent}; @@ -41,6 +41,16 @@ fn main() { } } +#[cfg(target_arch = "wasm32")] +/// Retrieve current width and height dimensions of browser client window +fn get_window_size() -> LogicalSize { + let client_window = web_sys::window().unwrap(); + LogicalSize::new( + client_window.inner_width().unwrap().as_f64().unwrap(), + client_window.inner_height().unwrap().as_f64().unwrap(), + ) +} + async fn run() { let event_loop = EventLoop::new().unwrap(); let window = { @@ -60,80 +70,83 @@ async fn run() { use wasm_bindgen::JsCast; use winit::platform::web::WindowExtWebSys; - // Retrieve current width and height dimensions of browser client window - let get_window_size = || { - let client_window = web_sys::window().unwrap(); - LogicalSize::new( - client_window.inner_width().unwrap().as_f64().unwrap(), - client_window.inner_height().unwrap().as_f64().unwrap(), - ) - }; - - let window = Rc::clone(&window); - - // Initialize winit window with current dimensions of browser client - window.set_inner_size(get_window_size()); - - let client_window = web_sys::window().unwrap(); - // Attach winit canvas to body element web_sys::window() .and_then(|win| win.document()) .and_then(|doc| doc.body()) .and_then(|body| { - body.append_child(&web_sys::Element::from(window.canvas())) + body.append_child(&web_sys::Element::from(window.canvas().unwrap())) .ok() }) .expect("couldn't append canvas to document body"); // Listen for resize event on browser client. Adjust winit window dimensions // on event trigger - let closure = wasm_bindgen::closure::Closure::wrap(Box::new(move |_e: web_sys::Event| { - let size = get_window_size(); - window.set_inner_size(size) + let closure = wasm_bindgen::closure::Closure::wrap(Box::new({ + let window = Rc::clone(&window); + move |_e: web_sys::Event| { + let _ = window.request_inner_size(get_window_size()); + } }) as Box); - client_window + web_sys::window() + .unwrap() .add_event_listener_with_callback("resize", closure.as_ref().unchecked_ref()) .unwrap(); closure.forget(); + + // Trigger initial resize event + let _ = window.request_inner_size(get_window_size()); } let mut input = WinitInputHelper::new(); let mut pixels = { + #[cfg(not(target_arch = "wasm32"))] let window_size = window.inner_size(); + + #[cfg(target_arch = "wasm32")] + let window_size = get_window_size().to_physical::(window.scale_factor()); + let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, window.as_ref()); - Pixels::new_async(WIDTH, HEIGHT, surface_texture) - .await - .expect("Pixels error") + let builder = PixelsBuilder::new(WIDTH, HEIGHT, surface_texture); + + #[cfg(target_arch = "wasm32")] + let builder = { + // Web targets do not support the default texture format + let texture_format = pixels::wgpu::TextureFormat::Rgba8Unorm; + builder + .texture_format(texture_format) + .surface_texture_format(texture_format) + }; + + builder.build_async().await.expect("Pixels error") }; let mut world = World::new(); let res = event_loop.run(|event, elwt| { - // Draw the current frame - if let Event::WindowEvent { - event: WindowEvent::RedrawRequested, - .. - } = event - { - world.draw(pixels.frame_mut()); - if let Err(err) = pixels.render() { - log_error("pixels.render", err); - elwt.exit(); - return; - } - } + match event { + Event::WindowEvent { + event: WindowEvent::RedrawRequested, + .. + } => { + // Draw the current frame + world.draw(pixels.frame_mut()); + if let Err(err) = pixels.render() { + log_error("pixels.render", err); + elwt.exit(); + return; + } - // Handle input events - if input.update(&event) { - // Close events - if input.key_pressed(KeyCode::Escape) || input.close_requested() { - elwt.exit(); - return; + // Update internal state and request a redraw + world.update(); + window.request_redraw(); } - // Resize the window - if let Some(size) = input.window_resized() { + Event::WindowEvent { + event: WindowEvent::Resized(size), + .. + } => { + // Resize the window if let Err(err) = pixels.resize_surface(size.width, size.height) { log_error("pixels.resize_surface", err); elwt.exit(); @@ -141,9 +154,12 @@ async fn run() { } } - // Update internal state and request a redraw - world.update(); - window.request_redraw(); + _ => (), + } + + // Handle input events + if input.update(&event) && (input.key_pressed(KeyCode::Escape) || input.close_requested()) { + elwt.exit(); } }); res.unwrap();