3

我正在尝试使用fabric.js(v0.9.21,通过ubuntu 12.04上的npm安装)和node.js在服务器上呈现画布(以后可以在没有客户端交互的情况下对其进行操作和扩展)。为了进行实验,我在客户端创建了一个简单的画布,然后使用canvas.toJSON()方法将其导出为 JSON。当我尝试仅使用该 JSON 重新加载画布时,效果很好(利用canvas.loadFromJSON().

您可以在这个 fiddle中看到整个示例。

(如果它不起作用,那么图像可能已过期 - 替换链接)。

然后我尝试使用这个简单的脚本在服务器端做同样的事情:

var fabric = require('fabric').fabric;
var fs     = require('fs');
var canvas = fabric.createCanvasForNode(570, 600);

fs.readFile('kitty.json', 'utf8', function(err, data) {
  canvas.loadFromJSON(data);
});

运行此脚本(使用node script.jsor require('./script.js') from inside node)时出现奇怪的崩溃:

> http.createClient is deprecated. Use `http.request` instead.

/usr/lib/node_modules/fabric/dist/all.js:12429
      ctx.drawImage(
          ^
Error: Image given has not completed loading
    at klass.fabric.Image.fabric.util.createClass._render (/usr/lib/node_modules/fabric/dist/all.js:12429:11)
    at klass.fabric.Image.fabric.util.createClass.render (/usr/lib/node_modules/fabric/dist/all.js:12303:12)
    at klass.(anonymous function) [as render] (/usr/lib/node_modules/fabric/dist/all.js:2405:48)
    at extend._draw (/usr/lib/node_modules/fabric/dist/all.js:5332:16)
    at extend.renderAll (/usr/lib/node_modules/fabric/dist/all.js:5468:16)
    at extend.insertAt (/usr/lib/node_modules/fabric/dist/all.js:5381:37)
    at fabric.util.object.extend._enlivenObjects (/usr/lib/node_modules/fabric/dist/all.js:7694:15)
    at Array.forEach (native)
    at fabric.util.object.extend._enlivenObjects (/usr/lib/node_modules/fabric/dist/all.js:7693:24)
    at onLoaded (/usr/lib/node_modules/fabric/dist/all.js:1995:11)

画布上只有一张图片(由 interwebs 的小猫收藏提供)和一个文本项。

我对节点相当陌生,所以也许我在此过程中错过了一些东西 - 任何提示都会很棒。谢谢。

4

1 回答 1

0

我认为问题在于您试图在将图像添加到画布之前渲染画布。在我的情况下,在 loadFromJSON() 的回调中调用 renderAll() 解决了这个问题。

canvas.loadFromJSON(JSON.stringify(json),canvas.renderAll.bind(canvas));

或者

canvas.loadFromJSON(JSON.stringify(json),canvas.renderAll());

这将确保仅在将 json 数据加载到画布后才呈现画布

var canvas = new fabric.Canvas('mycanvas');
var json = {
  "objects": [{
    "type": "image",
    "left": 300,
    "top": 295,
    "width": 500,
    "height": 375,
    "fill": "rgb(0,0,0)",
    "overlayFill": null,
    "stroke": null,
    "strokeWidth": 1,
    "strokeDashArray": null,
    "scaleX": 1,
    "scaleY": 1,
    "angle": 0,
    "flipX": false,
    "flipY": false,
    "opacity": 1,
    "selectable": true,
    "hasControls": true,
    "hasBorders": true,
    "hasRotatingPoint": false,
    "transparentCorners": true,
    "perPixelTargetFind": false,
    "src": "http://t3.gstatic.com/images?q=tbn:ANd9GcTE0NOJqQ46En2x1T61cZf_S4RwxOTtxcLsmfQUHkSXk5SOx-zaYnPj6jYI",
    "filters": []
  }, {
    "type": "text",
    "left": 300,
    "top": 537,
    "width": 116,
    "height": 57.6,
    "fill": "rgb(0,0,0)",
    "overlayFill": null,
    "stroke": null,
    "strokeWidth": 1,
    "strokeDashArray": null,
    "scaleX": 1,
    "scaleY": 1,
    "angle": 0,
    "flipX": false,
    "flipY": false,
    "opacity": 1,
    "selectable": true,
    "hasControls": false,
    "hasBorders": true,
    "hasRotatingPoint": false,
    "transparentCorners": true,
    "perPixelTargetFind": false,
    "text": "Kitten!",
    "fontSize": 12,
    "fontWeight": 400,
    "fontFamily": "Lato",
    "fontStyle": "",
    "lineHeight": 1.2,
    "textDecoration": "",
    "textShadow": "",
    "textAlign": "center",
    "path": null,
    "strokeStyle": "",
    "backgroundColor": "",
    "textBackgroundColor": "",
    "useNative": true
  }],
  "background": "rgba(0, 0, 0, 0)"
};
canvas.loadFromJSON(JSON.stringify(json), canvas.renderAll.bind(canvas));
#mycanvas {
  border: 1px solid black;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.1.0/fabric.all.min.js"></script>
<canvas id="mycanvas" width="570" height="600"></canvas>

于 2015-12-21T13:00:19.670 回答