javascript - Fabric.js - 带有免费矩形边界框的文本,如 Google 幻灯片
问题描述
我正在使用 Fabric.js 制作绘图编辑器。要求之一是创建灵活的文本框组件(如 Goole Slides 或 Power Point),其边界框可以在不影响文本大小和其他文本控件(如缩放、重新定位)的情况下进行调整……目前,fabric.js 提供fabric.Text
的不是足以完成这项任务。所以我正在使用fabric.Group
,但我对选择问题很感兴趣。我无法选择组的子对象。我该如何解决这个问题。欢迎任何信息
这是我想要实现的:
这就是我现在拥有的原始fabric.Text
对象
这就是我所取得的成就fabric.Group
这是我的课程,用于文本框
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;
解决方案
如果你想要灵活的宽度和高度,你可以使用 Fabric 的 TextBox。但我认为您还需要文本周围的边框,因为分组是一个很好的选项,但您必须根据您的文本调整 Rect 的宽度和高度。为此,您需要覆盖 Textbox 的 onKeyDown 方法并添加您自己的方法来更改 Rect 的宽度和高度。当然,您也可以在 text:changed 事件上调用该函数。我做了同样的事情,我不能分享完整的代码,但这里是提示
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;
}
}
},
});
编辑:向 IText 或文本框添加边框 https://stackoverflow.com/a/67055302/11036872
推荐阅读
- python - 更改文件会导致 GitHub Desktop 上重复更改的文件(和 Git Bash:git status)
- firebase - 基于 Firebase 数据库中 where 子句的查询
- spring-boot - springdoc-openapi 注释中的占位符
- python - 如何使用列表中的链接下载文件?
- r - 加载多个形状文件 Shiny r
- django - Wagtail 管理员 - 允许编辑器编辑自定义设置
- javascript - 我的 script.js 文件中的新引用函数不会使作者姓名出现
- angular - Angular Lifecycle Interface OnChanges 应该为方法 ngOnChanges 实现
- selenium - 在 AWS Lambda 上调试 Selenium 和 Chromedriver(无法访问 Chrome)
- lua - ROBLOX LUAu | 获取 DataStore 中的所有键和值