# Web Integration (Pyodide + pygame-ce) This document describes how ElectroSim runs in the browser, the added modules, and how browser-specific concerns are handled. ## Components and Data Sources - `web/index.html` - Loads Pyodide (0.27.7), NumPy, SciPy, and `pygame-ce` - Creates the HTML5 `canvas#canvas` target - Binds the Emscripten Module canvas to the DOM canvas - Sets SDL/pygame environment variables (display target, keyboard element, dummy audio) - Implements an async bootstrap: package load → file load → init → start - `web/main_web.py` - Web-adapted entrypoint that leverages the existing desktop simulation - Uses `pygame-ce` to render into the canvas - Runs an async-friendly frame loop (no `set_timer`, not supported on WASM) - Gracefully degrades if optional rendering pieces are unavailable - `web/config_web.py` - Overrides certain defaults for web (e.g., FPS, profiling overlay, sampler defaults) - Imported by `main_web.py` instead of desktop `config.py` - `web/server.py` - Simple HTTP static server for local development - `web/electrosim/` - A copy of the Python package so Pyodide can import the modules ## Keyboard Input Bridging SDL’s built-in DOM bridge may try to use missing symbols on some browsers. We: - Set `SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT` to `#canvas` so events are scoped - Focus the canvas on Start and make it focusable (`tabindex=0`) - Add a JavaScript bridge that captures `keydown` / `keyup` at capture phase and posts equivalent `pygame.event` KEYDOWN/KEYUP events to the Python side - This avoids the missing symbol path and preserves the desktop control scheme ## Field Sampling Fallback Numba kernels are not available in Pyodide. The field sampler: - Tries to import `_compute_field_grid_numba` - If unavailable, computes the electric field per grid-point using `electric_field_at_point` - Expected behavior: same visuals at lower performance ## Expected Behavior (Web) - Simulation runs at the configured `FPS_TARGET` (default 60) with async loop - Keyboard/mouse behave like desktop when the canvas is focused - Visuals: particles, trails, vectors, overlays identical to desktop - Performance: 2–10× slower than native; keep particle count modest ## Limitations - Audio is disabled (SDL dummy driver) - Timers (`set_timer`) are not supported; use an explicit loop - Numba acceleration disabled; kernels fall back to Python ## Debugging Tips - Open browser console to inspect logs and Python prints - Verify the canvas is focused if keys don’t work - Use the overlay (enable in `config_web.py`) to view frame timing