【问题标题】:Fabric.js - Text with free rectangular bounding box like Google slidesFabric.js - 带有免费矩形边界框的文本,如 Google 幻灯片
【发布时间】:2024-04-21 04:40:02
【问题描述】:

我正在使用 Fabric.js 制作绘图编辑器。要求之一是创建灵活的文本框组件(如 Goole Slides 或 Power Point),其边界框可以在不影响文本大小和其他文本控件(如缩放、重新定位)的情况下进行调整......目前,fabric.js 提供 @987654327 @ 不足以完成此任务。所以我正在使用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;

【问题讨论】:

    标签: javascript canvas html5-canvas drawing fabricjs


    【解决方案1】:

    如果你想要灵活的宽度和高度,你可以使用 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://*.com/a/67055302/11036872

    【讨论】: