Ad

Multi-line Split Of Very Long Text On Canvas (adding Line Breaks)

- 1 answer

I have a working example here at sandbox

Because top text is very long it extends across both ends. I am trying to split the text dynamically into multi lines so that they get accommodated based on the size of image and length of input text.

How do I split the text into multilines when it much longer than the image width?

function drawTextBG(ctx, txt, font, x, y, txtWidth, imgWidth) {
  ctx.save();
  ctx.font = font;
  ctx.textAlign = "center";
  ctx.textBaseline = 'middle';
  ctx.fillStyle = '#FFFFFF';
  var dimen = measureText(txt, font)
  var height = dimen['height']
  var width = dimen['width']
  var fontsize = height/5
  ctx.fillRect(x - width/2, y-height/2 + fontsize/2, width, parseInt(font));
  ctx.fillStyle = '#000000';
  ctx.fillText(txt, x, y);
  ctx.restore();
}

In particular within the function I need to split the txt if txt is greater than imgWidth into smaller chunks with each chunk of max size imgWidth

Ad

Answer

Unfortunately canvas doesn't take "\n" into account so you have to manage multiple lines yourself.

Example over here: https://codesandbox.io/s/lucid-worker-zm0ct

From input variable 'txt'. (There is probably a more elegant way of doing this.)

  let lines = [];
  let lineCount = 0;
  let tmpTxt = txt.split(" ");
  lines[lineCount] = [];
  for(let t = 0; t < tmpTxt.length; t++){
    if(measureText(lines[lineCount].join(" "), font).width > ctx.canvas.width) {
      let lastItem = lines[lineCount].pop();
      lineCount++;
      lines[lineCount] = [lastItem];
    }
    lines[lineCount].push(tmpTxt[t]);
  }

And then you will have to render each line with a Y offset which you can get programmatically from measureText().height

  let offset = measureText(txt, font).height;
  for(let l = 0; l < lines.length; l++) {
    ctx.fillText(lines[l].join(" "), x, y + (l * offset));
  }
Ad
source: stackoverflow.com
Ad