programmierhub/public/js/ui.js
Stefan Franke 502131f07c VR ProgrammierHub — begehbarer 3D-Lernraum für hybride Programmier-Lehre
Erste lauffähige Fassung: 3D-Raum, Echtzeit-Multiplayer (WebSocket),
Python-IDE via Pyodide im Browser, eigener Arbeitsplatz mit Live-Code-Monitor.
Modularer, self-hostbarer Aufbau (Three.js + Node/Express + ws), ohne CDN-
Abhängigkeit zur Laufzeit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-30 13:35:11 +00:00

58 lines
2.3 KiB
JavaScript

// ui.js — DOM-Oberfläche: Start-Overlay, Toolbar, HUD-Anzeigen, Fehleranzeige.
// Kennt Three.js/Netzwerk nicht — kommuniziert per Callbacks.
export class UI {
constructor() {
this.overlay = document.getElementById('overlay');
this.toolbar = document.getElementById('toolbar');
this.errBox = document.getElementById('err');
this.el = {
dbg: document.getElementById('dbg'),
net: document.getElementById('net'),
fps: document.getElementById('fps'),
count: document.getElementById('count'),
help: document.getElementById('helpBtn'),
ide: document.getElementById('ideBtn'),
};
this._startCb = null;
this._helpCb = null;
this._ideCb = null;
this._helpOn = false;
document.getElementById('startbtn').addEventListener('click', () => this._start());
document.getElementById('name').addEventListener('keydown', (e) => { if (e.key === 'Enter') this._start(); });
this.el.help.addEventListener('click', () => this._toggleHelp());
this.el.ide.addEventListener('click', () => { if (this._ideCb) this._ideCb(); });
}
_start() {
const name = (document.getElementById('name').value || 'Gast').trim().slice(0, 24) || 'Gast';
const role = document.getElementById('role').value;
this.overlay.style.display = 'none';
this.toolbar.style.display = 'flex';
if (this._startCb) this._startCb(name, role);
}
_toggleHelp() {
this._helpOn = !this._helpOn;
this.el.help.classList.toggle('on', this._helpOn);
this.el.help.textContent = this._helpOn ? '✋ Hilfe angefragt (klick = zurück)' : '✋ Hilfe anfragen';
if (this._helpCb) this._helpCb(this._helpOn);
}
onStart(cb) { this._startCb = cb; }
onHelpToggle(cb) { this._helpCb = cb; }
onOpenIde(cb) { this._ideCb = cb; }
setDbg(s) { if (this.el.dbg) this.el.dbg.textContent = s; }
setNet(text, color) { if (this.el.net) { this.el.net.textContent = text; this.el.net.style.color = color || '#f9e2af'; } }
setFps(n) { if (this.el.fps) this.el.fps.textContent = n; }
setCount(n) { if (this.el.count) this.el.count.textContent = n; }
showError(where, e) {
if (!this.errBox) return;
this.errBox.style.display = 'block';
this.errBox.textContent = '⚠ Fehler in ' + where + ':\n' + (e && (e.stack || e.message) || e);
this.setDbg('FEHLER @ ' + where);
}
}