'Rust WebAssembly inside browser change html canvas size - eframe

I'm simply trying to change the size of the html canvas element generated by webassembly from my rust code. I'm kinda new to rust and wasm and i'm still trying to figure out the doc at https://docs.rs/eframe/0.17.0/eframe/ but i'm having a hard time.

At first, i tried to modify it from the web dev tools but it resets every time. Same with css and html styling. So i tried to import my HtmlCanvasElement with wasm_bindgen::JsCast and web_sys and modify its size :

#[wasm_bindgen(start)]
pub fn start() {
    let document = web_sys::window().unwrap().document().unwrap();
    let canvas = document.get_element_by_id("app").unwrap();
    let canvas: web_sys::HtmlCanvasElement = canvas
        .dyn_into::<web_sys::HtmlCanvasElement>()
        .map_err(|_| ())
        .unwrap();

    canvas.set_width(1600);
    canvas.set_height(900);

    #[cfg(target_arch = "wasm32")]
    eframe::start_web("app", Box::new(TestApp::new())).unwrap();
}

pub struct TestApp;

#[cfg(target_arch = "wasm32")]
impl TestApp {
    pub fn new() -> TestApp {
        TestApp {
        }
    }
}

impl App for TestApp {
    fn name(&self) -> &str { "TestApp" }

    fn setup(&mut self,
        _ctx: &Context,
        frame: &Frame,
        _storage: Option<&dyn Storage>)
    {
        let document = web_sys::window().unwrap().document().unwrap();
        let canvas = document.get_element_by_id("app").unwrap();
        let canvas: web_sys::HtmlCanvasElement = canvas
            .dyn_into::<web_sys::HtmlCanvasElement>()
            .map_err(|_| ())
            .unwrap();

        canvas.set_width(1600);
        canvas.set_height(900);

        frame.set_window_size(Vec2{x:1600.0,y:900.0});
    }

    fn update(&mut self,
        ctx: &Context,
        _frame: &Frame)
    {
        CentralPanel::default().show(ctx, |ui| {
            ui.label("Hello World!");
        });
        ctx.request_repaint();
    }
}

But it still doesn't work...



Solution 1:[1]

Ok so, it seems that trying to change the canvas size from html or css is useless because it is tight to a parent "element" that has total control over the size of the canvas and keeps resetting the width to 1024. The height however gets automatically adjusted, which is handy. The width is not.

It also seems that using HtmlCanvasElement set_width() and set_height() inside the setup func just doesn't work. Used in the update func, something happend. It does affect the html width/height properties of the canvas, as observed with firefox dev tools :

<canvas id="app" style="width: 1024px; height: 632px;" width="100" height="100"></canvas>

But it did not affect it style width and height... which just had the effect of scaling my app inside the 1024x632 canvas. I have now the first 100x100 pixels of my app scaled inside the 1024x632 canvas.... Well at least it did something ! But i can't find any methods in HtmlCanvasElement to modify the style. Maybe i need to look again.

For the attempt with frame.set_window_size(Vec2{x:1600.0,y:900.0});, i just can't figure out what it's used for yet and i can't get it to do something.

Anyway, after few searches on the rust discord server (https://discord.gg/49hyRTrN), i've found it ! Thanks to Alex Mcleod from rust-lang zulipchat :

If you want the intrinsic size of the canvas to determine its size you can remove the height/width properties from the style="..." attribute

If you do want to be able to adjust the size in CSS and the intrinsic size separately though you'd do it through the style getter - https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html#method.style

then either https://docs.rs/web-sys/latest/web_sys/struct.CssStyleDeclaration.html#method.set_property or https://docs.rs/web-sys/latest/web_sys/struct.CssStyleDeclaration.html#method.set_css_text

PS: The docs.rs is really well done. I just can't really figure it out yet. Thanks for the awesome rust community for the help.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1