¿Hay alguna manera de cambiar el tamaño de la altura de un lienzo según el recuento de líneas de texto? El texto residirá en la parte inferior del lienzo. También se dibujará una imagen en el lienzo en la posición superior izquierda del lienzo, al mismo tiempo que el texto, por lo que el texto siempre comenzará en una ubicación fija en el lienzo justo debajo de la imagen. Solo quiero que el lienzo cambie de tamaño verticalmente según el recuento de líneas de texto, no mientras estoy escribiendo, solo después de hacer clic en un botón después de que el texto se haya escrito en un área de texto.

Estoy usando esto para el texto:

...

var str = $('#TEXTAREA').val();

var splittext = $.map(str.split(" "), function (t) { // Split words > than 40 chars
return t.match(/[\s\S]{1,40}/g) || [];
}).join(" ");

qrc.font = 'normal normal 14px monospace';
qrc.textAlign = 'center';
qrc.fillStyle = '#000';

wrapText(qrc, splittext, x, y, maxWidth, lineHeight);

function wrapText(context, text, x, y, maxWidth, fontSize, fontFace){
var words = text.split(' ');
var line = '';
var lineHeight = fontSize;

context.font=fontSize+" "+fontFace;

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>6){return(y);} // Change to "Add 14px to canvas height at each line count" ?   
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
return(y);
}

Actualmente, este código no imprime texto más allá de 6 líneas de texto. No sé en qué parte del código modificar / agregar (ver comentarios en el código). ¿Alguna pista?

ACTUALIZACIÓN con FIDDLE

Aquí hay un violín para experimentar. Utilice ese violín en su respuesta. Lea TODO comentario en violín. Estoy perplejo, pero estamos casi thar! Thx para entrada. http://jsfiddle.net/uL84x7vw/12/

ACTUALIZACIÓN con FIDDLE

Este violín es el mismo que el anterior, pero mueve el código del marcador de posición de la imagen a la parte inferior del código del violín para que no se borre. Se ve mejor, pero todas las líneas de texto, excepto la última línea de texto, todavía se están borrando. Obviamente falta un código. Thx para entrada. http://jsfiddle.net/uL84x7vw/15/

2
koolness 3 sep. 2014 a las 03:36

3 respuestas

La mejor respuesta

ACTUALIZACIÓN - FINAL

DEMO

¡Finalmente lo conseguí funcionando! El texto se muestra debajo del marcador de posición de la imagen y cambia el tamaño (verticalmente) del lienzo en cada adición o eliminación de una línea de texto. La función de división divide palabras largas que exceden el ancho del lienzo (o cualquier ancho prescrito). Usando la fuente monoespacio para la visualización de caracteres de ancho fijo, pero puede probar otros tipos de fuentes. ¡Copiar un lienzo a la imagen y viceversa salvó el día! :

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; // Since text alignment is centered.
var y = 104;  // Start position of text (under image placeholder).
var lineCount = 1;

var splittext = $.map(str.split(" "), function (t) {
return t.match(/[\s\S]{1,20}/g) || [];
}).join(" ");

ctx.font = 'normal normal 14px monospace'; // Monospace fonts have same widths.
ctx.textAlign = 'center'; // Choose text alignment, change var x accordingly.
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){ // If more than one line of text.

// Start - Canvas copy:

/* Only use drawImage for copying Canvas contents since getImageData()
is pixel data extraction requiring more processing time and cpu overhead. */

var backCanvas = document.createElement('canvas');
backCanvas.width = elem.width;
backCanvas.height = elem.height;
var backCtx = backCanvas.getContext('2d');
backCtx.drawImage(elem, 0,0);

// End - Canvas copy.

elem.height = elem.height+(lineHeight); // Canvas resizes vertically.
ctx.font = 'normal normal 14px monospace';
ctx.textAlign = 'center'; // Choose text alignment, change var x accordingly.
ctx.fillStyle = '#000'; 

ctx.drawImage(backCanvas, 0,0); // Paste canvas copy into source canvas.   
}   
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
return(y);    
}

// Create image placeholder.

ctx.fillStyle = 'red'; 
ctx.fillRect(0,0,200,90);

}

Siéntase libre de comentar sobre la racionalización del código cuando corresponda. Thx para entrada.

0
Community 23 may. 2017 a las 11:57

Según tengo entendido, desea que su texto aparezca dinámicamente y cambie de tamaño en el lienzo. Use el evento onchange para rastrear el número de líneas de su texto y manipular dinámicamente el lienzo. Cada vez que escriba un personaje, ya estará en el lienzo. Utilice canvas.width = canvas.width + 14;

0
PashaB 2 sep. 2014 a las 23:54

Si estás usando jquery:

var canvas = $('#yourCanvas');
canvas.height(canvas.height()+14);

Si no lo está (y está utilizando el atributo height=""):

var canvas = document.getElementById('yourCanvas');
canvas.height = canvas.height+14;

Si usa CSS para diseñar la altura:

var canvas = document.getElementById('yourCanvas');
canvas.style.height = (parseInt(canvas.style.height.substring(0,canvas.style.height.length-2))+14)+"px";    
0
Jason 2 sep. 2014 a las 23:57