Reputation: 3126
When fabricjs serializes a canvas it stores image src urls as full paths even if assets are (and were loaded as) relative on server.
e.g. assets/images/someimage.png
ends up as http://myserver.com/assets/images/someimage.png
I export the canvas json for loading in a hybrid mobile app which needs relative urls for local filesystem. (and doesn't want to know about the url of the server the canvas content was configured on)
My hack is in changing fabric.js:
loadImage: function(url, callback, context, crossOrigin) {
if (!url) {
callback && callback.call(context, url);
return;
}
// HACK: force relative
url = 'assets'+url.split('assets')[1];
basically to trim the url to make relative.
If there is an update to fabric I'll have to reapply this every time. I would prefer to just override the loadimage from the outside but ran into problems trying this with scope i.e Buffer and request objects.
Can anyone suggest a clean way of doing this? i.e without touching fabric.js I would kind of prefer if urls were serialized as relative in the first place.
Upvotes: 4
Views: 1399
Reputation: 41
2022 update:
It is now natively supported by setting Image attribute srcFromAttribute: true
(https://github.com/fabricjs/fabric.js/pull/5484)
fabric.Image.fromURL('assets/images/someimage.png', function(myImg) {
const img1 = myImg.set({ left: 0, top: 0, srcFromAttribute: true });
canvas.add(img1);
});
Upvotes: 0
Reputation: 2862
A better way is to override toObject in the Image class. This way the src is stored as relative when your images are serialized, rather than changing the url when an image is loaded (plus you don't have to modify the Fabric library which is never a good idea).
fabric.Image.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
src: 'assets'+this.getSrc().split('assets')[1];
});
};
})(fabric.Image.prototype.toObject);
Upvotes: 1