Canvas 使用fabric js的stickman示例在从json加载后不会保留行坐标逻辑

Canvas 使用fabric js的stickman示例在从json加载后不会保留行坐标逻辑,canvas,fabricjs,Canvas,Fabricjs,我试图使用JSON.stringify保存fabricjs stickman示例,并使用canvas.loadFromJSON将其加载回,我甚至使用以下方式将circleline1、line2、line3和line4的属性显式添加到JSON中 var jsonSave=JSON.stringify(canvas.toJSON(['line1','line2','line3','line4') 虽然我可以看到保存的JSON包含上述属性,但当我从JSON加载并尝试移动圆圈时,我得到一个错误,即未捕获

我试图使用JSON.stringify保存fabricjs stickman示例,并使用canvas.loadFromJSON将其加载回,我甚至使用以下方式将circleline1、line2、line3和line4的属性显式添加到JSON中

var jsonSave=JSON.stringify(canvas.toJSON(['line1','line2','line3','line4')

虽然我可以看到保存的JSON包含上述属性,但当我从JSON加载并尝试移动圆圈时,我得到一个错误,即未捕获类型错误:p.line1.set不是函数

我不明白为什么在保存之前,set是一个函数,但在保存并从JSON加载之后,它就不是了

还有没有其他方法可以让stickman工作而不使用set方法,这样在保存stickman并从JSON加载后它就不会中断

我确实查找了类似的问题,这个链接是我能找到的最类似的问题,但是这个答案中提供的解决方案似乎也没有解决保存和加载的问题

我还附上了下面的小提琴链接。重现情景

  • 尝试在小提琴加载后移动任何圆圈
  • 点击保存按钮。(您可以转到开发人员工具,在资源选项卡下查看会话存储中存储的JSON。)
  • 点击加载按钮
  • 尝试移动任何圆圈,并查看开发人员工具中的控制台选项卡

  • 任何帮助都将不胜感激。。谢谢..

    当您的代码创建圆对象时,您的代码会向圆对象添加额外的属性(例如line1、line2、line3、line4)。这些额外属性是对结构画布上现有线条对象的引用。您遇到的问题是,JSON格式不支持通过引用序列化对象。对象总是按值序列化。因此,对同一对象的多个引用将作为具有相同值的多个对象序列化为JSON字符串。当JSON字符串被反序列化时,您将拥有具有相同值的多个对象,而不是对同一对象的多个引用。为了进一步加剧问题,FabricJS的loadFromJSON()方法将顶级对象转换为FabricJS对象,但将内部属性对象(例如circle.line1)保留为普通对象。这些普通对象将不具有FabricJS方法(例如,无集合方法)

    如果您在谷歌上搜索“JSON对象引用”,那么您会发现一些文章,讨论以JSON格式保存对象引用的可能解决方法


    在您的情况下,一个可能的解决方案可能是将自定义特性(例如“$id”)添加到线条对象,其中自定义特性包含线条对象的唯一标识符。将此自定义属性保存到JSON字符串。加载JSON字符串后,可以扫描FabricJS画布中的线条对象,并创建从标识符到线条对象的映射。然后可以扫描FabricJS画布中的圆形对象,并使用地图中的线对象引用替换它们的线属性值。这不是一个简单的解决方案,但它应该可以工作。

    fabricjs可能的解决方法: (代码段不运行,如果您知道如何解决它,请告诉我)

    关键是要在save和load函数中编写自定义代码,以便再次将行附加到圆上

    var canvas=this.\uu canvas=newfabric.canvas('c',{selection:false}),saveNow,loadNow;
    fabric.Object.prototype.originX=fabric.Object.prototype.originY='center';
    (功能(){
    saveNow=(函数(){
    var jsonSave=JSON.stringify(canvas.toJSON(['linesID','selection','id']);
    sessionStorage.canvase=jsonSave;
    });
    函数_callBack(){
    var objs=canvas.getObjects();
    变量行={};
    对于(var i=0;i