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

使用FabricJS添加图片时,为何所有旧图片都被新图片替换?

问题原因及解决方案

问题根源

你遇到的问题是所有通过fabric.Image创建的对象都复用了同一个imgRef.current DOM元素。DOM元素属于引用类型,当你修改这个img的src属性时,所有指向它的Fabric图片对象都会同步显示最新的图片内容,导致旧对象被“替换”。

解决方案

每次创建新的Fabric图片对象时,创建一个独立的img元素,不再复用同一个ref指向的元素。修改后的核心代码如下:

async function SampleAction() {
  console.clear();
  const htmlDOM = new DOMParser().parseFromString(
    description.htmlValue,
    "text/html"
  );
  htmlDOM.firstChild.setAttribute("style", "padding: 0; margin:0");

  const invisibleDiv = document.createElement("div");
  invisibleDiv.setAttribute("id", "invisibleDiv");
  invisibleDiv.setAttribute(
    "style",
    "display: inline-block; background-color: transparent; padding: 0; margin: 0;"
  );

  invisibleDiv.innerHTML = htmlDOM.documentElement.innerHTML;
  hiddenDiv.current.appendChild(invisibleDiv);
  const htmlDomImg = await html2canvas(invisibleDiv, {
    backgroundColor: null
  });

  // 关键:创建新的img元素,不再复用共享的ref
  const newImg = new Image();
  newImg.src = htmlDomImg.toDataURL();
  newImg.style.height = htmlDomImg.style.height;
  newImg.style.width = htmlDomImg.style.width;

  const newItm = new fabric.Image(newImg, {
    left: 0,
    top: 0,
    width: newImg.width,
    height: newImg.height,
    id: (Math.random() + 1).toString(36).substring(7),
    objectDNA: {
      type: "text",
      text: htmlDOM.querySelector("html").textContent,
      rawHTML: htmlDOM.firstChild
    }
  });

  invisibleDiv.remove();
  setImgLayers([...imgLayers, newItm]);
}

说明

  • 原先的imgRef.current是固定的DOM节点,所有Fabric对象共享它的引用,因此修改src会影响所有实例。
  • 每次创建独立的Image元素后,每个Fabric.Image对象都会持有专属的图片引用,后续更新新图片时不会干扰旧对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:20:47