对于一个项目,我需要将各种类型的图像添加到画布中,保存到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 FabricJS
newImage.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();
}
我得到以下错误
Uncaught :未能在“CanvasRenderingContext2D”上执行“drawImage”:提供的值不是类型(CSSImageValue或HTMLImageElement或SVGImageElement或HTMLVideoElement或HTMLCanvasElement或ImageBitmap或OffscreenCanvas)
当我使用标准fabric.Image类时,一切都正常工作。应该重写子类中的其他方法吗?还是应该以另一种方式区分不同的图像类型?
发布于 2020-12-03 19:16:32
嗯,这个问题并不是真正的解决方案,但我找到了正确的方法来区分保存和加载中持续存在的对象--通过重写Object.prototype的toObject方法来设置自定义属性,比如:解决Fabric js extending toObject with custom properties, loses default ones问题!
发布于 2020-12-04 21:41:08
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交换
https://stackoverflow.com/questions/65112221
复制相似问题