限制 IText 或 Textbox 上的文本输入

问题描述 投票:0回答:4

我正在尝试使用 IText 或 Textbox 对象在织物画布上创建文本输入。这似乎在使用 Fabric 的 http://impretty.me 上完成得很好,但我似乎无法复制他们在这里所做的事情。我希望能够在 IText 上设置最大宽度/最大字符数,或者将 Textbox 对象限制为单行。

我的问题是在 IText 上设置宽度是无效的,即使宽度参数在 Textbox 上有效,我也需要将文本保持为单行。缩放文本(如 http://impretty.me 所示)会很好,但不是必需的。任何帮助将不胜感激。

我此时已经制定出的文本框和交互的代码如下。

const text = new fabric.IText('Type Your Message', {
  originY: 'center',
  hoverCursor: 'text',
  left: 210,
  top: 825,
  width: 300,
  fontFamily: 'Permanent Marker',
  fontSize: 50,
  hasBorders: false,
  hasControls: false,
  lockMovementX: true,
  lockMovementY: true,
  id: 'text'
})
canvas.add(text)

text.on('changed', function (options) {
  if (this.width >= 635) {
    const newText = this.text.slice(0, -1)
    this.text = newText
    this.hiddenTextarea.value = newText
    console.log(this)
  }
})
fabricjs
4个回答
1
投票

您可以调整文本大小以适合边界框

sizeDownTextNew = function(canvasObj, limit_height, limit_width )
{

    if(typeof (canvasObj) == "undefined" || canvasObj == null)
        return;
    var counter = 250; //Maximum of 250iterations to size down
    var initial_height = limit_height;
    var max = canvasObj.get('fontSize');
    var min = 6; //This is our minimum size
    var foundmin=0; //Flag if minimum is met
    var ratio = max;
    //Now reduce the size of actual text font size property
    while(canvasObj.height+2<canvasObj._getTextHeight()) //While the height of text is larger then actual text, try reducing the lineHeight
    {

        var fontSize = parseFloat(canvasObj.get('fontSize'));

        fontSize=fontSize - fontSize/max; //reduce the size with a set ratio

        if(fontSize > min) //If main font is greater then min font, we will now reduce
        {

            canvasObj.set('fontSize', fontSize);
            canvasObj.height = initial_height

        canvasObj.canvas.renderAll();
        canvasObj.height = initial_height;
        canvasObj.setCoords();
        canvasObj.canvas.renderAll();

        if(counter == 0) //Failsafe to exit the while loop if no condition is met
            break;
    }


    counter = 300;
    while(limit_width<canvasObj._getTextWidth()) //While the width of text is larger then actual text, try reducing it
    {
        var fontSize = parseFloat(canvasObj.get('fontSize'));

        fontSize=fontSize - fontSize/ratio; //reduce the size with a set ratio

            canvasObj.setCoords();
            canvasObj.canvas.renderAll();

        }
        else
        {
            break;
        }
        canvasObj.width = limit_width;
        counter -- ;
        if(counter == 0)
        {

            break;
        }

    }


}

然后像这样调用这个函数

text.on('changed', function (options) {

sizeDownTextNew(这个,500,60); })


0
投票

您可以将“maxLength”添加到文本区域。

    this.on("editing:entered", () => {
      if (this.hiddenTextarea) {
        // limit textarea length
        this.hiddenTextarea.maxLength = 40;
      }
    });

0
投票

要限制 Fabric js 版本 2+ 的文本, 我们需要重写 onInput 函数,如下

onInput: function(e) {

  if(this.width > this.maxWidth) {
    return;
  }

  if(this._textLines.length > this.maxLines) {
    return;
  }

  // Call parent class method
  this.callSuper('onInput', e);
}

注意:maxWidth - 限制宽度 和 maxLines - 限制文本框中的高度/行。
编辑:固定语法。


0
投票

解决方案可能是创建一个新的 Fabric 类来扩展 Fabric.Textbox 类。这是一个例子:

const LimitedTextbox = fabric.util.createClass(fabric.Textbox, {
  onInput: function (e: any) {
    const oldText = this.text;

    /**
     * Sometimes, when you insert a line break, it doesn't appear to Fabric as an 'insertLineBreak' but simply sets the date to null.
     * Therefore, it's important to check that it's not deleting any characters, and if the date is null, it means that a new line is being inserted
     */
    if (e.inputType === 'insertLineBreak' || (e.inputType !== 'deleteContentBackward' && !e.data)) {
      this._textBeforeEdit = oldText;
      this.hiddenTextarea.value = oldText;
      this.text = oldText;
      return;
    } else if (e.inputType !== 'deleteContentBackward') {
      if (this.width > this.maxWidth) {
        this._textBeforeEdit = oldText;
        this.hiddenTextarea.value = oldText;
        this.text = oldText;
        return;
      }

      if (this._textLines.length > this.maxLines) {
        this._textBeforeEdit = oldText;
        this.hiddenTextarea.value = oldText;
        this.text = oldText;
        return;
      }
    } else {
      /**
       * It's needed because otherwise, if I write many characters, he automatically adjusts the width even if the visible text doesn't change.
       * So, every time I delete something, I reset the width.
       * I do it during deletion; otherwise, if I do it in the maxWidth check, I never block it, and it would keep writing
       */
      this.width = this.maxWidth;
    }

    this.callSuper('onInput', e);
  },
});

...

textbox = new LimitedTextbox('custom text', {
  maxLines: 1,
  maxWidth: 100,
});
© www.soinside.com 2019 - 2024. All rights reserved.