You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React函数组件使用Cornerstone栈滚动工具时如何获取currentImageIdIndex

Cornerstone 图像栈滚动索引获取方案

你不需要直接操作DOM绑定原生事件,使用Cornerstone Tools官方提供的事件API即可,监听器需要在视口栈状态初始化完成后注册,组件卸载时要移除监听器避免内存泄漏。

核心实现逻辑

  • 监听事件:使用cornerstonetoolsstackscroll内置事件,滚轮滚动、拖拽切换图像时都会触发该事件
  • 注册时机:必须在addToolState完成栈状态挂载之后注册,否则事件无法正常绑定
  • 取值方式:直接从Cornerstone的工具状态中读取currentImageIdIndex,保证和内部状态完全同步,不需要自行计算索引

具体代码修改

1. 新增滚动事件处理回调

把这个方法放到组件内,注意用useCallback包裹避免引用变化导致监听器无法正确移除:

const handleStackScroll = useCallback(() => {
  if (!viewerRef.current) return;
  // 从Cornerstone状态中读取当前栈数据
  const stackState = cornerstoneTools.getToolState(viewerRef.current, 'stack');
  const currentStack = stackState?.data?.[0];
  if (currentStack) {
    const currentImageIdIndex = currentStack.currentImageIdIndex;
    // 此处编写索引获取后的业务逻辑,比如透传给父组件、更新本地展示状态等
    console.log('当前展示图像索引:', currentImageIdIndex);
  }
}, []);

2. 修正原有异步逻辑问题

你原来的代码中Promise.all没有等待执行完成就初始化栈,会导致mediaArray为空报错,需要把displayStack改成async函数,等所有imageId生成、首图加载完成后再初始化栈、绑定事件:

const displayStack = async (stackMediaArray) => {
  let mediaArray = [];

  // 等待所有图像的imageId生成完成
  await Promise.all(
    stackMediaArray.map((mediaObject) => {
      return new Promise((resolve, reject) => {
        let imageBuffer = base64StringToArrayBuffer(mediaObject.buffer);
        const imageId = cornerstoneFileImageLoader.fileManager.addBuffer(imageBuffer);
        mediaArray.push(imageId);
        resolve(mediaObject);
      }).catch(console.error);
    })
  );

  // 定义栈初始状态
  const stack = {
    currentImageIdIndex: 0,
    imageIds: mediaArray,
  };

  // 等待首图加载完成后初始化视口栈
  const firstImage = await cornerstone.loadAndCacheImage(mediaArray[0]);
  cornerstone.displayImage(viewerRef.current, firstImage);
  cornerstoneTools.addStackStateManager(viewerRef.current, ["stack"]);
  cornerstoneTools.addToolState(viewerRef.current, "stack", stack);

  // 栈状态初始化完成后,注册滚动事件监听器
  cornerstoneTools.addEventListener(
    viewerRef.current,
    "cornerstonetoolsstackscroll",
    handleStackScroll
  );

  setCornerstoneTools();
};

3. 增加useEffect清理逻辑

在useEffect的返回函数中移除事件监听器、销毁cornerstone实例,避免内存泄漏:

useEffect(() => {
  if (!viewerRef.current) return;
  initializeCornerstone();
  displayStack(props.stackMediaArray);

  // 组件卸载时执行清理
  return () => {
    cornerstoneTools.removeEventListener(
      viewerRef.current,
      "cornerstonetoolsstackscroll",
      handleStackScroll
    );
    cornerstone.disable(viewerRef.current);
  }
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, [viewerRef]);

注意事项

  • 不要自行维护索引值:Cornerstone内部会处理循环滚动、边界判断等逻辑,直接从工具状态读取的索引永远是准确的
  • 不需要绑定DOM原生事件:上述方案全程使用Cornerstone官方事件API,符合你不直接操作DOM的需求
  • 两种滚动触发方式都能捕获:不管是鼠标滚轮触发StackScrollMouseWheelTool,还是鼠标拖拽触发StackScrollTool,事件都会正常触发

内容的提问来源于stack exchange,提问作者Radespy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 02:21:21