这份 Fabric.js 问题排查指南汇总了大家最常遇到的问题,按通常出现的顺序排列。
撤销没有记录我的改动
Fabric.js 只在鼠标交互、添加和删除对象、文本编辑时触发事件。你的代码用 object.set() 或 canvas.bringObjectForward() 做的改动不会触发任何事件。把它们包起来:
engine.transaction("Recolor", () => shape.set("fill", "teal"));撤销后对象引用失效了
撤销和重做会重建改动过的对象,所以它们是 id 不变的新实例。保存 id,再用 engine.getObjectById(id) 查找对象。
加载后自定义属性丢了
用普通的 toJSON 和 loadFromJSON 时,Fabric.js 只保存它认识的属性。把类和它的自定义属性注册一下:
engine.registerObject({ fabricClass: Sticker, properties: ["label"] });加载以 UNKNOWN_OBJECT_TYPE 失败
文档里有当前页面没注册的类。通过 customObjects 传入,或在加载前调用 registerObject。这个类需要一个和保存的 type 一致的静态 type。在普通 Fabric.js 里,同样的问题会表现为 klass.fromObject is not a function。
打包结果里有两份 Fabric.js
在一份里注册的类另一份不认识,加载会以 UNKNOWN_OBJECT_TYPE 失败。请确认只安装了一份 fabric。在 Vite 里使用链接的包时,加上 resolve: { dedupe: ["fabric"] }。
加载以 MISSING_ASSETS 失败
error.missingAssets 列出了每张没加载成功的图片。用 assets.resolveUrl 修正地址,用 assets.replaceMissingImage 提供替代图片,或者之后调用 engine.replaceImage(oldUrl, newUrl)。
重新打开后文字显示不一样
创建文字时字体还没加载,所以 Fabric.js 用后备字体测量了它。在 assets.loadFont 里加载网络字体,并留意 FONT_UNAVAILABLE 警告。
导出时画布被污染
有一张来自其他网站的图片没用 CORS 加载,浏览器因此拦截 PNG、JPEG 和 WebP 导出。从返回 Access-Control-Allow-Origin 的服务器,用 crossOrigin: "anonymous" 加载它。运行 engine.preflightExport({ format }),可以在用户点击导出前提示这个问题。
只开一个标签页也报 SAVE_CONFLICT
你的适配器没有返回新的修订号。在 saveDocument 里返回 { revision },或者保存 document.revision。
恢复提示一直不出现
传入 recovery: { store: createIndexedDbRecovery() }。只有存在未保存改动时才会写副本;隐私浏览模式可能在关闭窗口时清空存储。
React:开发环境里有两个引擎
StrictMode 会把 effect 挂载两次。useDocumentEngine 会销毁第一个引擎,所以只有一个在运行。始终使用 hook 返回的引擎。
Vue:加载后画布不渲染
Vue 把 Fabric.js 画布包成了响应式代理。把它放在 shallowRef 里,或者传入 toRaw(canvas)。详见 Vue。
Next.js:"window is not defined"
Fabric.js 在服务端运行了。用 dynamic(() => import("./editor"), { ssr: false }) 加载编辑器。详见 Next.js。
如果这份 Fabric.js 问题排查清单没有覆盖你的问题,请带上错误 code、Fabric.js 版本和浏览器信息,提交一个 issue。