【问题标题】:Retrieve lines of text stored in an array and display them on a canvas with line breaks?检索存储在数组中的文本行并将它们显示在带有换行符的画布上?
【发布时间】:2013-10-28 05:26:44
【问题描述】:

下面是一个数组,它的元素存储了一些长文本行。

var fcontent = [
["Definition: The term computer is obtained from the word compute. A computer is an electronic device that inputs (takes in) facts (known as data), and then processes (does something to or with) it. Afterwards it outputs, or displays, the results for you to see. Data is all kinds of facts, including, pictures, letters, numbers, sounds, etc."],

["Moreover: A computer is a system that is made up of a number of components. Next is a diagram of a computer system with some of its components"],
]; 

我正在使用以下函数在 Canvas 上显示元素:

firstLevelContent:function()
{
    var startPoint = 48;  $('.gamelayer').hide();
    $('#gamecanvas').show();       
    for (var i=0; i<fcontent.length; i++)
    {
        game.context.strokeRect(1,  25, 637, 385);
        game.context.fillStyle = 'brown';
        game.context.font = 'bold 20px sans-serif';
        game.context.textBaseline = 'bottom';
        game.context.fillText(fcontent[i], 2, startPoint);
        startPoint+=17;
    }
},

但是文本显示在代码中,我想找到一种方法来换行以适应画布的宽度(640),以便我可以看到所有显示的文本。请帮助我。谢谢。

【问题讨论】:

  • 这不是 JavaScript 问题。您需要做的就是在 css 中为画布指定宽度。你能告诉我你用于画布的CSS吗?如果有正确的 css 类,文本将自动适合他的宽度。
  • @GeorgianBurungiu。不,html 画布不会自动应用换行符以使文本适合画布宽度。
  • 您必须使用 javascript 手动进行文本换行。您可以使用 context.measureText 方法来获取每个单词的宽度。当累积的单词超过画布长度时,开始换行。查看以前的 Stackoverflow 答案,了解如何在 html 画布上将文本换行到多行:stackoverflow.com/questions/2936112/…

标签: javascript html5-canvas


【解决方案1】:

您需要一个自动换行功能,将您的文本分成合适长度的行。关于如何做到这一点还有其他关于 SO 的建议,但似乎它们中的大多数都没有正确解释过长的单词(即当单个单词长于所需宽度时)或空格(即大多数假设单个单词之间的空格字符)。我有一个想法并想出了这个:

function wordWrap(text, width, ctx, useHyphen) {
    var words = text.split(/\b(?=\w)/),
        wrappedText = [],
        wordLength = 0,
        fullLength = 0,
        line = "",
        lineLength = 0,
        spacer = useHyphen ? "-" : "",
        spacerLength = ctx.measureText(spacer).width,
        letterLength = 0;

    // make sure width to font size ratio is reasonable
    if (ctx.measureText("M"+spacer).width > width) {return [];}

    // produce lines of text
    for (var i=0, l=words.length; i<l; i++) {

        wordLength = ctx.measureText(words[i].replace(/\s+$/,"")).width;
        fullLength = ctx.measureText(words[i]).width;

        if (lineLength + wordLength < width) {
            line += words[i];
            lineLength += fullLength;
        } else if (wordLength < width) {
            wrappedText.push(line);
            line = words[i];
            lineLength = fullLength;  
        } else {
            // word is too long so needs splitting up

            for (var k=0, lim=words[i].length; k<lim; k++) {

                letterLength = ctx.measureText(words[i][k]).width;

                if (words[i][k+1] && /\S/.test(words[i][k+1])) {

                    if (lineLength + letterLength + spacerLength < width) {
                        line += words[i][k];
                        lineLength += letterLength;
                    } else {
                        if (true || words[i][k+1] && /\s/.test(words[i][k+1])) {line += spacer;}
                        wrappedText.push(line);
                        line = words[i][k];
                        lineLength = letterLength;
                    }

                } else {
                    // last 'letter' in word

                    if (lineLength + letterLength < width) {
                        line += words[i].substr(k);
                        lineLength += ctx.measureText(words[i].substr(k)).width;
                    } else {
                        line += spacer;
                        wrappedText.push(line);
                        line = words[i].substr(k);
                        lineLength = ctx.measureText(words[i].substr(k)).width;
                    }

                    break;

                }


            }

        }
    }

    wrappedText.push(line);

    // strip trailing whitespace from each line
    for (var j=0, len=wrappedText.length; j<len; j++) {
        wrappedText[j] = wrappedText[j].replace(/\s+$/,"");
    }

    return wrappedText;

}

它可能可以改进,但它对我有用:http://jsfiddle.net/cP5Fz/9/

注意:在调用wordWrap 函数之前,您需要之前设置要使用的字体大小。

至于你传递的参数:

  • text: 你要换行的文字
  • width: 文本必须适合的宽度
  • ctx: 画布的上下文
  • useHyphen:设置为true,如果你想用连字符分隔长词(可选)

然后它将返回一个字符串数组,每个字符串都将分别放入所需的空间。

【讨论】:

  • 单词在音节间断连字,因此您可以通过在元音后的第一个辅音后断字来改善连字。
  • @markE 是的,好点。如果我有时间,我可能会玩弄它。
  • 我尝试了你的功能,但显示为空白是参数传递有什么问题:game.wrapText(fcontent[i], maxWidths, game.context, true); ?提示:fcontent-是要换行的文本,maxWidths 是画布宽度,game.context 是画布的上下文。谢谢。
  • @user2896649 你能帮我看看你是如何使用它的吗? jsfiddle.net
  • 请多多包涵,我是 js 和 jquery 的新手。这就是我使用它的方式:game.context.strokeRect(1, 25, 637, 385); game.context.fillStyle = '棕色'; game.context.font = 'bold 20px sans-serif'; game.context.textBaseline = '底部'; ctx=game.context; var texts=fcontent[i];最大宽度=620; var textLines = game.wrapWord(texts, maxWidths, ctx, true); for (var i = 0, l = textLines.length; i
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
  • 2011-03-12
  • 2012-04-21
  • 2016-07-08
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多