-
Notifications
You must be signed in to change notification settings - Fork 331
Open
Description
See #809 for idea from @stuarteberg. Opened issue here just to keep track. I think something like the below is probably in the right direction
Screencast.from.2025-07-21.10-47-11.mp4
For example, changing the visitTransformedAnnotationGeometry
call in src/ui/annotations.ts
to something like this would allow changing point annotations in the UI
visitTransformedAnnotationGeometry(
annotation,
chunkTransform as ChunkTransformParameters,
(layerPosition, isVector) => {
const copyButton = makeCopyButton({
title: "Copy position",
onClick: () => {
setClipboard(layerPosition.map((x) => Math.floor(x)).join(", "));
},
});
copyButton.style.gridColumn = "copy";
positionGrid.appendChild(copyButton);
for (let layerDim = 0; layerDim < layerRank; ++layerDim) {
const coordElement = document.createElement("input");
coordElement.classList.add(
"neuroglancer-selected-annotation-details-position-coord",
);
coordElement.style.gridColumn = `coord ${layerDim + 1}`;
coordElement.value = Math.floor(layerPosition[layerDim]).toString();
coordElement.addEventListener("change", (event) => {
const input = event.target as HTMLInputElement;
const value = parseFloat(input.value);
if (isNaN(value)) return;
const newLayerPosition = new Float32Array(layerPosition.length);
for (let i = 0; i < layerPosition.length; ++i) {
newLayerPosition[i] = layerPosition[i];
}
newLayerPosition[layerDim] = value;
const newAnnotation = reference.value;
if (!newAnnotation) return;
if (newAnnotation.type === AnnotationType.POINT) {
// TODO consider to refactor the visitTransformedAnnotationGeometry
// This is basically the same operation but using the inverse transform
// Also to handle other annotation types
// Annotations that are not points are more complex
// because they need to know which piece of geometry
// is being updated
const toChunkTransform = (chunkTransform as ChunkTransformParameters)
.layerToChunkTransform;
const { layerRank } = chunkTransform as ChunkTransformParameters;
const paddedChunkPosition = new Float32Array(layerRank);
paddedChunkPosition.set(newLayerPosition, 0);
const layerSourcePosition = new Float32Array(layerRank);
(isVector ? matrix.transformVector : matrix.transformPoint)(
layerSourcePosition,
toChunkTransform,
layerRank + 1,
paddedChunkPosition,
layerRank,
);
newAnnotation.point = layerSourcePosition;
}
annotationLayer.source.update(reference, newAnnotation);
annotationLayer.source.commit(reference);
});
positionGrid.appendChild(coordElement);
}
if (!isVector) {
const moveButton = makeMoveToButton({
title: "Move to position",
onClick: () => {
setLayerPosition(this, chunkTransform, layerPosition);
},
});
moveButton.style.gridColumn = "move";
positionGrid.appendChild(moveButton);
}
},
);
stuarteberg
Metadata
Metadata
Assignees
Labels
No labels