Skip to content

Conversation

@Vipitis
Copy link
Contributor

@Vipitis Vipitis commented Sep 17, 2025

#38

two evenings of tinkering but I can feel a bit of progress. Rendercanvas looks very web inspired, so I am reading a lot of things between the docs, pyodide docs, pyodide source that sound close but are ever so slightly different. Plus I don't have any webdev experience, it's more like a learning opportunity.

for those that want to give it a try - you can essentially just load the .html as a static page with the python script inserted. But you will need to build wheels and load them locally. Installing from pypi via micropip doesn't include these changes.

some todos:

  • Name the new backend "html", "pyodide", or other?
  • support all events
    • resize
    • close
    • mouse move doesn't work yet
    • wheel emits warning -> not anymore
    • (should events block navigation?)
    • listen to custom message events from the browser (for example to close?)
  • demo page should be able to load different examples (maybe multiple?)
  • Implement meta-tests
  • write tests for CI -> docs
  • put interactive canvas in docs? (doc builder also builds the wheel)

@Vipitis
Copy link
Contributor Author

Vipitis commented Sep 17, 2025

feel like some stuff breaks due to the python name mangling when using double underscores in combination with the subclass... which happens quite a bit - so I am sorta surprised it still works this far.

But I can't find any such references for Pyodide which would be odd if that is a known limitation.

@Vipitis
Copy link
Contributor Author

Vipitis commented Sep 20, 2025

feel like some stuff breaks due to the python name mangling

that wasn't the case. I actually fell through the line here

context = self._canvas_context
if context:
because I hadn't implemented context as a class. I took a lot of inspiration form the bitmap scripts and got it working
I also registered the auto backend successfully - meaning if you build the wheel and then load it statically. The examples noise.py and snake.py work out of the box (although not events yet). But the weekend has a few more days :)

auto_demo.mp4

E: turns out that wasn't true either and I am using the existing bitmaprenderingcontext due to how get_context is implemented.

@Vipitis
Copy link
Contributor Author

Vipitis commented Sep 20, 2025

singular keydown event works... so more events and other types shouldn't be impossible. However I will get to that another day.

snake_events.mp4

@Vipitis
Copy link
Contributor Author

Vipitis commented Sep 21, 2025

tried all day to make it work for the docs ... but either the .whl don't get included as static files or pyodide has trouble importing the wheel. I also wanted to automate the iframe inclusion with sphinx-gallery but seems like you need to either modify the gen_rst function or write an image scaper to append some custom rst to the examples... so I just added the comment to the relevant examples instead 🤷

classic "works on my machine", so have a video of what could have been instead:

doc_embed.mp4

@Korijn
Copy link
Contributor

Korijn commented Sep 21, 2025

Even so it's awesome how far you managed to take this!

@Vipitis
Copy link
Contributor Author

Vipitis commented Nov 1, 2025

regarding the buffer copy, the best I found is .assign() #115 (comment) , however I dug up the pyodide source and it looks like that still is a copy all the way down
https://github.com/pyodide/pyodide/blob/456dc8a668557200ba4e14d9fa450496f9f99226/src/core/jslib.c#L445C3-L447C3

I am also using that in the wgpu branch for all the buffer/texture writes so let's hope there is a better way.

@almarklein
Copy link
Member

I applied all suggestions.

Regarding the buffer copy, the best I found is .assign()

Also see pyodide/pyodide#5972, it looks like it's possible to do it without a copy, but only from JS code?

I am also using that in the wgpu branch for all the buffer/texture writes so let's hope there is a better way.

Oh, that's good to know. That makes it extra important to get this working ...

@almarklein
Copy link
Member

Thanks for the meticulous review Jan!

@Vipitis
Copy link
Contributor Author

Vipitis commented Nov 1, 2025

one more thing, I am getting ads on the docs page. But not in the wgpu-py or pygfx docs. Not sure what plan you have and how many projects that covers but perhaps it's just a checkbox somewhere. Just a heads up, I don't really mind myself.

@almarklein
Copy link
Member

It even worked on my phone - but the Textinput field opens the keyboard which is a bit unexpected.

Also fixed that. For the drag example the squares are huge, but I'll leave that for another day.

one more thing, I am getting ads on the docs page

I had a plan for just 2 projects. I now upped it to three :)

@Vipitis
Copy link
Contributor Author

Vipitis commented Nov 1, 2025

very nice! It's ready from my end.

I added a commit to the wgpu PR and it was working earlier (the renaming back to canvas is currently outdated) with mouse events being accurate, tab switching not breaking etc.

Things we haven't covered is changing scheduling mode(I had an example earlier where it only animated on hover) and turning off vsync, however that might not make sense in a browser context anyway.

Something that happens to me quite a bit during development was errors during the draw call, which then spam the console due to with log_exception and lag the tab or even make it unresponsive. Not sure what the best experience should be: an alert, a single warning to console, a suspend, a message inside the canvas?
Pyodide provides a way to capture stdout and stderr, which I wanted to try out for the compute examples in wgpu.

@almarklein
Copy link
Member

turning off vsync, however that might not make sense in a browser context anyway.

No, vsync does not apply; we're not rendering to the screen, but to a texture that's used by the browser's compositor to combine it with other content.

Something that happens to me quite a bit during development was errors during the draw call, which then spam the console

We already shorten messages if they are the same. But we can also hide them, and e.g. only emit every second or so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants