为了账号安全,请及时绑定邮箱和手机立即绑定

FabricJS:使用 Image 子类时无法执行“drawImage”

FabricJS:使用 Image 子类时无法执行“drawImage”

慕桂英3389331 2023-09-28 17:45:50
对于一个项目,我需要将各种类型的图像添加到画布,保存为 JSON 并再次加载。不同的类型没有任何特定的属性,我只需要类型不同即可。我创建了一个基于 Fabric.Image 的新类,如下所示:fabric.Icon = fabric.util.createClass(fabric.Image, {      type: "icon",      initialize: function (element, options) {        this.callSuper("initialize", element, options);      },      _render: function (ctx) {        this.callSuper("_render", ctx);      },    });    fabric.Icon.fromObject = function (object, callback) {      return fabric.Object._fromObject("Icon", object, callback);    };之后,我使用 SVG 图像添加这种新类型的新对象:let newImage = new Image();    //HTML Image type, not FabricJSnewImage.onload = () => {   let icon = new fabric.Icon(newImage);   //my subclass of fabric.Image class   this.canvas.add(icon);};newImage.src = "image.svg";当我将画布导出为 JSON 时let savedJSON = canvas.toJSON()并将其加载回来canvas.loadFromJSON(savedJSON, function () {    canvas.requestRenderAll();}我收到以下错误未捕获的类型错误:无法在“CanvasRenderingContext2D”上执行“drawImage”:提供的值不是类型“(CSSImageValue或HTMLImageElement或SVGImageElement或HTMLVideoElement或HTMLCanvasElement或ImageBitmap或OffscreenCanvas)”当我使用标准 Fabric.Image 类时,一切正常。我应该重写子类中的其他方法吗?或者我应该以其他方式区分各种图像类型?
查看完整描述

2 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞

Fabric Image 类具有稍微复杂的恢复机制,因为它需要在构造函数中使用不可序列化的图像元素。


这就是它在 FabricJS 中的实现方式:


  /**

   * Creates an instance of fabric.Image from its object representation

   * @static

   * @param {Object} object Object to create an instance from

   * @param {Function} callback Callback to invoke when an image instance is created

   */

  fabric.Image.fromObject = function(_object, callback) {

    var object = fabric.util.object.clone(_object);

    fabric.util.loadImage(object.src, function(img, isError) {

      if (isError) {

        callback && callback(null, true);

        return;

      }

      fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {

        object.filters = filters || [];

        fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) {

          object.resizeFilter = resizeFilters[0];

          fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {

            object.clipPath = enlivedProps[0];

            var image = new fabric.Image(img, object);

            callback(image, false);

          });

        });

      });

    }, null, object.crossOrigin);

  };

恐怕你必须复制它并将 Fabric.Image 与 Fabric.Icon 交换


查看完整回答
反对 回复 2023-09-28
?
跃然一笑

TA贡献1826条经验 获得超6个赞

好吧,这并不是这个问题的真正解决方案,但我找到了区分在保存和加载过程中持续存在的对象的正确方法 - 通过覆盖其 toObject 方法来设置 Object.prototype 上的自定义属性,如下所示:Fabric js extends toObject with custom属性,丢失默认属性 问题解决!



查看完整回答
反对 回复 2023-09-28
  • 2 回答
  • 0 关注
  • 191 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信