I am making drawing editor using Fabric.js. One of the requirements is to create flexible text box component (like Goole Slides or Power Point) whose bounding box can be adjusted without compromising text size and other text controls like scale, reposition... Currently, what fabric.js provides with fabric.Text
is not sufficient for this task. So I am using fabric.Group
but I am stack on selection issue. I cannot select sub-objects of group. How can I go about this issue. Any information is welcome
This is I want to achieve:
This is what I have now with raw fabric.Text
object
This is what I have achieved with fabric.Group
Here is my class which is intended for Textbox
class Text extends fabric.Group {
constructor(options) {
super([], Object.assign(options));
this.class = 'textbox';
this.init();
}
init() {
const left = this.left;
const top = this.top;
const width = this.width || 100;
const height = this.height || 40;
this.rect = new fabric.Rect({
left,
top,
width,
height,
fill: 'rgba(0,0,0,0)',
stroke: this.stroke,
type: 'rect',
originX: 'left',
originY: 'top',
strokeWidth: this.strokeWidth
});
this.text = new fabric.IText(this.text, {
left: left + 20,
top: top + 12,
fontSize: this.fontSize,
fontFamily: this.fontFamily,
fontColor: this.fontColor,
selectable: true
});
this.text.setCoords();
this.text.setControlsVisibility({
br: false, // middle top disable
bl: false, // midle bottom
tl: false, // middle left
tr: false, // I think you get it,
mb: false,
ml: false,
mt: false,
mr: false,
mtr: false
});
this.addWithUpdate(this.rect);
this.addWithUpdate(this.text);
}
toObject() {
const obj = super.toObject();
return Object.assign(obj, {
class: this.class
});
}
}
export default Text;
You can Use Fabric's TextBox If you want flexible width and height. But I think You also need border around text, For that Grouping is good Option but You have to adjust Width and Height of Rect based on Your Text. For that You need to override onKeyDown method of Textbox and add your own method for changing width and height of Rect. Of course you can also call that function on text:changed event. I did the same , I can't share full code but here's the hint
this.LimitedTextbox = fabric.util.createClass(fabric.IText, {
//you can ignore it , here i setting fixed width to Itext
initDimensions: function() {
this.isEditing && this.initDelayedCursor();
this.clearContextTop();
if (this.__skipDimension) {
return;
}
this._splitText();
this._clearCache();
if (this.path) {
this.width = this.path.width;
this.height = this.path.height;
}
else {
let width = this.calcTextWidth();
if(width>this.maxWidth){
this.width = width;
}else{
this.width = this.maxWidth;
}
this.height = this.calcTextHeight();
}
if (this.textAlign.indexOf('justify') !== -1) {
this.enlargeSpaces();
}
this.saveState({ propertySet: '_dimensionAffectingProps' });
},
onKeyDown:function(e){
//Can be Ignored , I wanted my textbox to have limited lines only
if ((e.keyCode == 13 && this._textLines.length>=this.maxLines) ||
(e.keyCode == 9 || e.keyCode == 27)) {
this.exitEditing();
self.lastSelected = undefined;
}else{
this.callSuper('onKeyDown',e);
let maxLine = Math.max(...this.__lineWidths);
//This is What you need , A function to change border width.
self.changeBorderWidth(this.toObject().groupId, this, { iWidth: this.width, iHeight: this.height,maxLine:maxLine,id:this.toObject().id },false,this.toObject().customType==='stamp_input');
if(this.dynamicMinWidth>this.maxWidth){
this.width = this.dynamicMinWidth;
}
}
},
});
Edit: To add border to IText or Textbox https://stackoverflow.com/a/67055302/11036872
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.