A tiny browser experiment where one glowing Pong ball moves across multiple real browser windows as if the desktop were one shared table.
Open the same URL in two or three separate windows, arrange them on your screen, and the ball will cross between touching windows. Empty space between windows behaves like a wall.
Browser windows from the same origin can communicate through localStorage. When one window writes to localStorage, every other open window receives a storage event.
This project uses that as a tiny message bus:
- Each window writes its screen rectangle:
screenX,screenY,innerWidth, andinnerHeight. - All windows keep a live registry of the other windows.
- The window with the lowest id becomes the host.
- Only the host runs physics.
- The host broadcasts the ball position through
localStorage. - Every window renders the same global ball position relative to its own
screenX/screenY.
That means each canvas is just a viewport into one shared screen-space coordinate system.
The collision model asks one simple question: is this screen point covered by any open window? If yes, the ball can move there. If no, it bounces. This makes touching windows behave like connected rooms while gaps behave like walls.
Serve the folder over localhost. Do not open index.html directly with file://.
node server.jsThen open:
http://127.0.0.1:8000/
Use separate browser windows, not tabs.
node physics.test.js
node windowRegistry.test.js
node viewport.test.jsThe tests cover the important weird parts: open-room collision, hidden tab host election, and shared screen coordinates.
index.html- full-window canvas and minimal stylingmain.js- app wiring and animation loopwindowRegistry.js- window heartbeat, cleanup, and host electionphysics.js- host-only ball physicsrenderer.js- glowing trail rendererviewport.js- shared screen-space window rectangle
This is intentionally dependency-free at runtime. It uses browser APIs, canvas, and localStorage.
The collision check probes the ball's leading edge, not its full swept circle. That is enough for normal window layouts. If you make tiny gaps or tight concave shapes, it may clip a corner.