Search code examples
rustcanvasrenderingwebglwebassembly

Rust and WASM - How to block or sleep for X seconds without preventing Canvas redrawing?


I've coded my game for an embedded system. I made a wait function that runs a loop and breaks after some specified milliseconds.

However, on browser environment, the canvas does not redraw during the loop.

I've looked at something like setTimeout and requestAnimationFrame. But it would take lots of effort to port my game to WASM on browser.

Is there any possible way to make the main thread sleep/block without preventing canvas redrawing? I do not have async/await in my code.


Solution

  • By default JavaScript and Wasm code running in a web page are running in “the main thread” (as it might be called elsewhere), as part of the event loop. As long as code is running, it blocks all screen updates and user interaction. You must return control between every frame you wish to display.

    requestAnimationFrame is the optimal way to run animations because the browser schedules it to run at a good upcoming time to redraw, and won't run it if the page is invisible.

    If is too difficult to rewrite your code with callbacks, consider changing your loop into an async loop — use wasm-bindgen-futures to start it and gloo-timers to delay.

    You can also run code continuously in a Web Worker (the web-API version of a “background thread”), but that worker won't be able to draw to a displayed canvas.