Fabric.js使用loadFromDatalessJSON加载多SVG对象时出错
解决Fabric.js加载含多SVG对象的无数据JSON时的forEach迭代错误
问题描述
你在使用Fabric.js处理包含多个SVG对象的无数据JSON(Dataless JSON)时遇到了报错,具体是在fabric.require.js:441行的objects.forEach(function(o, index) {处终止并抛出错误。
你的相关代码如下:
加载SVG的代码:
fabric.loadSVGFromURL(src, function(objects, options) { var img = fabric.util.groupSVGElements(objects, options); img.set('sourcePath', src); current.options.currentCanvas.add(img).renderAll(); img.set({ left: fabric.util.getRandomInt(40, 80), top: fabric.util.getRandomInt(40, 80), objID: newID, uploadBaseType: 'svg', origingSVG: src, }); }, null, true);
保存无数据JSON的代码:
JSON.stringify(current.options.createdCanvases[0].toDatalessJSON());
编辑阶段加载的代码:
canvas.loadFromDatalessJSON(output, canvas.renderAll.bind(canvas), function(o, object) {});
错误原因
问题的核心在于你在保存无数据JSON时,设置了obj.sourcePath = obj.origingSVG(SVG原始路径)——这个操作会导致对象数据中的objects键被替换成URL字符串。当forEach循环首次迭代后,原本存储子对象集合的objects数组被替换成了URL,后续自然无法继续执行数组的forEach方法,直接触发错误终止循环。
解决方案
要解决这个问题,关键是避免自定义属性和Fabric.js内部用来存储子对象集合的objects属性冲突,我们可以通过自定义独立字段存储SVG原始路径来规避这个问题:
1. 修改SVG加载时的属性设置
把存储原始SVG路径的字段换成自定义名称(比如svgOriginalPath),避免和Fabric内部属性冲突:
fabric.loadSVGFromURL(src, function(objects, options) { var img = fabric.util.groupSVGElements(objects, options); img.set('sourcePath', src); current.options.currentCanvas.add(img).renderAll(); img.set({ left: fabric.util.getRandomInt(40, 80), top: fabric.util.getRandomInt(40, 80), objID: newID, uploadBaseType: 'svg', svgOriginalPath: src, // 改用自定义字段存储原始路径 }); }, null, true);
2. 调整加载无数据JSON的回调逻辑(可选)
如果需要在加载后恢复sourcePath,可以在回调中安全设置,确保不破坏objects数组结构:
canvas.loadFromDatalessJSON(output, canvas.renderAll.bind(canvas), function(o, object) { // 仅当是SVG类型对象且存在自定义路径字段时,设置sourcePath if (object.uploadBaseType === 'svg' && object.svgOriginalPath) { object.sourcePath = object.svgOriginalPath; // 注意:不要修改object.objects属性,保持其数组结构不变 } });
总结
本质上是避免了自定义属性覆盖Fabric.js内部用于管理子对象的objects属性,通过自定义独立字段存储SVG原始路径,确保无数据JSON在序列化和反序列化过程中,对象结构不会被破坏,从而解决forEach迭代的错误。
内容的提问来源于stack exchange,提问作者sanjay chaudhary
相关产品推荐
相关产品推荐

