fix: preserve calibration draft on refresh

This commit is contained in:
Yoilun
2026-04-27 12:55:46 +08:00
parent cda586a197
commit be3d2ac3af

View File

@@ -2,6 +2,7 @@ import "./styles.css";
const zoneIds = ["r1c1", "r1c2", "r1c3", "r1c4", "r2c1", "r2c2", "r2c3", "r2c4"]; const zoneIds = ["r1c1", "r1c2", "r1c3", "r1c4", "r2c1", "r2c2", "r2c3", "r2c4"];
const allRegions = [...zoneIds, "trash"]; const allRegions = [...zoneIds, "trash"];
const draftStorageKey = "cold-display-guard.calibrationDraft.v1";
const palette = { const palette = {
r1c1: "#d92d20", r1c1: "#d92d20",
r1c2: "#b54708", r1c2: "#b54708",
@@ -133,6 +134,7 @@ const ctx = els.canvas.getContext("2d");
function boot() { function boot() {
wireEvents(); wireEvents();
loadDraftPolygons();
renderRegionList(); renderRegionList();
refreshAll(); refreshAll();
} }
@@ -164,7 +166,9 @@ async function refreshAll() {
state.summary = summary; state.summary = summary;
state.events = events.items || []; state.events = events.items || [];
fillForm(); fillForm();
loadPolygonsFromConfig(false); if (!hasAnyPolygon()) {
loadPolygonsFromConfig(false);
}
render(); render();
setStatus("已连接后端 19080"); setStatus("已连接后端 19080");
} catch (error) { } catch (error) {
@@ -185,6 +189,7 @@ async function saveConfig() {
}; };
state.config = await apiJson("/api/manage/config", {method: "PUT", body: payload}); state.config = await apiJson("/api/manage/config", {method: "PUT", body: payload});
const calibrationSaved = await persistCalibration({requireAny: false}); const calibrationSaved = await persistCalibration({requireAny: false});
saveDraftPolygons();
fillForm(); fillForm();
renderConfigPreview(); renderConfigPreview();
setStatus(calibrationSaved ? "配置和标定已保存" : "配置已保存;当前没有可保存的标定点"); setStatus(calibrationSaved ? "配置和标定已保存" : "配置已保存;当前没有可保存的标定点");
@@ -228,6 +233,7 @@ async function saveCalibration() {
try { try {
const saved = await persistCalibration({requireAny: true}); const saved = await persistCalibration({requireAny: true});
if (saved) { if (saved) {
saveDraftPolygons();
render(); render();
setStatus("标定已保存到项目配置"); setStatus("标定已保存到项目配置");
} }
@@ -289,6 +295,7 @@ function loadPolygonsFromConfig(updateStatus = true) {
if (Array.isArray(state.config.trash?.roi)) { if (Array.isArray(state.config.trash?.roi)) {
state.polygons.trash = state.config.trash.roi.map(([x, y]) => ({x, y})); state.polygons.trash = state.config.trash.roi.map(([x, y]) => ({x, y}));
} }
saveDraftPolygons();
render(); render();
if (updateStatus) { if (updateStatus) {
setStatus("已载入当前配置区域"); setStatus("已载入当前配置区域");
@@ -335,6 +342,7 @@ function addPoint(event) {
const x = clamp(rawX / imageRect.width); const x = clamp(rawX / imageRect.width);
const y = clamp(rawY / imageRect.height); const y = clamp(rawY / imageRect.height);
state.polygons[state.activeRegion].push({x: round(x), y: round(y)}); state.polygons[state.activeRegion].push({x: round(x), y: round(y)});
saveDraftPolygons();
render(); render();
} }
@@ -362,14 +370,44 @@ function getCanvasImageRect() {
function undoPoint() { function undoPoint() {
state.polygons[state.activeRegion].pop(); state.polygons[state.activeRegion].pop();
saveDraftPolygons();
render(); render();
} }
function clearRegion() { function clearRegion() {
state.polygons[state.activeRegion] = []; state.polygons[state.activeRegion] = [];
saveDraftPolygons();
render(); render();
} }
function hasAnyPolygon() {
return allRegions.some((id) => state.polygons[id].length > 0);
}
function saveDraftPolygons() {
localStorage.setItem(draftStorageKey, JSON.stringify(state.polygons));
}
function loadDraftPolygons() {
const raw = localStorage.getItem(draftStorageKey);
if (!raw) {
return;
}
try {
const draft = JSON.parse(raw);
for (const id of allRegions) {
if (!Array.isArray(draft[id])) {
continue;
}
state.polygons[id] = draft[id]
.filter((point) => Number.isFinite(point.x) && Number.isFinite(point.y))
.map((point) => ({x: clamp(point.x), y: clamp(point.y)}));
}
} catch {
localStorage.removeItem(draftStorageKey);
}
}
function drawCanvas() { function drawCanvas() {
ctx.clearRect(0, 0, els.canvas.width, els.canvas.height); ctx.clearRect(0, 0, els.canvas.width, els.canvas.height);
if (state.image) { if (state.image) {