emilk / egui

egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native
https://www.egui.rs/
Apache License 2.0
20.64k stars 1.49k forks source link

Web canvas size is tiny for the first frame #4622

Closed emilk closed 3 weeks ago

emilk commented 3 weeks ago

Repro

--- a/crates/eframe/src/web/app_runner.rs
+++ b/crates/eframe/src/web/app_runner.rs
@@ -188,6 +188,7 @@ impl AppRunner {
     /// The result can be painted later with a call to [`Self::run_and_paint`] or [`Self::paint`].
     pub fn logic(&mut self) {
         let canvas_size = super::canvas_size_in_points(self.canvas(), self.egui_ctx());
+        log::info!("canvas_size: {canvas_size:?}");
         let raw_input = self.input.new_frame(canvas_size);

         let full_output = self.egui_ctx.run(raw_input, |egui_ctx| {
./scripts/build_demo_web.sh && ./scripts/start_server.sh

Result

image

The symptom is that all windows gets squashed to a very small size, and pushed to the top left corner:

image

jprochazk commented 3 weeks ago

This is caused by the first requestAnimationFrame firing the callback before the resize observer is run on observe. Both are asynchronous and it seems like the animation frame takes precedence in the event loop because it is registered first... Or something like that.

Because the resize observer is called not just on every resize but also on the call to observe (exactly for the purpose of determining the initial dimensions), we can move the first request_animation_frame from WebRunner::start to the resize observer callback.