我已经使用 Fabric npm 包在我的 React 应用程序中设置了
Fabric.js
。我正在尝试构建一个艺术板,您可以在其中绘图、添加文本和添加图像。由于某种原因,添加元素(图像/文本)似乎会破坏应用程序。添加图像时,图像会出现一段时间,然后在发生某些变化时消失,并在选择任何其他图像/文本时重新出现。
重点是绘图时,只有绘图可见,添加元素时,只有元素可见,而所有元素(对象)都出现在画布上。
我已经创建了一个类似的环境来模拟该问题,请让我知道任何修复。
注意:主要代码位于
fabricCanvas.js
文件中,该文件创建一个类来处理所有 fabric.js
功能。
CODESANBOX 链接(已更新)
我还添加了一项检查,通过映射所有对象来检查图像是否存在于画布上,它确实存在,但由于某种原因不可见。
我也尝试了删除
strict
模式的解决方案,但没有帮助。
我尝试过在每次更新时调用
renderAll()
的不同解决方案,但这并不奏效。
你的初始化有很多问题
结合使用fabricJS和useEffect
第一:
<div
id="canvas-container"
ref={containerRef} //use ref on the container to observe his size
style={{ maxWidth: "100vw", overflow: "hidden" }}
>
<canvas id={canvasID} />
</div>
然后定义你的参考
const containerRef = useRef(null);
const canvasID = "canvas";
现在您可以使用 Effect hook 在组件挂载时运行初始化逻辑
/**
* Effect hook to run initialization logic when the component mounts or
when the container changes.
*/
useEffect(() => {
const container = containerRef.current;
/**
* Checking if the container exists before proceeding with initialization.
*/
if (!container) {
console.error("❌ The container does not exist");
return;
}
/**
* Getting the initial dimensions of the container.
*/
const clientHeight = container.clientHeight;
const clientWidth = container.clientWidth;
/**
* Create the main canvas
*/
fabricCanvas.init(canvasID, clientWidth, clientHeight);
}, []);
在这一步画布正在工作。 但在反应中,您希望在组件被卸载时处理画布。 我的建议是将画布初始化和不同的功能分开。将画布存储到您选择的上下文或状态管理器中
看这个例子:
useEffect(() => {
const container = containerRef.current;
/**
* Checking if the container exists before proceeding with initialization.
*/
if (!container) {
console.error("❌ The container does not exist");
return;
}
/**
* Setting the container reference in the fabricStore for future use.
*/
fabricStore.setContainerRef(container);
/**
* Getting the initial dimensions of the container.
*/
const clientHeight = container.clientHeight;
const clientWidth = container.clientWidth;
/**
* Create the main canvas
*/
initCanvas(clientHeight, clientWidth);
// your different config to initialize
initControls();
initWorkspace();
initBackground();
/**
* once the canvas has been created
* your different features
*/
if (fabricStore.canvas) {
new FabricFeature02(fabricStore.canvas);
new FabricFeature03(fabricStore.canvas);
new FabricFeature04(fabricStore.canvas);
new FabricFeature05(fabricStore.canvas);
}
const resizeObserver = new ResizeObserver((entries) => {
const { width = clientWidth, height = clientHeight } =
(entries[0] && entries[0]?.contentRect) || {};
resizeCanvas(width!, height!); // your resize logic
});
// Attaching the ResizeObserver to the container, assuming the container is of type HTMLDivElement.
resizeObserver.observe(container as HTMLDivElement);
/**
* Returning a cleanup function to be executed when the component is unmounted.
*/
return () => {
//Disposing of the canvas using the dispose method, assuming it exists in the fabricStore.
fabricStore.canvas?.dispose();
// Checking if the container element exists before attempting to disconnect the ResizeObserver
if (container) {
// Disconnecting the ResizeObserver to stop observing changes in the container size.
resizeObserver.disconnect();
}
};
}, []);