【问题标题】:HTML 5 Canvas | Resize height of canvas according to text line count?HTML 5 画布 |根据文本行数调整画布高度?
【发布时间】:2014-09-04 22:08:23
【问题描述】:

有没有办法根据文本行数调整画布的高度?文本将位于画布底部。图像也将在画布的最左上角绘制到画布中,同时也是文本,因此文本将始终从图像下方画布上的固定位置开始。我只想让画布根据文本行数垂直调整大小,而不是在我输入时,只有在我在文本区域中输入文本后单击按钮后。

我用这个来写文字:

...

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 行文本的文本。我不知道在代码中的哪里修改/添加(参见代码中的 cmets)。有什么提示吗?

更新 w/ FIDDLE

这是一个可供试验的小提琴。请在你的答案中使用那个小提琴。阅读小提琴中的 TODO 评论。我被难住了,但我们快到了!谢谢输入。 http://jsfiddle.net/uL84x7vw/12/

更新 w/ FIDDLE

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

【问题讨论】:

    标签: javascript jquery html5-canvas


    【解决方案1】:

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

    【讨论】:

    • 就像我上面提到的,在输入时没有动态应用文本到画布(我们看不到画布)。只有在单击按钮后,画布才会打印文本。谢谢输入。
    • 查看最新的 Fiddle 更新。谢谢输入。
    【解决方案2】:

    如果您使用的是 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";    
    

    【讨论】:

    • 在我的代码中哪里可以实现你的代码?另外,不需要画布重绘吗?谢谢输入。
    • 应该能够在您的返回(y)之前做到这一点,您的评论所在 - 这是假设您只需要在 6 行之后添加高度。根据stackoverflow.com/questions/4938346/…,它会清除画布(并需要重绘),但您也应该手动清除那些不这样做的浏览器的画布。
    • 重绘意味着使用新参数重复我的功能?我试过了,但每次应用它都会增加高度。明天我将有一个小提琴可供测试。谢谢输入。
    • 您可以保存/恢复画布上的当前内容stackoverflow.com/questions/4858187/…,但是是的,jsfiddle 会很好。祝你好运!
    • 查看最新的 Fiddle 更新。谢谢输入。
    【解决方案3】:

    更新 - 最终

    DEMO

    终于搞定了!文本显示在图像占位符下,并在每次添加或删除文本行时调整(垂直)画布大小。 split 函数分割超过画布宽度(或规定的任何宽度)的长单词。使用等宽字体进行固定宽度的字符显示,但您可以尝试其他类型的字体。 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);
    
    }
    

    如果适用,请随时评论简化代码。谢谢输入。

    【讨论】:

      猜你喜欢
      • 2012-04-21
      • 2016-09-22
      • 2017-01-12
      • 2023-03-19
      • 2014-04-02
      • 2012-08-02
      • 2023-03-22
      • 2017-08-11
      • 2010-11-11
      相关资源
      最近更新 更多