path change
This commit is contained in:
@@ -15,6 +15,8 @@ import { DeleteConfirmModal } from "../components/annotate/DeleteConfirmModal";
|
|||||||
import { drawOverlay, colorForClass } from "../components/extract/overlay";
|
import { drawOverlay, colorForClass } from "../components/extract/overlay";
|
||||||
import type { Settings } from "../types";
|
import type { Settings } from "../types";
|
||||||
|
|
||||||
|
const DEFAULT_CLASS_ID = 0;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
username: string;
|
username: string;
|
||||||
settings: Settings | null;
|
settings: Settings | null;
|
||||||
@@ -30,10 +32,10 @@ type Tool = "select" | "bbox" | "polygon";
|
|||||||
type InProgress =
|
type InProgress =
|
||||||
| { type: "bbox"; start: [number, number]; end: [number, number] }
|
| { type: "bbox"; start: [number, number]; end: [number, number] }
|
||||||
| {
|
| {
|
||||||
type: "polygon";
|
type: "polygon";
|
||||||
points: [number, number][];
|
points: [number, number][];
|
||||||
cursor: [number, number] | null;
|
cursor: [number, number] | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BboxHandle = "body" | "tl" | "tr" | "bl" | "br" | "t" | "b" | "l" | "r";
|
type BboxHandle = "body" | "tl" | "tr" | "bl" | "br" | "t" | "b" | "l" | "r";
|
||||||
|
|
||||||
@@ -63,7 +65,7 @@ function uuid(): string {
|
|||||||
try {
|
try {
|
||||||
const c = (globalThis as unknown as { crypto?: { randomUUID?: () => string } }).crypto;
|
const c = (globalThis as unknown as { crypto?: { randomUUID?: () => string } }).crypto;
|
||||||
if (c && typeof c.randomUUID === "function") return c.randomUUID();
|
if (c && typeof c.randomUUID === "function") return c.randomUUID();
|
||||||
} catch {}
|
} catch { }
|
||||||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (ch) => {
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (ch) => {
|
||||||
const r = (Math.random() * 16) | 0;
|
const r = (Math.random() * 16) | 0;
|
||||||
const v = ch === "x" ? r : (r & 0x3) | 0x8;
|
const v = ch === "x" ? r : (r & 0x3) | 0x8;
|
||||||
@@ -392,15 +394,15 @@ export function AnnotateMode({ username, settings }: Props) {
|
|||||||
if (cancelled) return;
|
if (cancelled) return;
|
||||||
setAnn(
|
setAnn(
|
||||||
loaded ??
|
loaded ??
|
||||||
(dims
|
(dims
|
||||||
? {
|
? {
|
||||||
version: 1,
|
version: 1,
|
||||||
image: selectedImagePath.split("/").pop() ?? "",
|
image: selectedImagePath.split("/").pop() ?? "",
|
||||||
width: dims.w,
|
width: dims.w,
|
||||||
height: dims.h,
|
height: dims.h,
|
||||||
annotations: [],
|
annotations: [],
|
||||||
}
|
}
|
||||||
: null)
|
: null)
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
@@ -420,7 +422,7 @@ export function AnnotateMode({ username, settings }: Props) {
|
|||||||
// Hold a ref to the latest drawCanvas so the image-change effect can call
|
// Hold a ref to the latest drawCanvas so the image-change effect can call
|
||||||
// it without subscribing to its identity (which flips on every `drawing` /
|
// it without subscribing to its identity (which flips on every `drawing` /
|
||||||
// `ann` / `overlayVisible` change and would reset state mid-interaction).
|
// `ann` / `overlayVisible` change and would reset state mid-interaction).
|
||||||
const drawCanvasRef = useRef<() => void>(() => {});
|
const drawCanvasRef = useRef<() => void>(() => { });
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
drawCanvasRef.current = drawCanvas;
|
drawCanvasRef.current = drawCanvas;
|
||||||
}, [drawCanvas]);
|
}, [drawCanvas]);
|
||||||
@@ -745,12 +747,12 @@ export function AnnotateMode({ username, settings }: Props) {
|
|||||||
annotations: ann.annotations.map((a) =>
|
annotations: ann.annotations.map((a) =>
|
||||||
a.id === selectedAnnId
|
a.id === selectedAnnId
|
||||||
? {
|
? {
|
||||||
...a,
|
...a,
|
||||||
class_id: cid,
|
class_id: cid,
|
||||||
class_name: className,
|
class_name: className,
|
||||||
author: username,
|
author: username,
|
||||||
updated_at: now,
|
updated_at: now,
|
||||||
}
|
}
|
||||||
: a
|
: a
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@@ -761,7 +763,7 @@ export function AnnotateMode({ username, settings }: Props) {
|
|||||||
return (
|
return (
|
||||||
classesRef.current[classId] ??
|
classesRef.current[classId] ??
|
||||||
classes[classId] ??
|
classes[classId] ??
|
||||||
`class_${classId}`
|
"Object"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -940,10 +942,12 @@ export function AnnotateMode({ username, settings }: Props) {
|
|||||||
setSelectedAnnId(null);
|
setSelectedAnnId(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (activeClassId == null) {
|
// if (activeClassId == null) {
|
||||||
setStatusMsg("Pick a class on the right first");
|
// setStatusMsg("Pick a class on the right first");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
const classId = activeClassId ?? DEFAULT_CLASS_ID;
|
||||||
|
|
||||||
e.stopPropagation(); // don't let the pan handler see this
|
e.stopPropagation(); // don't let the pan handler see this
|
||||||
const p = canvasToImageCoords(e.clientX, e.clientY);
|
const p = canvasToImageCoords(e.clientX, e.clientY);
|
||||||
if (!p) return;
|
if (!p) return;
|
||||||
@@ -1343,8 +1347,8 @@ export function AnnotateMode({ username, settings }: Props) {
|
|||||||
tool === "bbox" || tool === "polygon"
|
tool === "bbox" || tool === "polygon"
|
||||||
? "crosshair"
|
? "crosshair"
|
||||||
: zoom > 1
|
: zoom > 1
|
||||||
? "grab"
|
? "grab"
|
||||||
: "default";
|
: "default";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`annotate-mode${frameInfoHidden ? " frame-info-hidden" : ""}`}>
|
<div className={`annotate-mode${frameInfoHidden ? " frame-info-hidden" : ""}`}>
|
||||||
@@ -1524,8 +1528,8 @@ export function AnnotateMode({ username, settings }: Props) {
|
|||||||
pending.kind === "new-bbox"
|
pending.kind === "new-bbox"
|
||||||
? "new-bbox"
|
? "new-bbox"
|
||||||
: pending.kind === "new-polygon"
|
: pending.kind === "new-polygon"
|
||||||
? "new-polygon"
|
? "new-polygon"
|
||||||
: "reclass"
|
: "reclass"
|
||||||
}
|
}
|
||||||
onConfirm={(cid) => {
|
onConfirm={(cid) => {
|
||||||
commitPending(cid);
|
commitPending(cid);
|
||||||
@@ -1773,9 +1777,9 @@ function drawBboxHandles(
|
|||||||
const [x, y, w, h] = bbox;
|
const [x, y, w, h] = bbox;
|
||||||
const r = Math.max(5, 5 * screenToImage);
|
const r = Math.max(5, 5 * screenToImage);
|
||||||
const pts: [number, number][] = [
|
const pts: [number, number][] = [
|
||||||
[x, y], [x + w / 2, y], [x + w, y],
|
[x, y], [x + w / 2, y], [x + w, y],
|
||||||
[x, y + h / 2], [x + w, y + h / 2],
|
[x, y + h / 2], [x + w, y + h / 2],
|
||||||
[x, y + h], [x + w / 2, y + h], [x + w, y + h],
|
[x, y + h], [x + w / 2, y + h], [x + w, y + h],
|
||||||
];
|
];
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.setLineDash([]);
|
ctx.setLineDash([]);
|
||||||
@@ -1810,16 +1814,16 @@ function annotationsToShapes(annotations: Annotation[]): CocoShape[] {
|
|||||||
return annotations.map((a) =>
|
return annotations.map((a) =>
|
||||||
a.type === "bbox"
|
a.type === "bbox"
|
||||||
? {
|
? {
|
||||||
type: "bbox",
|
type: "bbox",
|
||||||
class_id: a.class_id,
|
class_id: a.class_id,
|
||||||
class_name: a.class_name,
|
class_name: a.class_name,
|
||||||
bbox: a.bbox,
|
bbox: a.bbox,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
type: "polygon",
|
type: "polygon",
|
||||||
class_id: a.class_id,
|
class_id: a.class_id,
|
||||||
class_name: a.class_name,
|
class_name: a.class_name,
|
||||||
points: a.points,
|
points: a.points,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user