diff --git a/apps/desktop/src/pages/Viewer/ModelViewer/index.tsx b/apps/desktop/src/pages/Viewer/ModelViewer/index.tsx
new file mode 100644
index 0000000..9c9e16c
--- /dev/null
+++ b/apps/desktop/src/pages/Viewer/ModelViewer/index.tsx
@@ -0,0 +1,3 @@
+export const Model3DViewer = () => {
+ return
3d model
;
+};
diff --git a/apps/desktop/src/pages/Viewer/MprViewer/Crosshair.tsx b/apps/desktop/src/pages/Viewer/MprViewer/Crosshair.tsx
deleted file mode 100644
index 87d9a80..0000000
--- a/apps/desktop/src/pages/Viewer/MprViewer/Crosshair.tsx
+++ /dev/null
@@ -1,246 +0,0 @@
-import { useEffect, useRef } from "react";
-import * as cornerstoneTools from "@cornerstonejs/tools";
-import { PublicViewportInput } from "@cornerstonejs/core/dist/types/types/IViewport.js";
-import setCtTransferFunctionForVolumeActor from "./CornerstoneDicomLoader/setCtTransferFunctionForVolumeActor";
-import {
- RenderingEngine,
- setVolumesForViewports,
- Enums as CoreEnums,
-} from "@cornerstonejs/core";
-import {
- viewportColors,
- viewportReferenceLineControllable,
- viewportReferenceLineDraggableRotatable,
- viewportReferenceLineSlabThicknessControlsOn,
- viewportId1,
- viewportId2,
- viewportId3,
- ViewportId,
-} from "./Crosshair.config";
-
-const {
- ToolGroupManager,
- CrosshairsTool,
- StackScrollMouseWheelTool,
- WindowLevelTool,
- ZoomTool,
- Enums: csToolsEnums,
-} = cornerstoneTools;
-
-const { MouseBindings } = csToolsEnums;
-
-const { ViewportType } = CoreEnums;
-
-function getReferenceLineColor(vpId: ViewportId) {
- return viewportColors[vpId];
-}
-
-function getReferenceLineControllable(vpId: ViewportId) {
- const index = viewportReferenceLineControllable.indexOf(vpId);
- return index !== -1;
-}
-
-function getReferenceLineDraggableRotatable(vpId: ViewportId) {
- const index = viewportReferenceLineDraggableRotatable.indexOf(vpId);
- return index !== -1;
-}
-
-function getReferenceLineSlabThicknessControlsOn(vpId: ViewportId) {
- const index = viewportReferenceLineSlabThicknessControlsOn.indexOf(vpId);
- return index !== -1;
-}
-
-interface CrosshairMprProps {
- wwwl: {
- windowCenter: number;
- windowWidth: number;
- };
- volumeId: string;
-}
-
-export const CrosshairMpr = (props: CrosshairMprProps) => {
- const containerRef = useRef(null);
- const viewportRef_AXIAL = useRef(null);
- const viewportRef_SAGITTAL = useRef(null);
- const viewportRef_CORONAL = useRef(null);
- const renderingEngine = useRef();
- const toolGroupRef = useRef(
- undefined
- );
- const ts = "-" + Date.now();
- const toolGroupId = "mprToolGroup" + ts;
- const renderingEngineId = "mprRenderingEngine" + ts;
-
- useEffect(() => {
- cornerstoneTools.addTool(StackScrollMouseWheelTool);
- cornerstoneTools.addTool(CrosshairsTool);
- cornerstoneTools.addTool(WindowLevelTool);
- cornerstoneTools.addTool(ZoomTool);
-
- toolGroupRef.current = ToolGroupManager.createToolGroup(toolGroupId);
-
- const run = async () => {
- if (
- !viewportRef_AXIAL.current ||
- !viewportRef_SAGITTAL.current ||
- !viewportRef_CORONAL.current
- )
- return;
-
- renderingEngine.current = new RenderingEngine(renderingEngineId);
-
- // Create the viewports
- const viewportInputArray: PublicViewportInput[] = [
- {
- viewportId: viewportId1,
- type: ViewportType.ORTHOGRAPHIC,
- element: viewportRef_AXIAL.current,
- defaultOptions: {
- orientation: CoreEnums.OrientationAxis.AXIAL,
- background: [0, 0, 0],
- },
- },
- {
- viewportId: viewportId2,
- type: ViewportType.ORTHOGRAPHIC,
- element: viewportRef_SAGITTAL.current,
- defaultOptions: {
- orientation: CoreEnums.OrientationAxis.SAGITTAL,
- background: [0, 0, 0],
- },
- },
- {
- viewportId: viewportId3,
- type: ViewportType.ORTHOGRAPHIC,
- element: viewportRef_CORONAL.current,
- defaultOptions: {
- orientation: CoreEnums.OrientationAxis.CORONAL,
- background: [0, 0, 0],
- },
- },
- ];
-
- renderingEngine.current.setViewports(viewportInputArray);
-
- // Set volumes on the viewports
- await setVolumesForViewports(
- renderingEngine.current,
- [
- {
- volumeId: props.volumeId,
- callback: ({ volumeActor }) =>
- setCtTransferFunctionForVolumeActor({
- volumeActor,
- defaultWindowCenter: props.wwwl.windowCenter,
- defaultWindowWidth: props.wwwl.windowWidth,
- }),
- },
- ],
- [viewportId1, viewportId2, viewportId3]
- );
-
- if (toolGroupRef.current) {
- // For the crosshairs to operate, the viewports must currently be
- // added ahead of setting the tool active. This will be improved in the future.
- toolGroupRef.current.addViewport(viewportId1, renderingEngineId);
- toolGroupRef.current.addViewport(viewportId2, renderingEngineId);
- toolGroupRef.current.addViewport(viewportId3, renderingEngineId);
-
- /**
- * zoom影像
- */
- toolGroupRef.current.addTool(ZoomTool.toolName);
- toolGroupRef.current.setToolActive(ZoomTool.toolName, {
- bindings: [
- {
- mouseButton: MouseBindings.Secondary, // 鼠标中键
- },
- ],
- });
-
- // Manipulation Tools
- toolGroupRef.current.addTool(StackScrollMouseWheelTool.toolName);
- // Add Crosshairs tool and configure it to link the three viewports
- // These viewports could use different tool groups. See the PET-CT example
- // for a more complicated used case.
-
- toolGroupRef.current.addTool(CrosshairsTool.toolName, {
- getReferenceLineColor,
- getReferenceLineControllable,
- getReferenceLineDraggableRotatable,
- getReferenceLineSlabThicknessControlsOn,
- });
-
- toolGroupRef.current.setToolActive(CrosshairsTool.toolName, {
- bindings: [{ mouseButton: 1 }],
- });
- // As the Stack Scroll mouse wheel is a tool using the `mouseWheelCallback`
- // hook instead of mouse buttons, it does not need to assign any mouse button.
- toolGroupRef.current.setToolActive(StackScrollMouseWheelTool.toolName);
-
- toolGroupRef.current.addTool(WindowLevelTool.toolName);
- toolGroupRef.current.setToolActive(WindowLevelTool.toolName, {
- bindings: [
- {
- mouseButton: MouseBindings.Auxiliary,
- },
- ],
- });
- }
-
- renderingEngine.current.renderViewports([
- viewportId1,
- viewportId2,
- viewportId3,
- ]);
- };
-
- run();
-
- return () => {
- // 禁用视口
- renderingEngine.current?.disableElement(viewportId1);
- renderingEngine.current?.disableElement(viewportId2);
- renderingEngine.current?.disableElement(viewportId3);
-
- // 销毁渲染引擎
- renderingEngine.current?.destroy();
-
- // 从 ToolGroupManager 中移除工具组
- ToolGroupManager.destroyToolGroup(toolGroupId);
-
- // 移出工具注册
- cornerstoneTools.removeTool(StackScrollMouseWheelTool);
- cornerstoneTools.removeTool(CrosshairsTool);
- cornerstoneTools.removeTool(WindowLevelTool);
- cornerstoneTools.removeTool(ZoomTool);
- };
- }, [props, renderingEngineId, toolGroupId]);
-
- /**
- * mpr resize
- */
- useEffect(() => {
- const container = containerRef.current;
- if (!container) return;
- let resizeTimeout: NodeJS.Timeout | null = null;
- const resizeObserver = new ResizeObserver(() => {
- if (resizeTimeout) clearTimeout(resizeTimeout);
- resizeTimeout = setTimeout(() => renderingEngine.current?.resize(), 100);
- });
- resizeObserver.observe(container);
- return () => {
- if (resizeTimeout) clearTimeout(resizeTimeout);
- resizeObserver.unobserve(container);
- resizeObserver.disconnect();
- };
- }, []);
-
- return (
-
- );
-};
diff --git a/apps/desktop/src/pages/Viewer/MprViewer/Crosshair.config.tsx b/apps/desktop/src/pages/Viewer/MprViewer/index.config.tsx
similarity index 63%
rename from apps/desktop/src/pages/Viewer/MprViewer/Crosshair.config.tsx
rename to apps/desktop/src/pages/Viewer/MprViewer/index.config.tsx
index 7d8e9cf..a0184df 100644
--- a/apps/desktop/src/pages/Viewer/MprViewer/Crosshair.config.tsx
+++ b/apps/desktop/src/pages/Viewer/MprViewer/index.config.tsx
@@ -34,3 +34,23 @@ export const viewportReferenceLineSlabThicknessControlsOn = [
export const volumeName = "CT_VOLUME_ID"; // Id of the volume less loader prefix
export const volumeLoaderScheme = "cornerstoneStreamingImageVolume"; // Loader id which defines which volume loader to use
export const volumeId = `${volumeLoaderScheme}:${volumeName}`; // VolumeId with loader id + volume id
+export const toolGroupMprId = "toolMprNo1";
+
+export function getReferenceLineColor(vpId: ViewportId) {
+ return viewportColors[vpId];
+}
+
+export function getReferenceLineControllable(vpId: ViewportId) {
+ const index = viewportReferenceLineControllable.indexOf(vpId);
+ return index !== -1;
+}
+
+export function getReferenceLineDraggableRotatable(vpId: ViewportId) {
+ const index = viewportReferenceLineDraggableRotatable.indexOf(vpId);
+ return index !== -1;
+}
+
+export function getReferenceLineSlabThicknessControlsOn(vpId: ViewportId) {
+ const index = viewportReferenceLineSlabThicknessControlsOn.indexOf(vpId);
+ return index !== -1;
+}
diff --git a/apps/desktop/src/pages/Viewer/StackViewer/index.config.ts b/apps/desktop/src/pages/Viewer/StackViewer/index.config.ts
new file mode 100644
index 0000000..172fda7
--- /dev/null
+++ b/apps/desktop/src/pages/Viewer/StackViewer/index.config.ts
@@ -0,0 +1,2 @@
+export const stackViewportId = "stackNo1";
+export const toolGroupStackId = "toolStackNo1";
diff --git a/apps/desktop/src/pages/Viewer/StackViewer/index.tsx b/apps/desktop/src/pages/Viewer/StackViewer/index.tsx
deleted file mode 100644
index 1b41b5d..0000000
--- a/apps/desktop/src/pages/Viewer/StackViewer/index.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import { useEffect, useRef, useState } from "react";
-import { PublicViewportInput } from "@cornerstonejs/core/dist/types/types/IViewport.js";
-import { Enums as CoreEnums, RenderingEngine } from "@cornerstonejs/core";
-import { IStackViewport } from "@cornerstonejs/core/dist/types/types";
-import { Slider } from "@/components/ui/slider";
-
-export interface StackViewerProps {
- imageIds: string[];
-}
-
-export const StackViewer = (props: StackViewerProps) => {
- const viewportStackRef = useRef(null);
- const renderingEngineRef = useRef();
- const containerRef = useRef(null);
- const viewportId = "stackViewport";
- const renderingEngineId = "stackRenderingEngine";
-
- useEffect(() => {
- if (!viewportStackRef.current) return;
- renderingEngineRef.current = new RenderingEngine(renderingEngineId);
- const viewportInput: PublicViewportInput = {
- viewportId,
- type: CoreEnums.ViewportType.STACK, // 用于 Stack 视图
- element: viewportStackRef.current,
- defaultOptions: {
- background: [0, 0, 0],
- },
- };
- renderingEngineRef.current.enableElement(viewportInput);
- const viewport = renderingEngineRef.current.getViewport(
- viewportId
- ) as IStackViewport;
-
- viewport.setStack(props.imageIds);
-
- return () => {
- renderingEngineRef.current?.disableElement(viewportId);
- renderingEngineRef.current?.destroy();
- };
- }, [props.imageIds, renderingEngineId, viewportId]);
-
- useEffect(() => {
- const container = containerRef.current;
- if (!container) return;
- let resizeTimeout: NodeJS.Timeout | null = null;
- const resizeObserver = new ResizeObserver(() => {
- if (resizeTimeout) clearTimeout(resizeTimeout);
- resizeTimeout = setTimeout(
- () => renderingEngineRef.current?.resize(),
- 100
- );
- });
- resizeObserver.observe(container);
- return () => {
- if (resizeTimeout) clearTimeout(resizeTimeout);
- resizeObserver.unobserve(container);
- resizeObserver.disconnect();
- };
- }, []);
-
- const onChangeIndex = (value: number[]) => {
- if (renderingEngineRef.current) {
- const viewport = renderingEngineRef.current.getViewport(viewportId);
- (viewport as IStackViewport).setImageIdIndex(value[0]);
- }
- };
-
- return (
-
- );
-};
diff --git a/apps/desktop/src/pages/Viewer/MprViewer/ToolBarMenu/index.tsx b/apps/desktop/src/pages/Viewer/ToolBarMenu/index.tsx
similarity index 100%
rename from apps/desktop/src/pages/Viewer/MprViewer/ToolBarMenu/index.tsx
rename to apps/desktop/src/pages/Viewer/ToolBarMenu/index.tsx
diff --git a/apps/desktop/src/pages/Viewer/index.tsx b/apps/desktop/src/pages/Viewer/index.tsx
index 3a81196..a1ddb69 100644
--- a/apps/desktop/src/pages/Viewer/index.tsx
+++ b/apps/desktop/src/pages/Viewer/index.tsx
@@ -1,31 +1,87 @@
import { useLocation } from "react-router-dom";
import { initCornerstone } from "./MprViewer/CornerstoneDicomLoader/init";
-import { CrosshairMpr } from "./MprViewer/Crosshair";
+import * as cornerstoneTools from "@cornerstonejs/tools";
import { useEffect, useRef, useState } from "react";
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable";
-import { StackViewer } from "./StackViewer";
import { createImageIdsAndCacheMetaData } from "./MprViewer/CornerstoneDicomLoader/createImageIdsAndCacheMetaData";
-import { volumeLoader } from "@cornerstonejs/core";
+import {
+ RenderingEngine,
+ setVolumesForViewports,
+ volumeLoader,
+ Enums as CoreEnums,
+} from "@cornerstonejs/core";
+import {
+ IStackViewport,
+ PublicViewportInput,
+} from "@cornerstonejs/core/dist/types/types";
+import {
+ getReferenceLineColor,
+ getReferenceLineControllable,
+ getReferenceLineDraggableRotatable,
+ getReferenceLineSlabThicknessControlsOn,
+ toolGroupMprId,
+ viewportId1,
+ viewportId2,
+ viewportId3,
+ volumeId,
+} from "./MprViewer/index.config";
+import setCtTransferFunctionForVolumeActor from "./MprViewer/CornerstoneDicomLoader/setCtTransferFunctionForVolumeActor";
+import { Slider } from "@/components/ui/slider";
+import { stackViewportId, toolGroupStackId } from "./StackViewer/index.config";
+import { ToolBarMenu } from "./ToolBarMenu";
+import { Model3DViewer } from "./ModelViewer";
+
+const {
+ ToolGroupManager,
+ CrosshairsTool,
+ StackScrollMouseWheelTool,
+ WindowLevelTool,
+ ZoomTool,
+ Enums: csToolsEnums,
+} = cornerstoneTools;
+
+const { MouseBindings } = csToolsEnums;
const wadoRsRoot = "http://localhost:8042/dicom-web";
+const { ViewportType, OrientationAxis } = CoreEnums;
+const wwwl = { windowCenter: 50, windowWidth: 850 };
+
export const Viewer = () => {
- const [cornerstoneLoaded, setCornerstoneLoaded] = useState(false);
+ const volumeViewport1Ref = useRef(null);
+ const volumeViewport2Ref = useRef(null);
+ const volumeViewport3Ref = useRef(null);
+ const stackViewportRef = useRef(null);
+
+ /**
+ * 当前的index
+ */
+ const [index, setIndex] = useState(0);
const location = useLocation();
const queryParams = new URLSearchParams(location.search);
const SeriesInstanceUID = queryParams.get("SeriesInstanceUID");
const StudyInstanceUID = queryParams.get("StudyInstanceUID");
- const imageIdsRef = useRef();
- const volumeId = "volume";
- const wwwl = { windowCenter: 50, windowWidth: 850 };
+ const [imageIds, setImageIds] = useState();
+ const renderingEngineId = "renderEngineNo1";
+ const renderingEngineRef = useRef();
useEffect(() => {
- const setImageOrderCache = async () => {
+ cornerstoneTools.addTool(StackScrollMouseWheelTool);
+ cornerstoneTools.addTool(CrosshairsTool);
+ cornerstoneTools.addTool(WindowLevelTool);
+ cornerstoneTools.addTool(ZoomTool);
+
+ const renderViewport = async () => {
if (!StudyInstanceUID || !SeriesInstanceUID) return;
+ if (!volumeViewport1Ref.current) return;
+ if (!volumeViewport2Ref.current) return;
+ if (!volumeViewport3Ref.current) return;
+ if (!stackViewportRef.current) return;
+ renderingEngineRef.current = new RenderingEngine(renderingEngineId);
// imageIds此时由于流式加载for mpr,是错乱的图片顺序
const imageIds = await createImageIdsAndCacheMetaData({
StudyInstanceUID,
@@ -37,26 +93,198 @@ export const Viewer = () => {
imageIds,
});
volume.load();
- imageIdsRef.current = volume.imageIds;
+
+ const volumeViewportInput: PublicViewportInput[] = [
+ {
+ viewportId: viewportId1,
+ type: ViewportType.ORTHOGRAPHIC,
+ element: volumeViewport1Ref.current,
+ defaultOptions: {
+ orientation: OrientationAxis.AXIAL,
+ background: [0, 0, 0],
+ },
+ },
+ {
+ viewportId: viewportId2,
+ type: ViewportType.ORTHOGRAPHIC,
+ element: volumeViewport2Ref.current,
+ defaultOptions: {
+ orientation: OrientationAxis.SAGITTAL,
+ background: [0, 0, 0],
+ },
+ },
+ {
+ viewportId: viewportId3,
+ type: ViewportType.ORTHOGRAPHIC,
+ element: volumeViewport3Ref.current,
+ defaultOptions: {
+ orientation: OrientationAxis.CORONAL,
+ background: [0, 0, 0],
+ },
+ },
+ ];
+ const stackViewportInput: PublicViewportInput = {
+ viewportId: stackViewportId,
+ type: ViewportType.STACK, // 用于 Stack 视图
+ element: stackViewportRef.current,
+ defaultOptions: {
+ background: [0, 0, 0],
+ },
+ };
+
+ renderingEngineRef.current.setViewports([
+ ...volumeViewportInput,
+ stackViewportInput,
+ ]);
+ renderingEngineRef.current.enableElement(stackViewportInput);
+ const stackViewport = renderingEngineRef.current.getViewport(
+ stackViewportId
+ ) as IStackViewport;
+
+ stackViewport.setStack(volume.imageIds);
+ setImageIds(volume.imageIds);
+
+ await setVolumesForViewports(
+ renderingEngineRef.current,
+ [
+ {
+ volumeId: volumeId,
+ callback: ({ volumeActor }) =>
+ setCtTransferFunctionForVolumeActor({
+ volumeActor,
+ defaultWindowCenter: wwwl.windowCenter,
+ defaultWindowWidth: wwwl.windowWidth,
+ }),
+ },
+ ],
+ [viewportId1, viewportId2, viewportId3]
+ );
+
+ const toolGroupMpr = ToolGroupManager.createToolGroup(toolGroupMprId);
+ if (toolGroupMpr) {
+ toolGroupMpr.addViewport(viewportId1, renderingEngineId);
+ toolGroupMpr.addViewport(viewportId2, renderingEngineId);
+ toolGroupMpr.addViewport(viewportId3, renderingEngineId);
+ toolGroupMpr.addTool(ZoomTool.toolName);
+ toolGroupMpr.setToolActive(ZoomTool.toolName, {
+ bindings: [{ mouseButton: MouseBindings.Secondary }],
+ });
+ toolGroupMpr.addTool(StackScrollMouseWheelTool.toolName);
+ toolGroupMpr.addTool(CrosshairsTool.toolName, {
+ getReferenceLineColor,
+ getReferenceLineControllable,
+ getReferenceLineDraggableRotatable,
+ getReferenceLineSlabThicknessControlsOn,
+ });
+ toolGroupMpr.setToolActive(CrosshairsTool.toolName, {
+ bindings: [{ mouseButton: MouseBindings.Primary }],
+ });
+ toolGroupMpr.setToolActive(StackScrollMouseWheelTool.toolName);
+
+ toolGroupMpr.addTool(WindowLevelTool.toolName);
+ toolGroupMpr.setToolActive(WindowLevelTool.toolName, {
+ bindings: [{ mouseButton: MouseBindings.Auxiliary }],
+ });
+ }
+
+ const toolGroupStack = ToolGroupManager.createToolGroup(toolGroupStackId);
+ if (toolGroupStack) {
+ toolGroupStack.addViewport(stackViewportId, renderingEngineId);
+ toolGroupStack.addTool(ZoomTool.toolName);
+ toolGroupStack.setToolActive(ZoomTool.toolName, {
+ bindings: [{ mouseButton: MouseBindings.Secondary }],
+ });
+ toolGroupStack.addTool(WindowLevelTool.toolName);
+ toolGroupStack.setToolActive(WindowLevelTool.toolName, {
+ bindings: [{ mouseButton: MouseBindings.Auxiliary }],
+ });
+ }
// 默认windowWidtth
const { windowCenter, windowWidth } = volume.cornerstoneImageMetaData;
console.log("默认窗宽/位: ", windowCenter, windowWidth);
-
- setCornerstoneLoaded(true);
};
initCornerstone(() => {
- setImageOrderCache();
+ renderViewport();
});
+ return () => {
+ renderingEngineRef.current?.disableElement(stackViewportId);
+ renderingEngineRef.current?.disableElement(viewportId1);
+ renderingEngineRef.current?.disableElement(viewportId2);
+ renderingEngineRef.current?.disableElement(viewportId3);
+ renderingEngineRef.current?.destroy();
+
+ ToolGroupManager.destroyToolGroup(toolGroupMprId);
+ ToolGroupManager.destroyToolGroup(toolGroupStackId);
+
+ cornerstoneTools.removeTool(StackScrollMouseWheelTool);
+ cornerstoneTools.removeTool(CrosshairsTool);
+ cornerstoneTools.removeTool(WindowLevelTool);
+ cornerstoneTools.removeTool(ZoomTool);
+ };
}, [SeriesInstanceUID, StudyInstanceUID]);
+ const onChangeIndex = (value: number[]) => {
+ setIndex(value[0]);
+ };
+
+ useEffect(
+ () => setIndex(imageIds ? Math.floor(imageIds.length / 2) : 0),
+ [imageIds]
+ );
+
+ /**
+ * 滚轮换图逻辑
+ */
+ useEffect(() => {
+ const handleWheel = (event: WheelEvent) => {
+ console.log("wheel");
+ if (!imageIds) return;
+ const delta = event.deltaY > 0 ? -1 : 1;
+ if (delta === -1 && index === 0) return;
+ if (delta === 1 && index === imageIds?.length - 1) return;
+ setIndex((p) => p + delta);
+ };
+ const stackElement = stackViewportRef.current;
+ stackElement?.addEventListener("wheel", handleWheel);
+ return () => {
+ stackElement?.removeEventListener("wheel", handleWheel);
+ };
+ }, [imageIds, index]);
+
+ useEffect(() => {
+ if (renderingEngineRef.current) {
+ const viewport = renderingEngineRef.current.getViewport(stackViewportId);
+ (viewport as IStackViewport)?.setImageIdIndex(index);
+ }
+ }, [index]);
+
+ useEffect(() => {
+ const container = stackViewportRef.current;
+ if (!container) return;
+ let resizeTimeout: NodeJS.Timeout | null = null;
+ const resizeObserver = new ResizeObserver(() => {
+ if (resizeTimeout) clearTimeout(resizeTimeout);
+ resizeTimeout = setTimeout(
+ () => renderingEngineRef.current?.resize(),
+ 100
+ );
+ });
+ resizeObserver.observe(container);
+ return () => {
+ if (resizeTimeout) clearTimeout(resizeTimeout);
+ resizeObserver.unobserve(container);
+ resizeObserver.disconnect();
+ };
+ }, []);
+
return (
- {/*
@@ -66,24 +294,38 @@ export const Viewer = () => {
className="w-full h-full"
>
-
- {cornerstoneLoaded && imageIdsRef.current && (
-
+
+
+ {imageIds && (
+
+
+ {index + 1}/{imageIds.length}
+
+
+
)}
- bototm
+
+
+
- {cornerstoneLoaded && imageIdsRef.current && (
-
- )}
+
+
+