2014-09-02 85 views
2

有没有办法根据文本行数调整画布高度?文本将驻留在画布的底部。图像也会在画布的最左上角位置被绘制到画布的同一时间,因此文本将始终从画布正下方的固定位置开始。我只想让画布根据文本行数进行垂直调整,而不是在输入文本时,而不是在文本输入到textarea后单击按钮后。HTML 5画布|根据文本行数调整画布高度?

我使用这个文本:

... 

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); 
} 

目前,这个代码不打印的文本超过6行文字。我不知道在代码中修改/添加的位置(请参阅代码中的注释)。任何提示?

UPDATE瓦特/ FIDDLE

这里的实验用小提琴。请在你的答案中使用那个小提琴。在小提琴中阅读TODO评论。我很难过,但我们差不多了! Thx输入。 http://jsfiddle.net/uL84x7vw/12/

UPDATE瓦特/ FIDDLE

这是小提琴与以前相同,但图像占位符代码移动到的小提琴代码底部,所以它不会被清除。它看起来更好,但除了文本的最后一行外,所有文本行仍然被清除。显然有些代码缺失。 Thx输入。 http://jsfiddle.net/uL84x7vw/15/

回答

0

更新 - FINAL

DEMO

终于得到了它的工作!文本显示在图像占位符下,并在每次添加或删除文本行时调整(垂直)画布大小。拆分功能拆分超过画布宽度的长单词(或指定的任何宽度)。使用等宽字体进行固定宽度字符显示,但您可以尝试其他类型的字体。 Copying a canvas to image and back救了一天! :

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); 

} 

如果适用,欢迎对简化代码发表评论。 Thx输入。

0

如果你正在使用jQuery:

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

如果你没有(和你正在使用height=""属性):

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

如果您使用的CSS样式的高度:

var canvas = document.getElementById('yourCanvas'); 
canvas.style.height = (parseInt(canvas.style.height.substring(0,canvas.style.height.length-2))+14)+"px";  
+0

在我的代码中,我可以实现你的代码?另外,不需要画布重绘? Thx输入。 – koolness 2014-09-03 00:15:57

+0

应该能够在返回之前(y)做到这一点,在您的评论是 - 这是假设你只需要增加6行后的高度。 根据http://stackoverflow.com/questions/4938346/canvas-width-and-height-in-html5它会清除画布(并需要重绘),但你也应该手动清除那些浏览器的画布不。 – Jason 2014-09-03 00:26:15

+0

重绘意味着用新参数重复我的功能?我尝试过,但每次使用它时都会增加高度。我明天会提供一个小提琴进行测试。 Thx输入。 – koolness 2014-09-03 03:00:10

0

据我所知,您希望您的文本动态显示并在画布中调整大小。使用onchange事件来跟踪文本的行数并动态操作画布。每次你写人物时,它已经在画布上。使用canvas.width = canvas.width + 14;

+0

就像我上面提到的那样,在输入时没有动态应用文本到画布(我们没有看到画布)。只有在点击一个按钮后,画布才会打印文本。 Thx输入。 – koolness 2014-09-03 00:18:48

+0

请参阅使用最新的小提琴更新。 Thx输入。 – koolness 2014-09-03 18:19:46