fix: enable overlay drag interaction; tidy dead export and residual readout

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
sjat 2026-06-08 22:57:03 +02:00
parent fac9168c00
commit 3538d5ccb9
3 changed files with 9 additions and 7 deletions

View file

@ -58,7 +58,7 @@ export function mountCalibration(deps: CalibrationDeps): void {
const renderList = (errs?: number[]) => {
list.innerHTML = points
.map((p, i) => `<li>(${p.machine[0]}, ${p.machine[1]}) → img(${p.image[0].toFixed(3)}, ${p.image[1].toFixed(3)})${errs ? ` <small>err ${(errs[i]! * overlay.width).toFixed(1)}px</small>` : ''}</li>`)
.map((p, i) => `<li>(${p.machine[0]}, ${p.machine[1]}) → img(${p.image[0].toFixed(3)}, ${p.image[1].toFixed(3)})${errs ? ` <small>err ${errs[i]!.toFixed(1)}px</small>` : ''}</li>`)
.join('');
};
@ -100,8 +100,12 @@ export function mountCalibration(deps: CalibrationDeps): void {
const machine = points.map((p) => p.machine);
const image = points.map((p) => p.image);
const H = estimateHomography(machine, image);
const errs = residuals(H, machine, image);
renderList(errs);
// Per-axis pixel residual (normalized error scaled by canvas width/height) — used only for misclick display.
const errsPx = machine.map((m, i) => {
const p = applyHomography(H, m);
return Math.hypot((p[0] - image[i]![0]) * overlay.width, (p[1] - image[i]![1]) * overlay.height);
});
renderList(errsPx);
jsonEl.value = JSON.stringify(
{ imagePoints: image, machinePoints: machine, homography: H },
null,

View file

@ -47,8 +47,6 @@ fileInput.addEventListener('change', async () => {
render();
});
// expose for the UI modules added in later tasks
export const app = { state, render, resize, overlay, stage, stream };
mountCalibration({
panel: document.getElementById('calib-panel') as HTMLElement,

View file

@ -2,8 +2,8 @@
body { margin: 0; display: flex; height: 100vh; font-family: system-ui, sans-serif; background: #111; color: #eee; }
#stage { position: relative; flex: 1; overflow: hidden; background: #000; }
#stream { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
#overlay { position: absolute; pointer-events: none; }
#overlay.interactive { pointer-events: auto; cursor: crosshair; }
#overlay { position: absolute; pointer-events: auto; cursor: default; }
#overlay.interactive { cursor: crosshair; }
#panel { width: 320px; padding: 16px; overflow-y: auto; background: #1b1b1b; }
#panel h1 { font-size: 16px; }
.filebtn { display: inline-block; padding: 8px 12px; background: #2962ff; border-radius: 4px; cursor: pointer; }