HTML5 Canvas API斜体字

时间:2014-06-11 12:40:35

标签: javascript html5 canvas html5-canvas

我在HTML5中使用Canvas API时遇到一个小问题。 我有一个文本,我必须在html页面的画布上显示。

文本示例可以是“This is a Italic words”。 所以我要做的就是显示我从数据库中获取的这个文本,但是只用Italic这个句子中的一个单词。所以我必须显示如下文字:

  

“这是 Italic 字”

所以我的代码看起来像这样:

<script>
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');

  //text
  context.fillStyle  = "#000000";
  context.font = "20px Sans-Serif";
  context.textBaseline = "top";
  context.fillText  ("This is an ", 195, 80 );

  context.font = "italic 20px Sans-Serif";
  context.fillText  ("Italic", 285, 80 );
  context.font = "20px Sans-Serif";
  context.fillText  ("text", 330, 80 );
</script>

所以这段代码实际上并不是动态的,我总是知道正确的像素在哪里开始其余的句子。 有没有人知道如何动态地解决这个问题并清理?

谢谢!

2 个答案:

答案 0 :(得分:2)

为了获得某种灵活性,你必须在文本中决定一个约定,它会告诉你样式的变化 而且,你必须使用measureText来填充文本的单独“运行”,每次运行使用正确的样式,measureText(thisRun).width将为你提供当前运行的像素大小。
那么你需要的是绘制单独的文本运行,每个运行都有自己的风格,然后根据measureText的返回值移动'cursor'。

作为一个简单的例子,我把样式约定为“§r”=常规文本,“§i”= italic,“§b”=粗体,“§l”=更轻,所以字符串:

var text = "This is an §iItalic§r, a §bbold§r, and a §llighter§r text";

将输出为:

enter image description here

小提琴在这里:

http://jsfiddle.net/gamealchemist/32QXk/6/

代码是:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

// marker used in the text to mention style change
var styleMarker = '§';

// table code style --> font style
var styleCodeToStyle = {
    r: '',
    i: 'italic',
    b: 'bold',
    l: 'lighter'
};

// example text
var text = "This is an §iItalic§r, a §bbold§r, and a §llighter§r text";

// example draw
drawStyledText(text, 20, 20, 'Sans-Serif', 20);

// example text 2 : 

var text2 = "This is a text that has separate styling data";
var boldedWords = [ 3, 5, 8 ];
var italicWords = [ 2, 4 , 7];

var words = text2.split(" ");
var newText ='';

for (var i=0; i<words.length; i++) {
  var thisWord = words[i];
  if (boldedWords.indexOf(i)!=-1) 
      newText += '§b' + thisWord + '§r ';
   else if (italicWords.indexOf(i)!=-1) 
      newText += '§i' + thisWord + '§r ';
    else 
       newText += thisWord + ' ';
}

drawStyledText(newText, 20, 60, 'Sans-Serif', 20);


function drawStyledText(text, x, y, font, fontSize) {
    // start with regular style
    var fontCodeStyle = 'r';
    do {
        // set context font
        context.font = buildFont(font, fontSize, fontCodeStyle);
        // find longest run of text for current style
        var ind = text.indexOf(styleMarker);
        // take all text if no more marker
        if (ind == -1) ind = text.length;
        // fillText current run
        var run = text.substring(0, ind);
        context.fillText(run, x, y);
        // return if ended
        if (ind == text.length) return;
        // move forward
        x += context.measureText(run).width;
        // update current style
        fontCodeStyle = text[ind + 1];
        // keep only remaining part of text
        text = text.substring(ind + 2);
    } while (text.length > 0)
}


function buildFont(font, fontSize, fontCodeStyle) {
    var style = styleCodeToStyle[fontCodeStyle];
    return style + ' ' + fontSize + 'px' + ' ' + font;
}

enter image description here

答案 1 :(得分:0)

Canvas可以使用context.measureText

测量当前字体中文本的宽度

演示:http://jsfiddle.net/m1erickson/S99Zv/

enter image description here

因此,您可以创建一个绘制文本的函数,并返回刚刚绘制的文本的长度:

function drawText(text,style,x,y){

    if(ctx.font!==style){ctx.font=style;}

    ctx.fillText(text,x,y);

    return(ctx.measureText(text).width);

}

然后只需累积返回值即可知道下一个文本块的x,y:

var style1="20px Sans-Serif";
var style2="italic 20px Sans-Serif";

var accumWidth=30;

accumWidth+=drawText("This is an ",style1,accumWidth,50);
accumWidth+=drawText("italic ",style2,accumWidth,50);
accumWidth+=drawText("word",style1,accumWidth,50);