当前位置: 首页 > 面试题库 >

Fabric.js-如何使用自定义属性在服务器上保存画布

公孙阳文
2023-03-14
问题内容

我希望能够将当前canvas的状态保存为服务器端数据库(可能作为JSON字符串),然后再使用进行恢复loadFromJSON。通常,这很容易使用以下方法完成:

var canvas = new fabric.Canvas();
function saveCanvas() {
    // convert canvas to a json string
    var json = JSON.stringify( canvas.toJSON() );

    // save via xhr
    $.post('/save', { json : json }, function(resp){ 
        // do whatever ...
    }, 'json');
}

然后

function loadCanvas(json) {

  // parse the data into the canvas
  canvas.loadFromJSON(json);

  // re-render the canvas
  canvas.renderAll();

  // optional
  canvas.calculateOffset();
}

但是,我还使用内置Object#set方法在要添加到画布上的结构对象上设置了一些自定义属性:

// get some item from the canvas
var item = canvas.item(0);

// add misc properties
item.set('wizard', 'gandalf');
item.set('hobbit', 'samwise');

// save current state
saveCanvas();

问题是,当我在服务器端检查请求时,我看到我的自定义属性没有从画布中解析出来,而是随其他内容一起发送。这可能与toObject方法如何删除对象类中不是默认属性的任何内容有关。解决该问题的一种好方法是什么,这样我就可以从服务器发送的JSON字符串中保存
还原画布,并且还原的画布还将包含我的自定义属性?谢谢。


问题答案:

好问题。

如果要向对象添加自定义属性,则这些对象在某种程度上可能是“特殊的”。子类化似乎是一个合理的解决方案。

例如,这是我们将a子类fabric.Image化为命名图像的方法。这些图像对象然后可能具有“ Gandalf”或“ Samwise”之类的名称。

fabric.NamedImage = fabric.util.createClass(fabric.Image, {

  type: 'named-image',

  initialize: function(element, options) {
    this.callSuper('initialize', element, options);
    options && this.set('name', options.name);
  },

  toObject: function() {
    return fabric.util.object.extend(this.callSuper('toObject'), { name: this.name });
  }
});

首先,我们给这些对象一个类型。此类型用于loadFromJSON自动调用fabric.<type>.fromObject方法。在这种情况下会是fabric.NamedImage.fromObject

然后,我们覆盖initialize(构造函数)实例方法,以便在初始化对象时也设置“名称”属性(如果提供了该属性)。

然后,我们覆盖toObject实例方法以在返回的对象中包含“名称”(这是结构中对象序列化的基石)。

最后,我们还需要实现fabric.NamedImage.fromObject我之前提到的loadFromJSON方法,以便知道在JSON解析期间要调用的方法:

fabric.NamedImage.fromObject = function(object, callback) {
  fabric.util.loadImage(object.src, function(img) {
    callback && callback(new fabric.NamedImage(img, object));
  });
};

我们正在这里加载图像(来自“
object.src”),然后从中创建一个实例fabric.NamedImage。请注意,到那时,构造函数将已经处理“名称”设置,因为我们之前覆盖了“初始化”方法。

并且我们还需要指定它fabric.NamedImage是一个异步“类”,这意味着它fromObject不返回实例,而是将其传递给回调:

fabric.NamedImage.async = true;

现在我们可以尝试一下:

// create image element
var img = document.createElement('img');
img.src = 'https://www.google.com/images/srpr/logo3w.png';

// create an instance of named image
var namedImg = new fabric.NamedImage(img, { name: 'foobar' });

// add it to canvas
canvas.add(namedImg);

// save json
var json = JSON.stringify(canvas);

// clear canvas
canvas.clear();

// and load everything from the same json
canvas.loadFromJSON(json, function() {

  // making sure to render canvas at the end
  canvas.renderAll();

  // and checking if object's "name" is preserved
  console.log(canvas.item(0).name);
});


 类似资料:
  • 我正在进行一个生成艺术项目,我希望允许用户保存从一个算法得到的图像。大意是: 使用生成算法在HTML5画布上创建图像 完成映像后,允许用户将画布作为映像文件保存到服务器 允许用户下载图像或将其添加到使用该算法生成的图像库中。 然而,我却被卡在了第二步上。经过谷歌的一番帮助,我找到了这篇博文,似乎正是我想要的: 这导致了JavaScript代码: 和相应的PHP(testsave.PHP): 但这似

  • Appium 的 iOS 版本的后端用的是Facebook's WebDriverAgent。该后端是基于苹果公司的 XCTest 框架,所以也有所有XCTest 框架已知的问题。其中有些问题我们正在设法解决,有一些在现阶段可能无法解决。本文中描述的方法已经能够使您完全掌握在设备上如何构建、管理和运行WDA。通过这种方式,您可以在CI环境中对您的自动化测试进行微调,并使其在长期运行的情况下更加稳定

  • 我已经为Word创建了一个插件。我正在尝试通过单击按钮更新word文档中的自定义属性的值。但却得不到拯救。我写的代码是: 但如果我在文档中添加一个空格然后保存它。然后保存自定义属性的值。代码为: 为什么行为是这样的。我不想在我的文档中添加任何额外的空白处。请帮帮我。提前道谢。

  • 您需要创建一个通用的JpaRepository,以便处理系统进行的所有事务。在这里遵循这个示例。 它与实现有点不同,因为我的目标不是执行搜索,而是操作save方法。 unsatisfiedDependencyException:创建名为“sistema menuservice”的bean时出错:通过字段“sistema menurepository”表示未满足的依赖关系;嵌套异常是org.spri

  • 我使用JAXB根据一些XSD模式生成java类。对于以下元素: <代码> jaxb生成以下代码: 问题是我们需要使用一些依赖于getter/setter方法命名约定的专有XML工具,例如,对于字段REC_LOC他们希望使用名为getRecLoc(String value)和setRecLoc()的方法,而不是getRECLOC()。 有没有办法自定义jaxb生成的方法名?

  • 我正在努力使用JavaScript和PHP将我的画布图像保存到服务器。我已经尝试了JS和PHP的多个例子,但总是失败。关于如何将图像数据发送到PHP脚本(bas64、blob、FormData),有相互矛盾的建议,我不确定如何最好地与JS通信。目前,零字节的PNG文件被保存到服务器,我不知道为什么。我想在服务器上将生成的画布保存为PNG,并在成功时在JS中执行命令。如何最好地处理它? JS: PH