I am trying to add text on an image using the element. First the image is drawn and on the image the text is drawn. So far so good.
But w
From the script here: http://www.html5canvastutorials.com/tutorials/html5-canvas-wrap-text-tutorial/
I've extended to include paragraph support. Use \n for new line.
function wrapText(context, text, x, y, line_width, line_height)
{
var line = '';
var paragraphs = text.split('\n');
for (var i = 0; i < paragraphs.length; i++)
{
var words = paragraphs[i].split(' ');
for (var n = 0; n < words.length; n++)
{
var testLine = line + words[n] + ' ';
var metrics = context.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > line_width && n > 0)
{
context.fillText(line, x, y);
line = words[n] + ' ';
y += line_height;
}
else
{
line = testLine;
}
}
context.fillText(line, x, y);
y += line_height;
line = '';
}
}
Text can be formatted like so:
var text =
[
"Paragraph 1.",
"\n\n",
"Paragraph 2."
].join("");
Use:
wrapText(context, text, x, y, line_width, line_height);
in place of
context.fillText(text, x, y);
look at https://developer.mozilla.org/en/Drawing_text_using_a_canvas#measureText%28%29
If you can see the selected text, and see its wider than your canvas, you can remove words, until the text is short enough. With the removed words, you can start at the second line and do the same.
Of course, this will not be very efficient, so you can improve it by not removing one word, but multiple words if you see the text is much wider than the canvas width.
I did not research, but maybe their are even javascript libraries that do this for you
Updated version of @mizar's answer, with one severe and one minor bug fixed.
function getLines(ctx, text, maxWidth) {
var words = text.split(" ");
var lines = [];
var currentLine = words[0];
for (var i = 1; i < words.length; i++) {
var word = words[i];
var width = ctx.measureText(currentLine + " " + word).width;
if (width < maxWidth) {
currentLine += " " + word;
} else {
lines.push(currentLine);
currentLine = word;
}
}
lines.push(currentLine);
return lines;
}
We've been using this code for some time, but today we were trying to figure out why some text wasn't drawing, and we found a bug!
It turns out that if you give a single word (without any spaces) to the getLines() function, it will return an empty array, rather than an array with a single line.
While we were investigating that, we found another (much more subtle) bug, where lines can end up slightly longer than they should be, since the original code didn't account for spaces when measuring the length of a line.
Our updated version, which works for everything we've thrown at it, is above. Let me know if you find any bugs!
Here was my spin on it... I read @mizar's answer and made some alterations to it... and with a little assistance I Was able to get this.
code removed, see fiddle.
Here is example usage. http://jsfiddle.net/9PvMU/1/ - this script can also be seen here and ended up being what I used in the end... this function assumes ctx
is available in the parent scope... if not you can always pass it in.
the post was old and had my version of the function that I was still tinkering with. This version seems to have met my needs thus far and I hope it can help anyone else.
It was brought to my attention there was a small bug in this code. It took me some time to get around to fixing it but here it is updated. I have tested it myself and it seems to work as expected now.
function fragmentText(text, maxWidth) {
var words = text.split(' '),
lines = [],
line = "";
if (ctx.measureText(text).width < maxWidth) {
return [text];
}
while (words.length > 0) {
var split = false;
while (ctx.measureText(words[0]).width >= maxWidth) {
var tmp = words[0];
words[0] = tmp.slice(0, -1);
if (!split) {
split = true;
words.splice(1, 0, tmp.slice(-1));
} else {
words[1] = tmp.slice(-1) + words[1];
}
}
if (ctx.measureText(line + words[0]).width < maxWidth) {
line += words.shift() + " ";
} else {
lines.push(line);
line = "";
}
if (words.length === 0) {
lines.push(line);
}
}
return lines;
}
Try this script to wrap the text on a canvas.
<script>
function wrapText(ctx, text, x, y, maxWidth, lineHeight) {
var words = text.split(' ');
var line = '';
for(var n = 0; n < words.length; n++) {
var testLine = line + words[n] + ' ';
var metrics = ctx.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
ctx.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else {
line = testLine;
}
}
ctx.fillText(line, x, y);
}
var canvas = document.getElementById('Canvas01');
var ctx = canvas.getContext('2d');
var maxWidth = 400;
var lineHeight = 24;
var x = (canvas.width - maxWidth) / 2;
var y = 70;
var text = 'HTML is the language for describing the structure of Web pages. HTML stands for HyperText Markup Language. Web pages consist of markup tags and plain text. HTML is written in the form of HTML elements consisting of tags enclosed in angle brackets (like <html>). HTML tags most commonly come in pairs like <h1> and </h1>, although some tags represent empty elements and so are unpaired, for example <img>..';
ctx.font = '15pt Calibri';
ctx.fillStyle = '#555555';
wrapText(ctx, text, x, y, maxWidth, lineHeight);
</script>
</body>
See demo here http://codetutorial.com/examples-canvas/canvas-examples-text-wrap.
I modified it using the code from here http://miteshmaheta.blogspot.sg/2012/07/html5-wrap-text-in-canvas.html
http://jsfiddle.net/wizztjh/kDy2U/41/