I am trying to subclass a fabricjs Image for a barcode field.
import {fabric} from 'fabric';
import bwipjs from 'bwip-js';
class Barcode extends fabric.Image {
constructor(options) {
console.log("constructor", options);
var wrkOptions = {
width: options.position.width,
height: options.position.height,
left: options.position.left,
top: options.position.top,
angle: options.direction || 0,
form: options.form || {}
};
super(wrkOptions);
this.type = 'barcode';
let canvas1 = document.createElement('canvas');
canvas1.width = options.position.width;
canvas1.height = options.position.height;
var bcOptions = { bcid: 'code128', // Barcode type
text: '0123456789', // Text to encode
scale: 3, // 3x scaling factor
height: 10, // Bar height, in millimeters
includetext: true, // Show human-readable text
textxalign: 'center', // Always good to set this
};
bwipjs.toCanvas(canvas1, bcOptions);
var dataUrl = canvas1.toDataURL("image/png");
this.setSrc(dataUrl, () => {
if (!options.restore) {
curCanvas.add(this);
this.setOptions(options);
this.setCoords();
}
},
wrkOptions);
}
toObject = () =>{
var ret = {
type: this.type,
position: {top: this.top, left: this.left, width: this.width * this.scaleX, height: this.height * this.scaleY},
color: this.fill,
direction: this.angle,
form: this.form
};
console.log(ret);
return ret;
}
}
fabric.Barcode = Barcode;
fabric.Barcode.fromObject = function (options, callback) {
var wrkOptions = {restore: true, ...options};
var bc = new Barcode(wrkOptions);
callback(bc);
};
Creating the barcode field works:
onAddBarcode = () => {
var color = Math.floor(Math.random() * 256 * 256 *256).toString(16);
var options = {
color: "#" + color,
position: {
top: Math.floor(Math.random() * 500),
left: Math.floor(Math.random() * 500),
width: Math.floor(Math.random() * 100),
height: Math.floor(Math.random() * 100)
}
};
return ret;
...this.getRandom()
};
var barcode = new Barcode(options);
}
But serializing and restoring the canvas does not work:
onReload = () => {
var json = JSON.stringify(this.canvas, null, 2);
this.canvas.clear();
this.canvas.loadFromJSON(json, this.canvas.renderAll.bind(this.canvas));
}
It does restore a barcode image, but it is positioned wrongly outside of the controls.
What's wrong?
I got it positioned correctly (after restoring) by resetting the position attributes in the setSrc callback:
....
this.setSrv(dataUrl,
() => {
this.left = options.position.left;
this.top = options.position.top;
this.angle = options.direction || 0;
this.width = options.position.width;
this.height = options.position.height;
this.setCoords();
callback(this);
});