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

React集成OpenSeadragonFabricjsOverlay报错:需先加载OpenSeadragon

问题:Create React App中OpenSeadragon FabricJS Overlay加载顺序错误

背景

我用Create React App开发Web应用,需要实现一个图片查看器,支持渲染图片并在其上绘制多个可编辑多边形。选用OpenSeadragon作为基础查看器,并搭配它的OpenseadragonFabricjsOverlay插件(基于fabric.js)来实现绘制功能。

已安装依赖

"@types/fabric": "^4.5.12",
"@types/openseadragon": "^3.0.4",
"fabric": "^5.2.4",
"openseadragon": "^3.1.0",
"openseadragon-fabricjs-overlay": "github:altert/OpenseadragonFabricjsOverlay"

现有Viewer组件代码

import React, { useEffect } from 'react';
import OpenSeadragon from 'openseadragon';
import 'openseadragon-fabricjs-overlay';
import { fabric } from 'fabric';

const Viewer = () => {
  useEffect(() => {
    const viewer = OpenSeadragon({
      id: 'osd-viewer',
      tileSources: {
        type: 'image',
        url: 'path/to/image/jpg'
      }
    });

    // 初始化overlay
    const options = {
        scale: 1000
    }
    const overlay = viewer.fabricjsOverlay(options);

    return () => {
      viewer.destroy();
    };
  });

  return (
    <div id="osd-viewer" style={{ height: '100%', width: '100%' }}></div>
  );
};

export default Viewer;

遇到的错误

运行时抛出错误:[openseadragon-canvas-overlay] requires OpenSeadragon,原因是OpenseadragonFabricjsOverlay插件加载时,OpenSeadragon还未完成加载,导致插件无法找到依赖的全局对象。

解决方案

方案1:手动将OpenSeadragon暴露到全局作用域

在导入插件前,先把OpenSeadragon挂载到window对象上,确保插件能找到它:

import React, { useEffect } from 'react';
import OpenSeadragon from 'openseadragon';
import { fabric } from 'fabric';

// 先将OpenSeadragon暴露到全局
window.OpenSeadragon = OpenSeadragon;
// 再导入插件
import 'openseadragon-fabricjs-overlay';

const Viewer = () => {
  useEffect(() => {
    const viewer = OpenSeadragon({
      id: 'osd-viewer',
      tileSources: {
        type: 'image',
        url: 'path/to/image/jpg'
      }
    });

    const options = {
        scale: 1000
    }
    const overlay = viewer.fabricjsOverlay(options);

    return () => {
      viewer.destroy();
    };
  }, []); // 加空依赖数组,确保只初始化一次

  return (
    <div id="osd-viewer" style={{ height: '100%', width: '100%' }}></div>
  );
};

export default Viewer;

方案2:使用动态导入控制加载顺序

在useEffect内部先异步加载OpenSeadragon,再加载插件,从根源保证顺序:

import React, { useEffect } from 'react';
import { fabric } from 'fabric';

const Viewer = () => {
  useEffect(() => {
    let viewer;

    const initViewer = async () => {
      // 先加载OpenSeadragon
      const OpenSeadragonModule = await import('openseadragon');
      const OpenSeadragon = OpenSeadragonModule.default;
      // 暴露到全局供插件使用
      window.OpenSeadragon = OpenSeadragon;
      // 再加载插件
      await import('openseadragon-fabricjs-overlay');

      // 初始化查看器
      viewer = OpenSeadragon({
        id: 'osd-viewer',
        tileSources: {
          type: 'image',
          url: 'path/to/image/jpg'
        }
      });

      const options = {
          scale: 1000
      }
      const overlay = viewer.fabricjsOverlay(options);
    };

    initViewer();

    return () => {
      if (viewer) viewer.destroy();
    };
  }, []);

  return (
    <div id="osd-viewer" style={{ height: '100%', width: '100%' }}></div>
  );
};

export default Viewer;

补充提示:原代码中useEffect未添加依赖数组,会导致组件每次渲染都重新创建viewer实例,建议添加空数组[],确保查看器只初始化一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:10:24