diff --git a/docs/backends.rst b/docs/backends.rst index 7738e067..7c3d6a0d 100644 --- a/docs/backends.rst +++ b/docs/backends.rst @@ -440,7 +440,7 @@ Similar as with PyScript, you can chose between a ```` and a ``
- + diff --git a/docs/static/_pyodide_iframe.html b/docs/static/_pyodide_iframe.html index 602f5287..561b900d 100644 --- a/docs/static/_pyodide_iframe.html +++ b/docs/static/_pyodide_iframe.html @@ -4,7 +4,7 @@ Rendercanvas example.py in Pyodide - + diff --git a/examples/pyodide.html b/examples/pyodide.html index 77968376..6e984f2e 100644 --- a/examples/pyodide.html +++ b/examples/pyodide.html @@ -4,7 +4,7 @@ RenderCanvas Pyodide example - + diff --git a/examples/serve_browser_examples.py b/examples/serve_browser_examples.py index 6bebdf28..488ae5f9 100644 --- a/examples/serve_browser_examples.py +++ b/examples/serve_browser_examples.py @@ -57,7 +57,7 @@ def get_html_index(): RenderCanvas PyScript examples - + @@ -84,7 +84,7 @@ def get_html_index(): example.py via PyScript - + diff --git a/rendercanvas/pyodide.py b/rendercanvas/pyodide.py index 12f83ecc..f6dbe082 100644 --- a/rendercanvas/pyodide.py +++ b/rendercanvas/pyodide.py @@ -20,6 +20,7 @@ raise ImportError("This module is only for use with Pyodide in the browser.") from pyodide.ffi import create_proxy, to_js +from pyodide.code import run_js from js import window, document, ImageData, Uint8ClampedArray, OffscreenCanvas @@ -72,6 +73,11 @@ def __init__( # If size or title are not given, set them to None, so they are left as-is. This is usually preferred in html docs. kwargs["size"] = kwargs.get("size", None) + # instead of using the callback directly (which blocks stack switching), chain on the resolve. TODO: avoid the eval and implement it using pyodide ffi + self._next_frame_promise = run_js( + "() => new Promise(resolve => requestAnimationFrame(resolve))" + )() + # Finalize init super().__init__(*args, **kwargs) self._final_canvas_init() @@ -133,7 +139,7 @@ def _rc_request_draw(self): self._time_to_draw() def _rc_request_paint(self): - window.requestAnimationFrame(create_proxy(lambda _: self._time_to_paint())) + self._next_frame_promise.then(lambda _: self._time_to_paint()) def _rc_force_paint(self): # Not very clean to do this, and not sure if it works in a browser;