add simple annotation navigation

This commit is contained in:
Ross
2025-06-03 16:22:01 +01:00
parent c21fe2cbd7
commit cdbe31df6b
+125
View File
@@ -1455,6 +1455,7 @@ function App({ container_id, imageStacks, autoCacheStack, ...props }: AppProps)
const numVisible = viewportGrid.rows * viewportGrid.cols;
const viewports = [];
//for (let i = 0; i < MAX_VIEWPORTS; i++) {
// Viewports rendering loop
for (let i = 0; i < numVisible; i++) {
// Determine if this viewport should be visible in the current grid
const isVisible = i < viewportGrid.rows * viewportGrid.cols;
@@ -1640,6 +1641,103 @@ function App({ container_id, imageStacks, autoCacheStack, ...props }: AppProps)
</span>
)}
</button>
// Annotations buttons
{viewportModes[i] === "stack" && (() => {
// Get all annotations for this stack
const imageIds = viewportImageIds[i];
const allAnnotations = cornerstoneTools.annotation.state.getAllAnnotations() || [];
const stackAnnotations = allAnnotations.filter(
ann =>
ann.metadata &&
ann.metadata.referencedImageId &&
imageIds.includes(ann.metadata.referencedImageId)
);
if (!stackAnnotations.length) return null;
return (
<div
style={{
position: "absolute",
left: "50%",
bottom: 60,
transform: "translateX(-50%)",
zIndex: 30,
display: "flex",
gap: 4,
pointerEvents: "auto",
}}
>
<button
style={{
background: "rgba(30,30,30,0.7)",
color: "#fff",
border: "none",
borderRadius: "50%",
width: 28,
height: 28,
fontSize: "16px",
fontWeight: "bold",
cursor: "pointer",
opacity: 0.7,
display: "flex",
alignItems: "center",
justifyContent: "center",
boxShadow: "0 1px 4px rgba(0,0,0,0.18)",
transition: "opacity 0.2s",
}}
title="Previous Annotation"
aria-label="Previous Annotation"
onClick={() => {
const renderingEngine = renderingEngineRef.current;
const viewport = renderingEngine?.getViewport(`CT_${i}`);
if (!viewport || typeof viewport.getCurrentImageIdIndex !== "function") return;
const currentIdx = viewport.getCurrentImageIdIndex();
const prevIdx = findNextAnnotationIdx(currentIdx, imageIds, stackAnnotations, -1);
if (prevIdx !== null && typeof viewport.setImageIdIndex === "function") {
csUtilities.jumpToSlice(viewport.element, { imageIndex: prevIdx });
updateOverlay(i, viewport);
}
}}
>
<span aria-hidden="true"></span>
</button>
<button
style={{
background: "rgba(30,30,30,0.7)",
color: "#fff",
border: "none",
borderRadius: "50%",
width: 28,
height: 28,
fontSize: "16px",
fontWeight: "bold",
cursor: "pointer",
opacity: 0.7,
display: "flex",
alignItems: "center",
justifyContent: "center",
boxShadow: "0 1px 4px rgba(0,0,0,0.18)",
transition: "opacity 0.2s",
}}
title="Next Annotation"
aria-label="Next Annotation"
onClick={() => {
const renderingEngine = renderingEngineRef.current;
const viewport = renderingEngine?.getViewport(`CT_${i}`);
if (!viewport || typeof viewport.getCurrentImageIdIndex !== "function") return;
const currentIdx = viewport.getCurrentImageIdIndex();
const nextIdx = findNextAnnotationIdx(currentIdx, imageIds, stackAnnotations, 1);
if (nextIdx !== null && typeof viewport.setImageIdIndex === "function") {
csUtilities.jumpToSlice(viewport.element, { imageIndex: nextIdx });
updateOverlay(i, viewport);
}
}}
>
<span aria-hidden="true"></span>
</button>
</div>
);
})()}
// ...existing code...
{/* Overlay info (bottom left of viewport) */}
<div
style={{
@@ -2693,3 +2791,30 @@ function setupTools(MAIN_TOOL_GROUP_ID) {
return mainToolGroup;
}
// Add this helper to find the next/previous annotation index for the current viewport
function findNextAnnotationIdx(currentIdx: number, imageIds: string[], annotations: any[], direction: 1 | -1) {
if (!annotations.length || !imageIds.length) return null;
// Find all annotation indices in this stack
const annIndices = annotations
.map(ann => imageIds.findIndex(id => id === ann.metadata.referencedImageId))
.filter(idx => idx !== -1)
.sort((a, b) => a - b);
if (!annIndices.length) return null;
// Find the next/prev annotation index
if (direction === 1) {
// Next
for (let idx of annIndices) {
if (idx > currentIdx) return idx;
}
return annIndices[0]; // wrap around
} else {
// Previous
for (let i = annIndices.length - 1; i >= 0; i--) {
if (annIndices[i] < currentIdx) return annIndices[i];
}
return annIndices[annIndices.length - 1]; // wrap around
}
}