File: /home/panomity.de/vr.panomity.com/plugins/walk/walk.js
/**
* Walk-Through-Modus für CMS4VR.
*
* Nutzt krpanos Tiefenkarten-Navigation (depthmap_navigation): mit aktivierter
* Szenen-Tiefenkarte kann man mit WASD/Pfeilen durch den Raum GEHEN (echte
* Parallaxe, Wand-Kollision) und über die Szenen-Hotspots weiter durch die
* Wohnung. Die Tastensteuerung wird nur im Walk-Modus scharfgeschaltet, damit
* WASD sonst (z.B. im Chat) nicht ins Leere greift.
*/
const walkMode = { on: false, watcher: null };
function walkKrpano() {
return (typeof krpano !== 'undefined') ? krpano : document.getElementById('krpanoSWFObject');
}
function walkLang() {
return (typeof ollamaChatConfig !== 'undefined' && ollamaChatConfig.language) || 'en';
}
function walkText(de, en) { return walkLang() === 'de' ? de : en; }
// Tasten-Handler der Navigation an/aus (verhindert WASD-Störungen außerhalb Walk).
function walkSetKeys(active) {
const k = walkKrpano();
try {
const ev = k.get('events[depthmap_navigation]');
if (ev) {
ev.onkeydown = active ? 'depthmap_handlekey(1);' : '';
ev.onkeyup = active ? 'depthmap_handlekey(0);' : '';
}
if (!active) {
['forward', 'backward', 'left', 'right', 'up', 'down', 'faster', 'jump']
.forEach(p => { try { k.set('walkaround.' + p, 0); } catch (e) { /* egal */ } });
}
} catch (e) { /* Plugin evtl. noch nicht geladen */ }
}
function walkEnableDepth(on) {
const k = walkKrpano();
try {
const dm = k.get('image.depthmap');
if (dm) dm.enabled = on;
} catch (e) { /* Szene ohne Tiefenkarte */ }
}
function walkToggle() {
const k = walkKrpano();
walkMode.on = !walkMode.on;
const btn = document.getElementById('walk-button');
if (walkMode.on) {
walkEnableDepth(true);
walkSetKeys(true);
// Beim Szenenwechsel die Tiefenkarte der neuen Szene aktiv halten.
walkMode.watcher = setInterval(() => walkEnableDepth(true), 1200);
if (btn) btn.classList.add('active');
walkHint(true);
walkShowPad(true);
// krpano fokussieren, damit WASD/Pfeile sofort ankommen.
try { const el = document.getElementById('pano') || (k.get && k.get('canvas')); if (el && el.focus) el.focus(); } catch (e) { /* egal */ }
} else {
clearInterval(walkMode.watcher);
walkSetKeys(false);
walkStopAll();
walkEnableDepth(false);
// Zur Aufnahmeposition zurück.
try { k.call('tween(view.tx, 0.0, 0.4); tween(view.ty, 0.0, 0.4); tween(view.tz, 0.0, 0.4);'); } catch (e) { /* egal */ }
if (btn) btn.classList.remove('active');
walkHint(false);
walkShowPad(false);
}
}
window.walkToggle = walkToggle;
// Bewegungsrichtung setzen (fuer On-Screen-Steuerung + Touch).
function walkSet(dir, on) {
const k = walkKrpano();
try { k.set('walkaround.' + dir, on ? 1 : 0); } catch (e) { /* egal */ }
}
function walkStopAll() {
['forward', 'backward', 'left', 'right'].forEach(d => walkSet(d, 0));
}
// Sichtbare Geh-Steuerung (Steuerkreuz) — macht Bewegung offensichtlich,
// funktioniert auch auf Touch-Geraeten ohne Tastatur.
function walkShowPad(show) {
let pad = document.getElementById('walk-pad');
if (show) {
if (pad) { pad.style.display = 'grid'; return; }
pad = document.createElement('div');
pad.id = 'walk-pad';
const defs = [
['forward', '▲', 'gf'], ['left', '◀', 'gl'], ['right', '▶', 'gr'], ['backward', '▼', 'gb'],
];
defs.forEach(([dir, glyph, cls]) => {
const btnEl = document.createElement('button');
btnEl.className = 'walk-pad-btn ' + cls;
btnEl.textContent = glyph;
const start = (e) => { e.preventDefault(); walkSet(dir, true); };
const stop = (e) => { e.preventDefault(); walkSet(dir, false); };
btnEl.addEventListener('pointerdown', start);
btnEl.addEventListener('pointerup', stop);
btnEl.addEventListener('pointerleave', stop);
btnEl.addEventListener('pointercancel', stop);
pad.appendChild(btnEl);
});
document.body.appendChild(pad);
} else if (pad) {
pad.style.display = 'none';
}
}
function walkHint(show) {
let h = document.getElementById('walk-hint');
if (show) {
if (!h) {
h = document.createElement('div');
h.id = 'walk-hint';
document.body.appendChild(h);
}
h.textContent = walkText(
'Begehen-Modus — mit den Pfeilen (oder WASD) gehen · ziehen zum Umsehen · Szenen anklicken für den nächsten Raum',
'Walk mode — walk with the arrows (or WASD) · drag to look · click scenes for the next room');
h.style.display = 'block';
} else if (h) {
h.style.display = 'none';
}
}
function walkInit() {
const tryInit = (attempt) => {
const k = walkKrpano();
if (!k || !k.get) {
if (attempt < 40) setTimeout(() => tryInit(attempt + 1), 500);
return;
}
if (document.getElementById('walk-button')) return;
// Sicherheitshalber Tasten der Navigation deaktivieren (nur Walk-Modus schaltet sie scharf).
walkSetKeys(false);
const btn = document.createElement('div');
btn.id = 'walk-button';
btn.title = walkText('Begehen — durch die Wohnung gehen', 'Walk — move through the apartment');
btn.innerHTML = '<i class="mdi mdi-walk"></i><span>' + walkText('Gehen', 'Walk') + '</span>';
btn.addEventListener('click', walkToggle);
document.body.appendChild(btn);
console.log('Walk: ready');
};
tryInit(0);
}
window.walkInit = walkInit;
walkInit();