Homing-Bild
This commit is contained in:
@@ -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 => {
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user