Reputation:
I'm trying to use FabricJS canvas, and I'd like to export canvas as JSON.
I've tried loading image using both new fabric.Image
and fabric.Image.fromURL
both of them work great.
Now I want to get JSON from canvas. But I want 2 kinds of JSON. One where image's src would be link to a image which I used initially. Another would simply add base64 data right on JSON. So I tried to use canvas.toJSON()
and canvas.toDatalessJSON()
, but to my surprise, It simply gives same result with link, and none of them contain image data.
How do I export to JSON which INCLUDES image data right on JSON? (I already got with the link)
I've put together a small demo of what I have till now. Notice when you click on export and see on console, both objects have source link and none of them actually have base64 data.
The reason I want base64 is because I want it instant when I re-use somewhere else.
I tried searching over the internet, according to docs, toJSON should contain, but looks like it's only for shapes, and not image. Or did I miss something?
Thanks in advance!
Upvotes: 5
Views: 3083
Reputation: 15604
Extend toObject of fabric.Image
fabric.Image.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
src: this.toDataURL()
});
};
})(fabric.Image.prototype.toObject);
And for src use object.toDataURL()
DEMO
const useFabricImage = () => {
const c = document.getElementById("designer");
const canvas = new fabric.Canvas(c, {width: 500, height: 500})
const url = "https://i.imgur.com/KxijB.jpg";
const img = new Image();
img.src = url;
const fabricImage = new fabric.Image(img, {});
canvas.add(fabricImage);
return canvas;
}
const useFromURL = () => {
const c = document.getElementById("designer");
const canvas = new fabric.Canvas(c, {width: 500, height: 500})
const url = "https://i.imgur.com/KxijB.jpg";
fabric.Image.fromURL(url, (img) => {
canvas.add(img);
},{
crossOrigin:'annonymous'
});
return canvas;
}
fabric.Image.prototype.toDatalessObject = fabric.Image.prototype.toObject;
fabric.Image.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
src: this.toDataURL()
});
};
})(fabric.Image.prototype.toObject);
const canvas = useFromURL();
const button = document.getElementById("export");
button.addEventListener("click", () => {
console.log(canvas.toJSON());
console.log(canvas.toDatalessJSON());
})
#designer {
border: 1px solid aqua;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.3/fabric.min.js"></script>
<canvas id="designer" height="500" width="500"></canvas>
<button id="export">Export</button>
Upvotes: 6
Reputation: 2777
You need to extend fabric.Image.protype.toObject()
:
fabric.Image.prototype.toObject = (function (toObject) {
return function () {
var image = this;
var getData = function () {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
context = canvas.getContext('2d');
context.drawImage(image.getElement(), 0, 0);
return canvas.toDataURL('image/png').replace(/^data:image\/png;base64,/, '');
};
return fabric.util.object.extend(toObject.call(this), {
dataURL: getData(),
});
};
})(fabric.Image.prototype.toObject);
After that dataURL
property will be automatically added to your object.
Upvotes: 1