JSFiddle - React, Tailwind, and code Playground
HTML
<textarea id="textArea">Finally got it working! The text displays under the image placeholder and resizes (vertically) the canvas at each addition or deletion of line of text. The split function splits long words exceeding canvas width (or whatever width prescribed). Go ahead, add or remove text and Show Canvas!</textarea><br>
<button id="myButton">Show Canvas</button><br>
<canvas id="myCanvas"></canvas>
JavaScript
$('#myButton').click(function(){
showCanvas();
});
function showCanvas(){
var elem = document.getElementById('myCanvas');
var wd = 200;
var ht = 110;
ctx = elem.getContext('2d');
ctx.canvas.width = wd;
ctx.canvas.height = ht;
ctx.fillStyle = '#FFF'; // text area BG color
ctx.fillRect(0,0,wd,ht);
var str = $('#textArea').val();
var maxWidth = 190;
var lineHeight = 14;
var x = 100;
var y = 104;
var lineCount = 1;
var splittext = $.map(str.split(" "), function (t) { // Split words > than 20 words length
return t.match(/[\s\S]{1,20}/g) || [];
}).join(" ");
ctx.font = 'normal normal 14px monospace';
ctx.textAlign = 'center';
ctx.fillStyle = '#000';
wrapText(ctx, splittext, x, y, maxWidth, lineHeight);
function wrapText(context, text, x, y, maxWidth, fontSize){
var words = text.split(' ');
var line = '';
var lineHeight = fontSize;
context.font=fontSize+" ";
for(var n = 0; n < words.length; n++){
var testLine = line + words[n] + ' ';
var metrics = context.measureText(testLine);
var testWidth = metrics.width;
if(testWidth > maxWidth) {
context.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
if(++lineCount>1){
var backCanvas = document.createElement('canvas');
backCanvas.width = elem.width;
backCanvas.height = elem.height;
var backCtx = backCanvas.getContext('2d');
// save main canvas contents
backCtx.drawImage(elem, 0,0);
elem.height = elem.height+(lineHeight); // Resize amount
ctx.font = 'normal normal 14px monospace';
ctx.textAlign = 'center';
ctx.fillStyle = '#000';
ctx.drawImage(backCanvas, 0,0);
}
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
return(y);
}
// Image placeholder
ctx.fillStyle = '#f00';
ctx.fillRect(0,0,200,90);
// end Image placeholder
}