Fabricjs Fixed TextBox

Viewed 6134

How can I fix the size of a textBox in order to prevent it to overflow its size when typing (fixed width and height)?

var canvas = window._canvas = new fabric.Canvas('c');

var text = new fabric.Textbox('MyText', {
    width: 300,
    height: 300,
    top: 5,
    left: 5,
    hasControls: false,
    fontSize: 30,
    fixedWidth: 300,
    fixedFontSize: 30
});
canvas.add(text);

http://jsfiddle.net/643qazk0/2/

3 Answers

You can override insertChars method and check text overflow.

See snippet below.

// Create canvas
const canvas = new fabric.Canvas(document.querySelector('canvas'));

// Define `LimitedTextbox` class which extends `Textbox`
const LimitedTextbox = fabric.util.createClass(fabric.Textbox, {

  // Override `insertChars` method
  insertChars: function(chars) {

    if (this.maxWidth) {
      const textWidthUnderCursor = this._getLineWidth(this.ctx, this.get2DCursorLocation().lineIndex);
      if (textWidthUnderCursor + this.ctx.measureText(chars).width > this.maxWidth) {
        chars = '\n' + chars;
      }
    }

    if (this.maxLines) {
      const newLinesLength = this._wrapText(this.ctx, this.text + chars).length;
      if (newLinesLength > this.maxLines) {
        return;
      }
    }

    // Call parent class method
    this.callSuper('insertChars', chars);
  }

});

// Create limited text box with max width 300px and max 2 lines
canvas.add(
  new LimitedTextbox('text', {
    top: 10,
    left: 10,
    width: 300,
    maxWidth: 300,
    maxLines: 2
  })
);

canvas.renderAll();
.canvas-container {
  border: 1px solid gray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.js"></script>

<canvas width="600" height="300"></canvas>

Tested with Fabric 1.7.20

For fixed textbox in fabric js Version 2+, We need to override the onInput function as follows

onInput: function(e) {
    if(this.width > this.maxWidth) {
        return;
    }

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

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

Note: maxWidth - to limit width and maxLines - to limit height / lines in text box

The solution provided here blocks only the representation of characters. Under the hood, the hidden textarea continue to accept the characters.

Therefore, if the backspace is allowed and clicked - all invisible text written after maxLines will pop up.

Solution: Synchronise the hidden text area with the text using the following code:

 if (this._textLines.length > this.maxLines && e.inputType !== 'deleteContentBackward') {
    this.hiddenTextarea.value = this.text;
    return;
 }

Related