Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fabric.js text width being ignored

Tags:

html

fabricjs

I am trying to add text to a canvas from a form input. Is there a way to automatically wrap the fabricjs text, to fit inside the canvas?

There are 3 issues I am trying to overcome: 1. the text doesn't respect the 'text.left' position if the string is longer than the given space. 2. I cannot escape newlines, so the \n is written inline with the text. 3. Center-align is completely ignored until text is updated.

Here is my fabric text:

var text = new fabric.Text($('#myInput').text(), {
    left: 10,
    top: 12,
    width: 230,
    textAlign: 'center',
    fontSize: 28,
    fontFamily: 'Helvetica Nue, Helvetica, Sans-Serif, Arial, Trebuchet MS'
});

A fiddle showing the issue.

How do I insert a newline? How do I center-align the text in the given text-block? How do position the text-block on the canvas without having to make edits?

Edit:

I have found that part of my problem was from using a text input. I changed that to a textarea element, and now newlines can be inserted easily. Weirdly, centering also works when I do this.

I guess the only issue is that the text doesn't auto-wrap when it's wider than the given text-block width. So, instead of wrapping and adding lines, it just extends beyond the canvas.

is there a way to do wordwrap type styling or do I have to count characters and insert linebreaks?

like image 475
dval Avatar asked Aug 05 '14 15:08

dval


1 Answers

I know this one's old, but I ran into this same issue. In my case, the text is in a group, so I want it to wrap to a specific width, but allow the group to resize (so I couldn't use the TextBox). I ended up pre-processing the string to put line breaks when the set width is met.

 function addTextBreaks(text, width, fontSize) {
    text = text.trim();
    var words = text.toString().split(' '),
        canvas = document.createElement('canvas'),
        context = canvas.getContext('2d'),
        idx = 1,
        newString = '';
    context.font = fontSize + 'px Lato';
    while (words.length > 0 && idx <= words.length) {
        var str = words.slice(0, idx).join(' '),
            w = context.measureText(str).width;
        if (w > width) {
            if (idx == 1) {
                idx = 2;
            }
            newString += words.slice(0, idx - 1).join(' ');
            newString += '\n';
            words = words.splice(idx - 1);
            idx = 1;
        }
        else { idx += 1;}
    }
    if (idx > 0) {
        var txt = words.join(' ');
        newString += txt;
    }
    return newString;
}
like image 113
Ben Felda Avatar answered Oct 13 '22 00:10

Ben Felda