当前位置: 首页 > 知识库问答 >
问题:

fabric.js - 如何解决fabricjs中的canvas层级生成错乱?

姚昊焱
2023-04-27

有一个使用了fabricjs(版本:5.3.0)写的弹框组件,大致为:

import { Modal } from "antd";
import { fabric } from "fabric";

const Test: React.FC<any> = ({ a, b, c }) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [canvas, setCanvas] = useState<fabric.Canvas>();

  useEffect(() => {
    initCanvas();
  }, [a, b]);

  const initCanvas = () => {
    let imgUrl = a.img.Url;
    let imgName = a.img.name;
    let img = new Image();
    img.src = imgUrl;

    // 设置背景图片
    img.onload = () => {
      let c = new fabric.Canvas(canvasRef.current, {
        width: img.width,
        height: img.height,
      });
      c.setBackgroundImage(
        imgUrl,
        c.requestRenderAll.bind(c),
        {
          scaleX: 1,
          scaleY: 1,
          name: imgName,
          left: 150,
          top: 150,
        }
      );
      setCanvas(c);
    }
  };

  ......

  const onOk = () => {
        ...
  }

  const onModalCancel = () => {
        ...
  }

  return (
    <Modal
      open={open}
      onOk={onOk}
      onCancel={onModalCancel}
      forceRender={true}
      destroyOnClose={true}
    >
      <div>
        <canvas id="canvas" ref={canvasRef} />
      </div>
    </Modal>
  )
};
export default Test;

正常情况下应该是canvas-container下有一个lower-canvas和一个upper-canvas,
1682500565168.png

但是现在总是出现生成了多层嵌套的canvas,外层嵌套的canvas会丢失lower-canvas,导致数据正确但是绘制总是出问题,无法选中绘制图形或者总是只显示第一次的数据,感觉canvas第一次初始化后,之后都没有正确初始化
1682500710610.png

请问这个问题该怎么解决呢?

共有1个答案

卫华奥
2023-04-27

这个问题可能是因为在每次重新初始化画布时候,没有清除之前的画布实例。要解决这个问题,可以在 initCanvas 函数中检查 canvas 状态,如果已经存在一个画布实例,就先销毁它,然后再创建一个新的画布实例。

修改一下initCanvas 函数:



const initCanvas = () => {
  // 如果已存在画布实例,先销毁它
  if (canvas) {
    canvas.dispose();
  }

  let imgUrl = a.img.Url;
  let imgName = a.img.name;
  let img = new Image();
  img.src = imgUrl;

  // 设置背景图片
  img.onload = () => {
    let c = new fabric.Canvas(canvasRef.current, {
      width: img.width,
      height: img.height,
    });
    c.setBackgroundImage(
      imgUrl,
      c.requestRenderAll.bind(c),
      {
        scaleX: 1,
        scaleY: 1,
        name: imgName,
        left: 150,
        top: 150,
      }
    );
    setCanvas(c);
  }
};
 类似资料:
  • 我有React原生应用。我安装了react-native-vector-icons库。当我在Xcode中得到这个错误后: 多个命令生成'/用户/jocoders/库/开发人员/Xcode/DerivedData/openCells-gtlsipogexxyteffomqvumgwiihd/构建/产品/调试-iphoneSimator/openCalls.app/Fonts': 目标“openCal

  • 我已经使用最新的gradle和gradle插件将Android Studio从4.1.3升级到4.2。现在,由于jcenter是生命周期的结束,不推荐在构建脚本中使用jcenter()的引用: 建议“迁移”到mavenCentral()。我有各种似乎不在mavenCentral()上的依赖项,因为gradle找不到它们,例如: 我谷歌了这个工件(在这种情况下是“物质搜索视图”),并在搜索平台“MV

  • 请问 canvas 如何做出像如上图片的效果,图片中的手机壳摄像头是会遮住那个心的图案的,其它位置则不会,大概思路是怎么样的呢?这里就是有两个图层,一个作为背景图,一个是遮罩图,如下图

  • 错误是: 错误:元素类型无效:应为字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。您可能忘记了从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。 在App.js:22检查你的代码。在应用程序中(由ExpoRoot创建)在ExpoRoot中(位于renderApplication.js:45)在RCTView中(位于View.js:34)在视图中(位于AppConta

  • tensorflow_安装_测试。派克 以下是输出: 我该如何解决这个问题?

  • 我是Django新手,试图在virtualenv中创建一个Django项目来学习,但在上出现以下错误: 回溯(最后一次调用):文件“manage.py”,第21行,main() 文件“manage.py”,第17行,从命令行执行(sys.argv) 文件 “/home/suraj/Documents/my_projects/django_project/venv/lib/python3.6/sit