I can't seem to be able to add text to a canvas if the text includes "\n". I mean, the line breaks do not show/work.
ctxPaint.fillText("s ome \n \\n <br/> thing", x, y);
The above code will draw "s ome \n <br/> thing"
, on one line.
Is this a limitation of fillText or am I doing it wrong? the "\n"s are there, and aren't printed, but they don't work either.
The fillText() method draws filled text on the canvas. If you want to break lines you can do this by splitting the text at the new lines and calling the filltext() multiple times. By doing so, you are splitting the text into lines and drawing each line separately.
To change the color of text created by fillText, use the fillStyle property. Similarly, to change the color of text created by strokeText, use the strokeStyle property: var canvas = document. querySelector( "#myCanvas" );
Solution with Javascript To add a text to the HTML <canvas> element, you need to use the fillText() or strokeText() methods, or you can use the combination of the two. You can also give color to your text, define the font and size, and even add gradients.
Drawing Text on the Canvas To draw text on a canvas, the most important property and methods are: font - defines the font properties for the text. fillText(text,x,y) - draws "filled" text on the canvas. strokeText(text,x,y) - draws text on the canvas (no fill)
If you just want to take care of the newline chars in the text you could simulate it by splitting the text at the newlines and calling multiple times the fillText()
Something like http://jsfiddle.net/BaG4J/1/
var c = document.getElementById('c').getContext('2d');
c.font = '11px Courier';
console.log(c);
var txt = 'line 1\nline 2\nthird line..';
var x = 30;
var y = 30;
var lineheight = 15;
var lines = txt.split('\n');
for (var i = 0; i<lines.length; i++)
c.fillText(lines[i], x, y + (i*lineheight) );
canvas{background-color:#ccc;}
<canvas id="c" width="150" height="150"></canvas>
I just made a wrapping proof of concept (absolute wrap at specified width. No handling words breaking, yet)
example at http://jsfiddle.net/BaG4J/2/
var c = document.getElementById('c').getContext('2d');
c.font = '11px Courier';
var txt = 'this is a very long text to print';
printAt(c, txt, 10, 20, 15, 90 );
function printAt( context , text, x, y, lineHeight, fitWidth)
{
fitWidth = fitWidth || 0;
if (fitWidth <= 0)
{
context.fillText( text, x, y );
return;
}
for (var idx = 1; idx <= text.length; idx++)
{
var str = text.substr(0, idx);
console.log(str, context.measureText(str).width, fitWidth);
if (context.measureText(str).width > fitWidth)
{
context.fillText( text.substr(0, idx-1), x, y );
printAt(context, text.substr(idx-1), x, y + lineHeight, lineHeight, fitWidth);
return;
}
}
context.fillText( text, x, y );
}
canvas{background-color:#ccc;}
<canvas id="c" width="150" height="150"></canvas>
And a word-wrapping (breaking at spaces) proof of concept.
example at http://jsfiddle.net/BaG4J/5/
var c = document.getElementById('c').getContext('2d');
c.font = '11px Courier';
var txt = 'this is a very long text. Some more to print!';
printAtWordWrap(c, txt, 10, 20, 15, 90 );
function printAtWordWrap( context , text, x, y, lineHeight, fitWidth)
{
fitWidth = fitWidth || 0;
if (fitWidth <= 0)
{
context.fillText( text, x, y );
return;
}
var words = text.split(' ');
var currentLine = 0;
var idx = 1;
while (words.length > 0 && idx <= words.length)
{
var str = words.slice(0,idx).join(' ');
var w = context.measureText(str).width;
if ( w > fitWidth )
{
if (idx==1)
{
idx=2;
}
context.fillText( words.slice(0,idx-1).join(' '), x, y + (lineHeight*currentLine) );
currentLine++;
words = words.splice(idx-1);
idx = 1;
}
else
{idx++;}
}
if (idx > 0)
context.fillText( words.join(' '), x, y + (lineHeight*currentLine) );
}
canvas{background-color:#ccc;}
<canvas id="c" width="150" height="150"></canvas>
In the second and third examples i am using the measureText()
method which shows how long (in pixels) a string will be when printed.
I'm afraid it is a limitation of Canvas' fillText
. There is no multi-line support. Whats worse, there's no built-in way to measure line height, only width, making doing it yourself even harder!
A lot of people have written their own multi-line support, perhaps the most notable project that has is Mozilla Skywriter.
The gist of what you'll need to do is multiple fillText
calls while adding the height of the text to the y value each time. (measuring the width of M is what the skywriter people do to approximate text, I believe.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With