fabric.js通过canvas.tojson()和loadfromjson()实现对象级序列化,但默认冗余大;大型画布需精简属性、分离图片资源、适配标准格式以兼顾性能与互操作性。

Canvas 本身不提供内置的序列化能力,真正实现图形数据 JSON 存储,依赖的是上层绘图库(如 Fabric.js)或手动构建的数据结构。核心不是“把 Canvas 元素转成 JSON”,而是把画布上的**对象状态**提取、标准化、持久化。
用 Fabric.js 快速完成完整序列化
Fabric.js 是目前最成熟的支持 Canvas 对象级序列化的库,它把每个图形(矩形、文本、图片等)都封装为可序列化的对象实例。
- 调用 canvas.toJSON() 即可获取整个画布的完整 JSON 表示,包含所有对象的位置、尺寸、样式、层级、组合关系等
- 反向加载只需 canvas.loadFromJSON(json, () => canvas.renderAll()),Fabric 会自动重建对象并渲染
- 默认保存全部属性(包括未显式设置的 originX、version、strokeDashArray 等),适合小画布;大型画布建议精简
控制序列化范围,避免数据膨胀
默认 toJSON() 输出体积大、冗余多,尤其在数百对象场景下易达 MB 级。可通过参数或重写方法压缩:
- 传入属性白名单: canvas.toJSON(['left', 'top', 'width', 'height', 'fill', 'text']),只保留业务必需字段
- 重写对象的 toObject 方法,在其中过滤或添加自定义字段(如业务 ID、标签、版本号)
- 对图片类对象,避免直接存 base64 —— 改为存 URL 或唯一标识符,由前端按需加载
适配 JSON Canvas 规范,提升兼容性
若需跨应用互通(如导出为 .canvas 文件、与 Obsidian 或其他白板工具协作),应采用标准 JSON Canvas 格式:
- 结构固定为 { "nodes": [...], "edges": [...] },nodes 描述元素(text/file/link/group),edges 描述连接关系
- 每个 node 至少含 id、type、x、y、width、height;支持 color 编码(如 "4" 表示绿色)
- 可编写转换器:将 Fabric 对象映射为 nodes 数组,把 group 内嵌对象扁平化,把连线信息提取为 edges
图片资源单独处理,不塞进主 JSON
Canvas 中的图片若以 base64 形式直接写入 JSON,会导致体积剧增、解析变慢、难以复用。
- 推荐方案:图片上传后返回 CDN 地址或本地 blob URL,JSON 中仅存 src 字段
- 离线场景可用 IndexedDB 存储 Blob,JSON 中记录 key,加载时查库还原
- 若必须内联,确保使用 canvas.toDataURL('image/png', 0.8) 控制质量,并剔除 data:image/png;base64, 前缀后存为纯字符串
不复杂但容易忽略:序列化不是“一键保存”,关键在定义好哪些状态要留、哪些可丢、哪些需外部托管。选对结构,才能兼顾性能、可维护和互操作性。











