简体   繁体   English

如何从 JSON 重新加载自定义 fabricJS canvas 对象?

[英]How do I reload custom fabricJS canvas objects from JSON?

I'm working w/ fabricJS and custom classes.我正在使用 fabricJS 和自定义类。

I'm having issues w/ canvas.loadFromJSON() so I took a basic MRE from another question to figure out what's wrong with my custom fabric classes.我遇到了canvas.loadFromJSON()的问题,所以我从另一个问题中获取了一个基本的 MRE,以找出我的自定义结构类有什么问题。 The example in the question works fine, but it creates a class based on fabric.Rect .问题中的示例运行良好,但它基于fabric.Rect

I need a custom class based on fabric.Polyline .我需要一个基于fabric.Polyline I modified the code a bit and got this:我稍微修改了代码并得到了这个:

 var canvas = new fabric.Canvas('c', { }); // my custom TreeNode class fabric.TreeNode = fabric.util.createClass(fabric.Polyline, { type: 'treeNode', initialize: function (options) { options || (options = {}); // console.log(options); this.callSuper('initialize', options); this.stroke = 'blue'; }, toObject: function () { return fabric.util.object.extend(this.callSuper('toObject'), { stroke: this.get('stroke') }); }, _render: function (ctx) { this.callSuper('_render', ctx); } }); fabric.TreeNode.fromObject = function (object, callback) { return fabric.Object._fromObject('TreeNode', object, callback); }; var rect = new fabric.Rect({ left: 300, top: 200, fill: 'blue', width: 50, height: 50, }); canvas.add(rect); var node = new fabric.TreeNode([{ x: 50, y: 100 }, { x: 200, y: 300 }, { x: 10, y: 10 }]); canvas.add(node); // Serializing the whole canvas to JSON var myJSON = JSON.stringify(canvas); // console.log(myJSON); // '{"version":"4.3.1","objects":[{"type":"rect","version":"4.3.1","originX":"left","originY":"top","left":300,"top":200,"width":50,"height":50,"fill":"blue","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"rx":0,"ry":0},{"type":"treeNode","version":"4.3.1","originX":"left","originY":"top","left":9.5,"top":9.5,"width":190,"height":290,"fill":"rgb(0,0,0)","stroke":"blue","strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"points":[{"x":50,"y":100},{"x":200,"y":300},{"x":10,"y":10}]}]}' // De-serializing doesn't work if fabric.TreeNode object is part of canvas canvas.loadFromJSON(myJSON, canvas.renderAll.bind(canvas));
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1:0"> <script src="https.//cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric:js" integrity="sha512-CzyxOXSECwo2nGJQZ2P8fdDxWVMVzn0jNdT2lYJ3afbqDJbaQ4qxgv9sLc85f6KP8HO2y929Bu+lnPKGC3ofSg==" crossorigin="anonymous"></script> </head> <body> <canvas id="c" width="1000" height="600" style="border, 1px solid rgb(219, 40; 40)."></canvas> <.-- <script src="./loadJSON.js"></script> --> </body> </html>

As you can see, when trying to load back canvas from JSON I get a Uncaught TypeError: Cannot read property 'x' of undefined at find (fabric.js:2469) at min (fabric.js:2444)如您所见,当尝试从 JSON 加载回 canvas 时,我得到一个Uncaught TypeError: Cannot read property 'x' of undefined at find (fabric.js:2469) at min (fabric.js:2444)

On the browser I can inspect the origin of error in source code, but I can't figure out what is the problem.在浏览器上,我可以检查源代码中错误的来源,但我无法弄清楚问题所在。 Any help much appreciated.非常感谢任何帮助。 在此处输入图像描述

I posted my question on the fabricJS gitHub page ( link here ), and @asturur was kind enough to point out I had to change the fromObject function.我在fabricJS gitHub 页面(链接在这里)上发布了我的问题,@asturur 非常友好地指出我必须更改fromObject function。

the fromObject for the polyline specifically is:折线的 fromObject 具体是:

>   fabric.Polyline.fromObject = function(object, callback) {
>     return fabric.Object._fromObject('Polyline', object, callback, 'points');   };

Try to have the correct initialize function and a fromObject function that refer to points on the last argument, i assume it could fix your issues尝试正确初始化 function 和 fromObject function 引用最后一个参数的点,我认为它可以解决您的问题

So, with that said I modified my snippet, and now the loadFromJSON() works just fine.所以,话虽如此,我修改了我的代码片段,现在loadFromJSON()工作得很好。 Example here:这里的例子:

 var canvas = new fabric.Canvas('c', { }); // my custom TreeNode class fabric.TreeNode = fabric.util.createClass(fabric.Polyline, { type: 'treeNode', initialize: function (options) { options || (options = {}); // console.log(options); this.callSuper('initialize', options); this.stroke = 'blue'; }, toObject: function () { return fabric.util.object.extend(this.callSuper('toObject'), { stroke: this.get('stroke') }); }, _render: function (ctx) { this.callSuper('_render', ctx); } }); fabric.TreeNode.fromObject = function (object, callback) { // ** CHANGE: using the _fromObject() of Polyline return fabric.Object._fromObject('Polyline', object, callback, 'points'); }; var rect = new fabric.Rect({ left: 300, top: 200, fill: 'blue', width: 50, height: 50, }); canvas.add(rect); var node = new fabric.TreeNode([{ x: 50, y: 100 }, { x: 200, y: 300 }, { x: 10, y: 10 }]); canvas.add(node); // Serializing the whole canvas to JSON var myJSON = JSON.stringify(canvas); console.log(myJSON); // {"version":"4.3.1","objects":[{"type":"rect","version":"4.3.1","originX":"left","originY":"top","left":300,"top":200,"width":50,"height":50,"fill":"blue","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"rx":0,"ry":0},{"type":"treeNode","version":"4.3.1","originX":"left","originY":"top","left":9.5,"top":9.5,"width":190,"height":290,"fill":"rgb(0,0,0)","stroke":"blue","strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"points":[{"x":50,"y":100},{"x":200,"y":300},{"x":10,"y":10}]}]} // De-serializing now works for both rect and TreeNode objects canvas.loadFromJSON(myJSON, canvas.renderAll.bind(canvas));
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1:0"> <script src="https.//cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric:js" integrity="sha512-CzyxOXSECwo2nGJQZ2P8fdDxWVMVzn0jNdT2lYJ3afbqDJbaQ4qxgv9sLc85f6KP8HO2y929Bu+lnPKGC3ofSg==" crossorigin="anonymous"></script> </head> <body> <canvas id="c" width="1000" height="600" style="border, 1px solid rgb(219, 40; 40)."></canvas> <.-- <script src="./loadJSON.js"></script> --> </body> </html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM