0
votes

Firefox (v21) seems quite erratical in rendering text in a textarea. I want to be able to write on a canvas, by using a textarea. It is a layer on top of the canvas, and the latter 'listens' to the key commands in the textarea, to render the same text. Chrome behaves pretty well in this respect, but in Firefox I have to compensate with adding extra pixel height and width when writing to the canvas, depending on font size and type. This is something I can can work around, but if someone has an idea if this is a bug or can be fixed in a neat way, suggestions are welcome.

However! :) I haven't been able to work around some other (IMO) strange behavior of the textarea: sometimes when the text reaches the end of line it just breaks off the last word when adding a white spice. To demonstrate this you can look here: http://generation-v.nl/test.html

I think you should be able to see the whole text on the first line, but when you add a white space at the end of the first line, the last word 'er' suddenly moves to the next line. It seems as FF counts the white space as part of the word in measuring its width. Chrome just keeps the word 'er' on the same line when adding the white space. (btw, the red text you might see is the text on the canvas)

I've tried 'word-break: break-all;' but then the white space is padded to the start of the next line. Suggestions to solve this are very welcome. Thanks!

1
Any reson to use canvas? - Nitesh
Yes, I am making a canvas drawing tool :) - Fab

1 Answers

0
votes

I found a hack solution to my problem, which is based on measuring the width of the text on a line by cloning it into an 'inline-block' span and measuring this text-width. Here is the result:

http://jsfiddle.net/RPgrq/

var ta = document.getElementsByTagName('textarea')[0],
sp = document.getElementById('span'),
false_keys = [37,38, 39, 40] , width= 150;

ta.addEventListener('keyup', function(e) {
var text = this.value, count = text.length, n = 0, test_width, new_string = '', caret_start = this.selectionStart, caret_end = this.selectionEnd;

if(false_keys.indexOf(e.keyCode) > -1) { return; }

sp.innerHTML = '';
for(n = 0; n < count ; n++) {
    switch(text[n]) {
        case ' ' : sp.innerHTML += '&nbsp'; break;
        case '\n': sp.innerHTML = ''; break;
        default: sp.innerHTML += text[n]; break;
    }
    new_string += text[n];

    test_width = parseInt(window.getComputedStyle(sp).getPropertyValue('width').slice(0,-2), 10);
    if(test_width >= width) {
        if(new_string.slice(-1) == ' ' || new_string.slice(-1) == '\n') {
            new_string = new_string.slice(0, -1) + '\n';
        }
        else {
            new_string = new_string.replace(/\s([^\s]*)$/, '\n$1');         
        }
        sp.innerHTML = '' ; 
    }
}

this.value = new_string;
this.setSelectionRange(caret_start, caret_end);
});

(note: in the script frame you can set the 'width' variable to wrap the text)