Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/439.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Fabric JS在数据库中存储步骤_Javascript_Reactjs_Fabricjs - Fatal编程技术网

Javascript Fabric JS在数据库中存储步骤

Javascript Fabric JS在数据库中存储步骤,javascript,reactjs,fabricjs,Javascript,Reactjs,Fabricjs,这个问题可能有点固执己见,事先对此表示歉意。有没有办法以有效的方式将步骤存储在FabricJS画布上?假设我是一个用户,我想稍后继续编辑画布,所以我关闭了窗口,下次打开它时,我们可以从数据库加载前面的所有步骤?我正在考虑将canvas.toJSON()存储到数据库中,但它非常大,比我需要的要大得多,因为所做的更改通常非常小。是否有任何函数或约定较短且“可加载”到画布?我正在考虑为此创建我自己的约定,只存储实际更改,即增量,这是一个好主意吗?您可以在其最终位置(或初始位置,无论什么)将其序列化,然

这个问题可能有点固执己见,事先对此表示歉意。有没有办法以有效的方式将步骤存储在FabricJS画布上?假设我是一个用户,我想稍后继续编辑画布,所以我关闭了窗口,下次打开它时,我们可以从数据库加载前面的所有步骤?我正在考虑将
canvas.toJSON()
存储到数据库中,但它非常大,比我需要的要大得多,因为所做的更改通常非常小。是否有任何函数或约定较短且“可加载”到画布?我正在考虑为此创建我自己的约定,只存储实际更改,即增量,这是一个好主意吗?

您可以在其最终位置(或初始位置,无论什么)将其序列化,然后在步骤之间保存增量,以便每次在历史中前进/后退时都可以使用
Object.assign()

let superBigObj = {a: 100, b: 200, c: 300, d: {hello: "world"}};

let smallObj = Object.assign(superBigObj, {c: 400});

// smallObj is now: {a: 100, b: 200, c: 400, d: {hello: "world"}};
问题在于,您需要编写重复数据消除程序以递归方式删除相同的属性(或仅提取更改的属性)

如果您担心数据库中的大小,那么您可以执行类似于
atob
btoa
的操作来base64 it

TL;博士 您可以删除不必要的(默认)对象数据并使用
lz字符串压缩


结果如此长的原因是它提供了包括默认值在内的所有属性。因此,您可以通过删除默认值来解决这个问题

此示例脚本删除值为
0
null
的每个对象属性

var canvas=newfabric.canvas('c');
add(newfabric.Rect({left:50,top:50,height:20,width:20,fill:'green'));
canvas.add(新的fabric.Circle({left:100,top:100,radius:50,fill:'red'}));
让output=canvas.toJSON();
让copy={…输出,对象:[]};
(output.objects | |[]).map(object=>{
让objectCopy={};
for(让输入对象){
val=对象[键];
如果(val!==null&&val!==0){
objectCopy[key]=对象[key]
}否则{
//console.log('skipped',key,object[key])
}
}
copy.objects.push(objectCopy);
})
var canvas2=newfabric.Canvas('d');
canvas2.loadFromJSON(JSON.stringify(canvas));
log(JSON.stringify(canvas.length);
log(JSON.stringify(copy.length)
#画布包装器{
位置:相对位置;
}


谢谢Daniel,我试过你的例子,效果很好。我有两个关于“另一种方法”的问题1。它支持嵌套对象吗?2.让画布读取经过
lz字符串压缩的JSON容易吗?还有一个离题的问题,如果我假设将所有这些步骤存储在某个唯一标识符下,例如
canvas\u session\u id
,那么最好的数据库存储体系结构是什么?我正在考虑关键值存储。但可能不是最好的选择,因为我假设在我的用例中读取和写入的频率相同。如果在存储之前进行压缩,则可以在加载数据之前取消压缩。压缩有助于存储和传输。如果您以压缩格式存储,则键值应该可以,如果您将其发送到服务器进行数据存储,则可以进行去抖动,数据将保存在本地,并较少上载。如果您希望保留每个步骤,那么每个步骤都需要存储。如果我只坚持使用
Object.assign()
我不会创建任何重复的属性,对吗?或者你的意思是,如果我不小心将相同的属性名称分配给两个不同的东西?同样,通过这种方法,我必须发明自己的存储和加载约定,对吗?@Alien13对--现有的属性将被新属性覆盖(因此
c
将成为
400
)。存在于其中但不存在于另一个的事物将被添加。这在处理嵌套对象时是草率的,但这可能是一个开始。另一个答案看起来更具体。是的,你必须发明一种存储/加载机制。通过对对象进行重复数据消除来保存增量,然后
.assign()
将该增量重新组装为重复数据消除的对象。不过警告:这将不会非常有效。