Homing-Bild

This commit is contained in:
chk
2026-06-10 11:05:39 +02:00
parent 07dee473ab
commit 4d9d7868f3
2 changed files with 36 additions and 65 deletions

View File

@@ -284,48 +284,45 @@ async function onCalculateClick() {
// ── Foto ─────────────────────────────────────────────────────────────────────
/**
* Kameraliste vom Backend holen und <select id="cam-select"> befüllen.
* Schlägt das Laden fehl, bleiben die hardkodierten Fallback-Optionen erhalten.
*/
async function loadCameras() {
const select = document.getElementById('cam-select');
if (!select) return;
try {
const res = await fetch('/api/webcam/cameras');
if (!res.ok) return;
const { cameras } = await res.json();
select.innerHTML = cameras
.map(c => `<option value="${c.id}">${c.id} (${c.position || c.name})</option>`)
.join('');
} catch {
// Fallback: hardkodierte Optionen aus index.html bleiben erhalten
}
}
/**
* Foto-Button: holt ein HD-JPEG der gewählten Kamera und zeigt es an.
* Der Endpoint /api/webcam/snapshot/:id liefert das JPEG direkt (kein base64).
* Foto-Button: holt HD-JPEGs aller 3 Kameras parallel
* und zeigt sie nebeneinander im Snapshot-Bereich an.
*/
async function onFotoClick() {
const camId = document.getElementById('cam-select')?.value || 'cam0';
const display = document.getElementById('foto-display');
const display = document.getElementById('snapshot-info-picture');
if (!display) return;
appendLog(`Foto: ${camId}`);
const camIds = ['cam0', 'cam1', 'cam2'];
const labels = { cam0: 'front', cam1: 'left', cam2: 'right' };
appendLog('Foto: alle Kameras …');
// Cache-Buster über Timestamp-Parameter, damit der Browser nicht aus dem Cache lädt
const url = `/api/webcam/snapshot/${camId}?t=${Date.now()}`;
const t = Date.now();
const img = document.createElement('img');
img.style.maxWidth = '100%';
img.style.height = 'auto';
img.alt = camId;
img.onload = () => appendLog(`Foto ${camId}: OK (${img.naturalWidth}×${img.naturalHeight}px)`);
img.onerror = () => appendLog(`Foto ${camId}: Fehler beim Laden`);
img.src = url;
// Wrapper mit 3 Spalten
const wrapper = document.createElement('div');
wrapper.style.cssText = 'display:flex; gap:6px; align-items:flex-start;';
camIds.forEach(id => {
const col = document.createElement('div');
col.style.cssText = 'flex:1 1 0; min-width:0;';
const caption = document.createElement('div');
caption.style.cssText = 'font-size:0.8em; margin-bottom:3px; color:#aaa;';
caption.textContent = `${id} (${labels[id]})`;
const img = document.createElement('img');
img.style.cssText = 'width:100%; height:auto; display:block;';
img.alt = id;
img.onload = () => appendLog(` ${id}: ${img.naturalWidth}×${img.naturalHeight}px`);
img.onerror = () => appendLog(` ${id}: Fehler`);
img.src = `/api/webcam/snapshot/${id}?t=${t}`;
col.appendChild(caption);
col.appendChild(img);
wrapper.appendChild(col);
});
display.innerHTML = '';
display.appendChild(img);
display.appendChild(wrapper);
}
async function onCommandClick(btn) {
@@ -364,8 +361,6 @@ function setupUi() {
btn.addEventListener("click", () => onCommandClick(btn));
});
// Kameraliste vom Backend laden (befüllt #cam-select dynamisch)
loadCameras();
// ===== SECTION COLLAPSE/EXPAND =====
document.querySelectorAll(".section h2").forEach(heading => {

View File

@@ -9,12 +9,9 @@
</head>
<body>
<!-- Optionaler Titel (bewusst neutral, leicht ausblendbar) -->
<!--<h1 class="app-title">appRobotHoming</h1>-->
<div class="sections">
<!-- ACTIONS -->
<!-- AKTIONEN -->
<div class="section full">
<h2>Aktionen</h2>
@@ -34,26 +31,11 @@
<button id="btn-calculate">Read Position from Markers</button>
<select id="cam-select" title="Kamera wählen">
<option value="cam0">cam0 (front)</option>
<option value="cam1">cam1 (left)</option>
<option value="cam2">cam2 (right)</option>
</select>
<button id="btn-foto">Foto</button>
<a href="/calibration.html">
<button type="button">Calibration Page</button>
</a>
</div>
</div>
<!-- FOTO DISPLAY -->
<div class="section full">
<h2>Foto</h2>
<div id="foto-display"></div>
</div>
<!-- AUSGABE / LOG (default collapsed) -->
<!-- AUSGABE / LOG -->
<div class="section full">
<h2>Ausgabe</h2>
<textarea id="log" readonly></textarea>
@@ -68,7 +50,6 @@
<!-- RESULT RAW JSON -->
<div class="section half">
<h2>Result Raw JSON</h2>
<div class="panel">
<label>Raw JSON</label>
<textarea id="result-json" readonly></textarea>
@@ -78,15 +59,13 @@
<!-- RESULT TREE VIEW -->
<div class="section half">
<h2>Result Tree View</h2>
<!-- bewusst alte Struktur beibehalten -->
<div class="panel">
<label>Tree View</label>
<div id="result-tree"></div>
</div>
</div>
<!-- SNAPSHOT (vorbereitet, aber leer) -->
<!-- SNAPSHOT -->
<div class="section full">
<h2>Snapshot CSV</h2>
<div id="snapshot-info"></div>
@@ -94,17 +73,14 @@
</div>
<div class="section full">
<h2>Snapshot</h2>
<h2>Snapshots</h2>
<div id="snapshot-info-picture"></div>
</div>
</div>
<!--<script src="/calculateActions.js"></script> -->
<script src="/calculateAngles.js"></script>
<script src="/client.js"></script>
</body>
</html>