如何在html画布中的文本周围绘制一个矩形?

时间:2015-10-14 23:51:09

标签: javascript html html5 canvas

我知道我在画布上读了几个关于上升和字体高度的东西,但我根本就没理解。

首先,为什么文本从右到上而不是从右到底的形式绘制,就像矩形一样。我在文档的任何地方都找不到。如果我想在字母周围绘制一个矩形,尤其是'y'或'p',那么我该怎么办呢?

我有canvas with text

null

如何绕过它绘制矩形?

提前致谢!

2 个答案:

答案 0 :(得分:2)

以下是在文字周围绘制矩形的一些关键

如果您希望文本从左上角对齐,则可以设置这些上下文对齐属性:

def hangman():
    answer = raw_input('Enter a word: ') # getting the word
    guesses = 6 # number of starting guesses
    word = '[' + '-'*len(answer) + ']' # this is the string of interest to be printed
    while True:
        print word, 'You have %d guesses left' % guesses,
        if guesses == 0 or '-' not in word: break
            # game finishes if word is guessed, or guesses run out
        letter = raw_input(', enter a letter: ') # guess a letter
        guesses -= 1 # decrease number of guesses by 1 each time
        for index, char in enumerate(answer): # iterate through all letters in answer
            if letter == char: # check if guessed letter is in the answer
                wordlist = list(word) # representing the word as a list to allow mutation
                wordlist[index+1] = letter # mutate the correctly guessed letter
                word = ''.join(wordlist) # recombining the list into a string

您可以使用此上下文方法测量文本的水平宽度:

context.textAlign='left';  // this is the default to align horizontally to the left
context.textBaseline='top';  // text will be aligned vertically to the top

没有原生的画布方式来测量文字高度,但对于大多数字体和非极端字体,我和你一起工作可以得到一个很好的近似高度:

// set the font size and font face before measuring
context.font='14px verdana';
var textWidth=context.measureText('Hello').width;

示例代码和演示:



var lineHeight=fontsizeInPixels * 1.286;

// get references to canvas and context
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var fontsize = 14;
var fontface = 'verdana';
var lineHeight = fontsize * 1.286;
var text = 'Draw a rectangle around me.';

ctx.font = fontsize + 'px ' + fontface;
var textWidth = ctx.measureText(text).width;

ctx.textAlign = 'left';
ctx.textBaseline = 'top';

ctx.fillText(text, 20, 50);
ctx.strokeRect(20, 50, textWidth, lineHeight);

canvas {
  border: 1px solid red;
}




答案 1 :(得分:2)

首先,一些误解:

  • ctx.closePath()方法会关闭仍处于打开状态的Path2D:即ctx.moveTo(10,10); ctx.lineTo(50, 50); ctx.lineTo(30, 50);将保留未关闭的路径。调用closePath()将为您创建最后一个ctx.lineTo(10,10) 因此,ctx.rect()始终是封闭的路径,无需调用此方法 ctx.fill()将为您关闭路径 ctx.fillText()未生成路径且已包含fill()方法,无需再次调用。

现在,为什么指定了基线而不是文本的顶部,这是因为默认情况下ctx.textBaseline属性设置为"bottom"。如果需要,您可以将其设置为"top"

目前无法在画布中获取文字的高度,但您可以使用some tricksas noted by markE,px中的近似值为1.286 * fontSize。

要获得文字中字母的位置,您可以使用ctx.measureText()方法。

因此,对于您的示例,您可以结束:

var ctx = canvas.getContext('2d');
// the font size at which we will draw text
var fontSize= 15;
// set it
ctx.font = fontSize+'px Arial';
// the text position
var x = 50, y=50;
// the string to draw
var str = "Hello yyyqqqppp ";

ctx.strokeStyle="red";

// get every characters positions
var chars = [];
for(var i=0; i<str.length;i++) {
    if (str[i] === "y" || str[i] === "p") 
    	chars.push(i);
}
//iterate through the characters list
for(var i=0; i<chars.length; i++){
  // get the x position of this character
  var xPos = x+ctx.measureText(str.substring(0,chars[i])).width;
  // get the width of this character
  var width = ctx.measureText(str.substring(chars[i],chars[i]+1)).width;
  // get its height through the 1.286 approximation
  var height = fontSize*1.286;
  // get the y position
  var yPos = y-height/1.5
  // draw the rect
  ctx.strokeRect(xPos, yPos, width, height);
  }
// draw our text
ctx.fillText(str, x, y);
<canvas id="canvas"></canvas>