javascript - Fabric JS在数据库中存储步骤
问题描述
这个问题可能有点自以为是,对此提前表示抱歉。有什么方法可以有效地存储在 FabricJS 画布上完成的步骤?假设我是一个用户,我想稍后继续编辑我的画布,所以我关闭了窗口,下次打开它时,我们可以从数据库中加载所有之前的步骤吗?我正在考虑存储canvas.toJSON()
到数据库中,但它非常大,比我需要的要大得多,因为所做的更改通常非常小。是否有任何更短且“可加载”到画布的功能或约定?我正在考虑为此创建自己的约定,仅存储实际更改,即增量,这是个好主意吗?
解决方案
TL;博士;
您可以删除不必要的(默认)对象数据并使用压缩lz-string
结果如此长的原因是它为您提供了所有属性,包括默认值。所以你可以通过删除默认值来解决这个问题。
此示例脚本删除每个值为0
or的对象属性null
。
var canvas = new fabric.Canvas('c');
canvas.add(new fabric.Rect({left: 50, top: 50, height: 20, width: 20, fill: 'green'}));
canvas.add(new fabric.Circle({left: 100, top: 100, radius: 50, fill: 'red'}));
let output = canvas.toJSON();
let copy = {...output, objects:[]};
(output.objects || []).map(object => {
let objectCopy = {};
for (let key in object) {
val = object[key];
if (val !== null && val !== 0){
objectCopy[key] = object[key]
} else {
// console.log('skipped', key, object[key])
}
}
copy.objects.push(objectCopy);
})
var canvas2 = new fabric.Canvas('d');
canvas2.loadFromJSON(JSON.stringify(canvas));
console.log(JSON.stringify(canvas).length);
console.log(JSON.stringify(copy).length);
#canvas-wrapper {
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js" integrity="sha512-ACqMrfAtm537AWzgx/xQ57JnFxXeq8RylQMGg4y/e6M2ew4Z8NycE8aId/Bt2ZE+w1gNsox3MgwxKl7SGMRdtA==" crossorigin="anonymous"></script>
<div id="canvas-wrapper"><canvas id="c" width="400" height="200" /></div>
<div id="canvas-wrapper"><canvas id="d" width="400" height="200" /></div>
这给了我们大约 20% 的改进。
此外,这种方法很幼稚,还有很大的改进空间。它不能处理组(嵌套对象),如果您将默认值 1 覆盖为 0(即strokeWidth
),它将忽略它并导致错误的结果。因此,该解决方案必须考虑每种对象类型的完整默认设置列表,但它可以很容易地为您提供超过 50% 的常用压缩率。
另一种选择是使用压缩库(如lz-string
)来压缩您的字符串结果。这可以开箱即用地为您带来 %70-%80 的改进。这更快,更可靠。
恕我直言,理想的情况是两者都做,这可以让你降低到原来的 5-10%
推荐阅读
- c# - 如何知道是否有来自 Windows 服务的交互式会话处于活动状态?
- python - 浏览全局 file_name 变量中的图像后 imread 出错
- javascript - IE>10浏览器通过js获取上一个URL
- javascript - socket.io 在 node.js 中等待响应
- magento2 - 在送货地址中,我希望按城市计算运费,因为它们默认使用国家和邮政编码
- css - 将 SVG 路径设为 100% 宽度?
- reactjs - 使用 Webpack 构建后未定义窗口
- macos - MacOS 上的 CRM 控制台应用程序
- .net-core - EntityFrameworkCore 对存储过程的支持
- python - 在 sql.select 中提供条件作为第二个参数