Use canvas directly (#4780)

This commit is contained in:
Jan Procházka 2024-07-15 18:59:15 +02:00 committed by GitHub
parent cb9f30482f
commit 0d89e31e3e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 22 additions and 27 deletions

View File

@ -85,10 +85,10 @@
//! //!
//! /// Call this once from JavaScript to start your app. //! /// Call this once from JavaScript to start your app.
//! #[wasm_bindgen] //! #[wasm_bindgen]
//! pub async fn start(&self, canvas_id: &str) -> Result<(), wasm_bindgen::JsValue> { //! pub async fn start(&self, canvas: web_sys::HtmlCanvasElement) -> Result<(), wasm_bindgen::JsValue> {
//! self.runner //! self.runner
//! .start( //! .start(
//! canvas_id, //! canvas,
//! eframe::WebOptions::default(), //! eframe::WebOptions::default(),
//! Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc))),) //! Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc))),)
//! ) //! )

View File

@ -31,12 +31,12 @@ impl AppRunner {
/// # Errors /// # Errors
/// Failure to initialize WebGL renderer, or failure to create app. /// Failure to initialize WebGL renderer, or failure to create app.
pub async fn new( pub async fn new(
canvas_id: &str, canvas: web_sys::HtmlCanvasElement,
web_options: crate::WebOptions, web_options: crate::WebOptions,
app_creator: epi::AppCreator, app_creator: epi::AppCreator,
text_agent: TextAgent, text_agent: TextAgent,
) -> Result<Self, String> { ) -> Result<Self, String> {
let painter = super::ActiveWebPainter::new(canvas_id, &web_options).await?; let painter = super::ActiveWebPainter::new(canvas, &web_options).await?;
let system_theme = if web_options.follow_system_theme { let system_theme = if web_options.follow_system_theme {
super::system_theme() super::system_theme()

View File

@ -122,17 +122,6 @@ fn theme_from_dark_mode(dark_mode: bool) -> Theme {
} }
} }
fn get_canvas_element_by_id(canvas_id: &str) -> Option<web_sys::HtmlCanvasElement> {
let document = web_sys::window()?.document()?;
let canvas = document.get_element_by_id(canvas_id)?;
canvas.dyn_into::<web_sys::HtmlCanvasElement>().ok()
}
fn get_canvas_element_by_id_or_die(canvas_id: &str) -> web_sys::HtmlCanvasElement {
get_canvas_element_by_id(canvas_id)
.unwrap_or_else(|| panic!("Failed to find canvas with id {canvas_id:?}"))
}
/// Returns the canvas in client coordinates. /// Returns the canvas in client coordinates.
fn canvas_content_rect(canvas: &web_sys::HtmlCanvasElement) -> egui::Rect { fn canvas_content_rect(canvas: &web_sys::HtmlCanvasElement) -> egui::Rect {
let bounding_rect = canvas.get_bounding_client_rect(); let bounding_rect = canvas.get_bounding_client_rect();

View File

@ -5,7 +5,7 @@ use wasm_bindgen::JsValue;
/// therefore this trait is merely there for specifying and documenting the interface. /// therefore this trait is merely there for specifying and documenting the interface.
pub(crate) trait WebPainter { pub(crate) trait WebPainter {
// Create a new web painter targeting a given canvas. // Create a new web painter targeting a given canvas.
// fn new(canvas_id: &str, options: &WebOptions) -> Result<Self, String> // fn new(canvas: HtmlCanvasElement, options: &WebOptions) -> Result<Self, String>
// where // where
// Self: Sized; // Self: Sized;

View File

@ -18,9 +18,7 @@ impl WebPainterGlow {
self.painter.gl() self.painter.gl()
} }
pub async fn new(canvas_id: &str, options: &WebOptions) -> Result<Self, String> { pub async fn new(canvas: HtmlCanvasElement, options: &WebOptions) -> Result<Self, String> {
let canvas = super::get_canvas_element_by_id_or_die(canvas_id);
let (gl, shader_prefix) = let (gl, shader_prefix) =
init_glow_context_from_canvas(&canvas, options.webgl_context_option)?; init_glow_context_from_canvas(&canvas, options.webgl_context_option)?;
#[allow(clippy::arc_with_non_send_sync)] #[allow(clippy::arc_with_non_send_sync)]

View File

@ -83,7 +83,10 @@ impl WebPainterWgpu {
} }
#[allow(unused)] // only used if `wgpu` is the only active feature. #[allow(unused)] // only used if `wgpu` is the only active feature.
pub async fn new(canvas_id: &str, options: &WebOptions) -> Result<Self, String> { pub async fn new(
canvas: web_sys::HtmlCanvasElement,
options: &WebOptions,
) -> Result<Self, String> {
log::debug!("Creating wgpu painter"); log::debug!("Creating wgpu painter");
let mut backends = options.wgpu_options.supported_backends; let mut backends = options.wgpu_options.supported_backends;
@ -162,7 +165,6 @@ impl WebPainterWgpu {
} }
} }
let canvas = super::get_canvas_element_by_id_or_die(canvas_id);
let surface = instance let surface = instance
.create_surface(wgpu::SurfaceTarget::Canvas(canvas.clone())) .create_surface(wgpu::SurfaceTarget::Canvas(canvas.clone()))
.map_err(|err| format!("failed to create wgpu surface: {err}"))?; .map_err(|err| format!("failed to create wgpu surface: {err}"))?;

View File

@ -57,7 +57,7 @@ impl WebRunner {
/// Failing to initialize graphics, or failure to create app. /// Failing to initialize graphics, or failure to create app.
pub async fn start( pub async fn start(
&self, &self,
canvas_id: &str, canvas: web_sys::HtmlCanvasElement,
web_options: crate::WebOptions, web_options: crate::WebOptions,
app_creator: epi::AppCreator, app_creator: epi::AppCreator,
) -> Result<(), JsValue> { ) -> Result<(), JsValue> {
@ -67,7 +67,7 @@ impl WebRunner {
let text_agent = TextAgent::attach(self)?; let text_agent = TextAgent::attach(self)?;
let runner = AppRunner::new(canvas_id, web_options, app_creator, text_agent).await?; let runner = AppRunner::new(canvas, web_options, app_creator, text_agent).await?;
{ {
// Make sure the canvas can be given focus. // Make sure the canvas can be given focus.

View File

@ -32,10 +32,13 @@ impl WebHandle {
/// Call this once from JavaScript to start your app. /// Call this once from JavaScript to start your app.
#[wasm_bindgen] #[wasm_bindgen]
pub async fn start(&self, canvas_id: &str) -> Result<(), wasm_bindgen::JsValue> { pub async fn start(
&self,
canvas: web_sys::HtmlCanvasElement,
) -> Result<(), wasm_bindgen::JsValue> {
self.runner self.runner
.start( .start(
canvas_id, canvas,
eframe::WebOptions::default(), eframe::WebOptions::default(),
Box::new(|cc| Ok(Box::new(WrapApp::new(cc)))), Box::new(|cc| Ok(Box::new(WrapApp::new(cc)))),
) )

View File

@ -166,7 +166,7 @@
check_for_panic(); check_for_panic();
handle.start("the_canvas_id").then(on_app_started).catch(on_error); handle.start(document.getElementById("the_canvas_id")).then(on_app_started).catch(on_error);
} }
function on_app_started(handle) { function on_app_started(handle) {

View File

@ -138,7 +138,10 @@
const handle_one = new wasm_bindgen.WebHandle(); const handle_one = new wasm_bindgen.WebHandle();
const handle_two = new wasm_bindgen.WebHandle(); const handle_two = new wasm_bindgen.WebHandle();
Promise.all([handle_one.start("canvas_id_one"), handle_two.start("canvas_id_two")]).then((handles) => { Promise.all([
handle_one.start(document.getElementById("canvas_id_one")),
handle_two.start(document.getElementById("canvas_id_two")),
]).then((handles) => {
on_apps_started(handle_one, handle_two) on_apps_started(handle_one, handle_two)
}).catch(on_error); }).catch(on_error);
} }