在 node.js 中使用 fabric.js 渲染和操作服务器端画布
Posted
技术标签:
【中文标题】在 node.js 中使用 fabric.js 渲染和操作服务器端画布【英文标题】:Using fabric.js to render and manipulate server-side canvas in node.js 【发布时间】:2012-12-01 07:34:52 【问题描述】:我正在尝试将fabric.js(v0.9.21,在ubuntu 12.04上通过npm安装)与node.js一起在服务器上呈现画布(以后可以在没有客户端交互的情况下对其进行操作和扩展)。为了进行实验,我在客户端创建了一个简单的画布,然后使用canvas.toJSON()
方法将其导出为 JSON。当我尝试仅使用该 JSON 重新加载画布时,效果很好(使用 canvas.loadFromJSON()
)。
你可以看到整个例子in this 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.js
或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 的小猫收藏提供)和一个文本项。
我对 node 还很陌生,所以也许我在此过程中遗漏了一些东西 - 任何提示都会很棒。谢谢。
【问题讨论】:
你有哪些版本的节点和节点画布?您是否也遵循了 node-canvas 安装说明? github.com/LearnBoost/node-canvas/wiki/Installation---Ubuntu 我在 Ubuntu 12.04 上使用画布 0.13.1、节点 0.8.16 和结构 0.9.21。我按照说明再次重新安装以确保结果仍然相同。您能否使用您的设置运行我的代码(假设版本相同)?谢谢! 嗯,这很奇怪......缩小到http.request
现在有不同的签名(显然在节点 0.8.x 中)。我以为我们在生产中使用 0.8,这让我想知道事情如何仍然有效。无论如何,用这个替换 request
方法似乎可以做到 - gist.github.com/600934872f28397e6350。我将对此进行更多研究并更新 Fabric 本身。
很高兴知道 - 感谢您的调查。
【参考方案1】:
我认为问题在于您试图在将图像添加到画布之前渲染画布。在我的情况下,在 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" ></canvas>
【讨论】:
以上是关于在 node.js 中使用 fabric.js 渲染和操作服务器端画布的主要内容,如果未能解决你的问题,请参考以下文章
Fabric.JS 与 Node.JS - 导出为 PNG/JPEG
在 python 服务器上从 Fabric.js JSON 构造图像