使用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
相关产品推荐
相关产品推荐

