简体   繁体   English

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

[英]how do I draw a rectangle around a text in html canvas?

I know I read a couple of stuff about ascent and font height in canvas but I simply don't get it. 我知道我在画布上读到了一些有关上升和字体高度的信息,但我根本不了解。

First of all why is the text drawn from right to top instead of the form right to bottom like with rectangles. 首先,为什么要从右到上绘制文本,而不是像矩形一样从右到下绘制文本。 I can't find that anywhere in the doc. 我在文档的任何地方都找不到。 And then what do I do if I want to draw a rectangle around a letter, especially 'y' or 'p' the ones that go below the baseline. 然后,如果我想在一个字母周围绘制一个矩形,特别是基线以下的“ y”或“ p”,该怎么办。

I have a canvas with text , 我有一个带有文字画布

 ctx.beginPath();
  ctx.fillText('Hello yyyqqqppp', 50, 50);
  ctx.fillStyle = 'red';
  ctx.fill();
  ctx.closePath();

what do I do to get the rectangle drawn around it? 我该怎么做才能在其周围绘制矩形?

Thanks in advance! 提前致谢!

Here are some keys to drawing a rectangle around text 这是一些在文本周围绘制矩形的键

If you want the text to be aligned from the top-left then you can set these context alignment properties: 如果要从左上角对齐文本,则可以设置以下上下文对齐属性:

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

You can measure the horizontal width of text using this context method: 您可以使用以下上下文方法测量文本的水平宽度:

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

There is no native canvas way to measure text height, but for most fonts and non-extreme font sizes I've worked with you can get a good approximation of the height like this: 没有原生的画布方式可以测量文本高度,但是对于我使用过的大多数字体和非极限字体大小,您都可以像这样获得高度的近似值:

var lineHeight=fontsizeInPixels * 1.286;

Example code and a Demo: 示例代码和演示:

 // 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; } 
 <canvas id=canvas width=300 height=300></canvas> 

First, a few misconceptions : 首先,一些误解:

  • ctx.closePath() method does close a Path2D that is still open : ie ctx.moveTo(10,10); ctx.lineTo(50, 50); ctx.lineTo(30, 50); ctx.closePath()方法确实关闭仍然打开的Path2D:即ctx.moveTo(10,10); ctx.lineTo(50, 50); ctx.lineTo(30, 50); ctx.moveTo(10,10); ctx.lineTo(50, 50); ctx.lineTo(30, 50); will leave an unclosed path. 将留下一条未封闭的道路。 Calling closePath() will create the last ctx.lineTo(10,10) for you. 调用closePath()将为您创建最后一个ctx.lineTo(10,10)
    ctx.rect() is therefore always a closed path, no need to call this method. 因此, ctx.rect()始终是封闭路径,无需调用此方法。
    ctx.fill() will close the path for you. ctx.fill()将为您关闭路径。
    ctx.fillText() doesn't produce a path and already includes the fill() method, no need to call it again. ctx.fillText()不会产生路径,并且已经包含fill()方法,无需再次调用它。

Now, why is the baseline specified instead of the top of the text, it is because by default the ctx.textBaseline property is set to "bottom" . 现在,为什么指定基线而不是文本的顶部,这是因为默认情况下ctx.textBaseline属性设置为"bottom" You can set it to "top" if you need. 如果需要,可以将其设置为"top"

There is currently no way to get the height of a text in canvas but you can use some tricks or as noted by markE , an approximation of 1.286*fontSize in px. 当前无法获取画布中文本的高度,但是您可以使用一些技巧,或者如markE所指出的那样 ,以px表示的近似1.286 * fontSize。

To get the position of a letter in your text, you can use the ctx.measureText() method. 要获取字母在文本中的位置,可以使用ctx.measureText()方法。

So for your example you can end with : 因此,对于您的示例,您可以结尾为:

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM