Option to give existing canvas element as winit window (#515)

This commit is contained in:
Tomasz Sterna 2020-09-22 01:12:34 +02:00 committed by GitHub
parent 74f881f20d
commit dd6f0b5e04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 10 deletions

View file

@ -24,3 +24,4 @@ uuid = { version = "0.8", features = ["v4", "serde"] }
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
uuid = { version = "0.8", features = ["wasm-bindgen"] } uuid = { version = "0.8", features = ["wasm-bindgen"] }
web-sys = "0.3"

View file

@ -40,6 +40,8 @@ pub struct Window {
pub vsync: bool, pub vsync: bool,
pub resizable: bool, pub resizable: bool,
pub mode: WindowMode, pub mode: WindowMode,
#[cfg(target_arch = "wasm32")]
pub canvas: Option<String>,
} }
/// Defines the way a window is displayed /// Defines the way a window is displayed
@ -64,6 +66,8 @@ impl Window {
vsync: window_descriptor.vsync, vsync: window_descriptor.vsync,
resizable: window_descriptor.resizable, resizable: window_descriptor.resizable,
mode: window_descriptor.mode, mode: window_descriptor.mode,
#[cfg(target_arch = "wasm32")]
canvas: window_descriptor.canvas.clone(),
} }
} }
} }
@ -77,6 +81,8 @@ pub struct WindowDescriptor {
pub vsync: bool, pub vsync: bool,
pub resizable: bool, pub resizable: bool,
pub mode: WindowMode, pub mode: WindowMode,
#[cfg(target_arch = "wasm32")]
pub canvas: Option<String>,
// this is a manual implementation of the non exhaustive pattern, // this is a manual implementation of the non exhaustive pattern,
// especially made to allow ..Default::default() // especially made to allow ..Default::default()
@ -93,6 +99,8 @@ impl Default for WindowDescriptor {
vsync: true, vsync: true,
resizable: true, resizable: true,
mode: WindowMode::Windowed, mode: WindowMode::Windowed,
#[cfg(target_arch = "wasm32")]
canvas: None,
__non_exhaustive: (), __non_exhaustive: (),
} }
} }

View file

@ -31,4 +31,5 @@ log = { version = "0.4", features = ["release_max_level_info"] }
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
winit = { version = "0.22.2", package = "cart-tmp-winit", features = ["web-sys"] } winit = { version = "0.22.2", package = "cart-tmp-winit", features = ["web-sys"] }
wasm-bindgen = { version = "0.2" }
web-sys = "0.3" web-sys = "0.3"

View file

@ -38,10 +38,30 @@ impl WinitWindows {
.with_resizable(window.resizable), .with_resizable(window.resizable),
}; };
let winit_window = winit_window_builder #[allow(unused_mut)]
.with_title(&window.title) let mut winit_window_builder = winit_window_builder.with_title(&window.title);
.build(&event_loop)
.unwrap(); #[cfg(target_arch = "wasm32")]
{
use wasm_bindgen::JsCast;
use winit::platform::web::WindowBuilderExtWebSys;
if let Some(selector) = &window.canvas {
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
let canvas = document
.query_selector(&selector)
.expect("Cannot query for canvas element");
if let Some(canvas) = canvas {
let canvas = canvas.dyn_into::<web_sys::HtmlCanvasElement>().ok();
winit_window_builder = winit_window_builder.with_canvas(canvas);
} else {
panic!("Cannot find element: {}", selector);
}
}
}
let winit_window = winit_window_builder.build(&event_loop).unwrap();
self.window_id_to_winit.insert(window.id, winit_window.id()); self.window_id_to_winit.insert(window.id, winit_window.id());
self.winit_to_window_id.insert(winit_window.id(), window.id); self.winit_to_window_id.insert(winit_window.id(), window.id);
@ -50,14 +70,16 @@ impl WinitWindows {
{ {
use winit::platform::web::WindowExtWebSys; use winit::platform::web::WindowExtWebSys;
let canvas = winit_window.canvas(); if window.canvas.is_none() {
let canvas = winit_window.canvas();
let window = web_sys::window().unwrap(); let window = web_sys::window().unwrap();
let document = window.document().unwrap(); let document = window.document().unwrap();
let body = document.body().unwrap(); let body = document.body().unwrap();
body.append_child(&canvas) body.append_child(&canvas)
.expect("Append canvas to HTML body"); .expect("Append canvas to HTML body");
}
} }
self.windows.insert(winit_window.id(), winit_window); self.windows.insert(winit_window.id(), winit_window);