Search code examples
javascriptcanvashtml5-canvasfabricjs

Textbox of Fabric.js does not wrap a long word


I am using the Textbox of Fabric.js. I have given a fixed width. But if a user types a long word without any space that exceeds the given width of textbox, it does not wrap.

Any solution?


Solution

  • Yes there is a solution that you may like or not to implement word breaking:

    override the fabric default function for line breaking:

    fabric.Textbox.prototype._wrapLine = function(ctx, text, lineIndex) {
    var lineWidth        = 0,
        lines            = [],
        line             = '',
        words            = text.split(' '),
        word             = '',
        letter           = '',
        offset           = 0,
        infix            = ' ',
        wordWidth        = 0,
        infixWidth       = 0,
        letterWidth      = 0,
        largestWordWidth = 0;
    
    for (var i = 0; i < words.length; i++) {
        word = words[i];
        wordWidth = this._measureText(ctx, word, lineIndex, offset);
        lineWidth += infixWidth;
    
        // Break Words if wordWidth is greater than textbox width
        if (this.breakWords && wordWidth > this.width) {
            line += infix;
            var wordLetters = word.split('');
            while (wordLetters.length) {
                letterWidth = this._getWidthOfChar(ctx, wordLetters[0], lineIndex, offset);
                if (lineWidth + letterWidth > this.width) {
                    lines.push(line);
                    line = '';
                    lineWidth = 0;
                }
                line += wordLetters.shift();
                offset++;
                lineWidth += letterWidth;
            }
            word = '';
        } else {
            lineWidth += wordWidth;
        }
    
        if (lineWidth >= this.width && line !== '') {
            lines.push(line);
            line = '';
            lineWidth = wordWidth;
        }
    
        if (line !== '' || i === 1) {
            line += infix;
        }
        line += word;
        offset += word.length;
        infixWidth = this._measureText(ctx, infix, lineIndex, offset);
        offset++;
    
        // keep track of largest word
        if (wordWidth > largestWordWidth && !this.breakWords) {
            largestWordWidth = wordWidth;
        }
    }
    
    i && lines.push(line);
    
    if (largestWordWidth > this.dynamicMinWidth) {
            this.dynamicMinWidth = largestWordWidth;
        }
    
        return lines;
    };
    

    Usage:

    var breakingTextbox = new fabric.Textbox(longText, {
            width: 200,
            breakWords: true
    });