HTML5 canvas ctx.fillText 不会换行?
如果文本包含“\n”,我似乎无法将文本添加到画布。我的意思是,换行符不显示/工作。
ctxPaint.fillText("s ome \n \\n <br/> thing", x, y);
上面的代码将在一行上绘制“s ome \n
。
gt; thing”
这是 fillText 的限制还是我做错了? “\n”在那里,但没有打印,但它们也不起作用。
I can't seem to be able to add text to a canvas if the text includes "\n". I mean, the line breaks do not show/work.
ctxPaint.fillText("s ome \n \\n <br/> thing", x, y);
The above code will draw "s ome \n <br/> thing"
, on one line.
Is this a limitation of fillText or am I doing it wrong? the "\n"s are there, and aren't printed, but they don't work either.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(20)
如果您只想处理文本中的换行符,您可以通过在换行符处拆分文本并多次调用
fillText()
来模拟它,例如 http://jsfiddle.net/BaG4J/1/
我刚刚做了一个换行概念验证(以指定宽度绝对换行。尚未处理断词)
示例位于 http://jsfiddle.net/BaG4J/2/
还有一个自动换行(在空格处)概念证明。
示例位于 http://jsfiddle.net/BaG4J/5/
在第二个和第三个示例中,我使用
measureText()
方法显示打印时字符串的长度(以像素为单位)。If you just want to take care of the newline chars in the text you could simulate it by splitting the text at the newlines and calling multiple times the
fillText()
Something like http://jsfiddle.net/BaG4J/1/
I just made a wrapping proof of concept (absolute wrap at specified width. No handling words breaking, yet)
example at http://jsfiddle.net/BaG4J/2/
And a word-wrapping (breaking at spaces) proof of concept.
example at http://jsfiddle.net/BaG4J/5/
In the second and third examples i am using the
measureText()
method which shows how long (in pixels) a string will be when printed.恐怕这是 Canvas 的
fillText
的限制。没有多线支持。更糟糕的是,没有内置的方法来测量线高,只能测量线宽,这让你自己测量变得更加困难!很多人都编写了自己的多行支持,也许最著名的项目是 Mozilla Skywriter 。
您需要做的要点是多次
fillText
调用,同时每次将文本的高度添加到 y 值。 (我相信,测量 M 的宽度是 Skywriter 人员用来近似文本的方法。)I'm afraid it is a limitation of Canvas'
fillText
. There is no multi-line support. Whats worse, there's no built-in way to measure line height, only width, making doing it yourself even harder!A lot of people have written their own multi-line support, perhaps the most notable project that has is Mozilla Skywriter.
The gist of what you'll need to do is multiple
fillText
calls while adding the height of the text to the y value each time. (measuring the width of M is what the skywriter people do to approximate text, I believe.)也许来这个聚会有点晚了,但我发现以下在画布上包装文本的教程非常完美。
http://www.html5canvastutorials.com/tutorials/html5-canvas-包装文本教程/
从那以后,我能够想到让多行工作(抱歉拉米雷斯,你的不适合我!)。我将文本包装在画布中的完整代码如下:
其中
c
是我的画布的 ID,text
是我的文本框的 ID。正如您可能看到的,我使用的是非标准字体。只要您在操作画布之前在某些文本上使用了该字体,就可以使用@font-face - 否则画布将无法拾取该字体。
希望这对某人有帮助。
Maybe coming to this party a bit late, but I found the following tutorial for wrapping text on a canvas perfect.
http://www.html5canvastutorials.com/tutorials/html5-canvas-wrap-text-tutorial/
From that I was able to think get multi lines working (sorry Ramirez, yours didn't work for me!). My complete code to wrap text in a canvas is as follows:
Where
c
is the ID of my canvas andtext
is the ID of my textbox.As you can probably see am using a non-standard font. You can use @font-face as long as you have used the font on some text PRIOR to manipulating the canvas - otherwise the canvas won't pick up the font.
Hope this helps someone.
将文本分成几行,并分别绘制每行:
Split the text into lines, and draw each separately:
这是我的解决方案,修改此处已介绍的流行的wrappText()函数。我正在使用 JavaScript 的原型功能,以便您可以从画布上下文中调用该函数。
基本用法:
这是我整理的一个演示:
http://jsfiddle.net/7RdbL/
Here's my solution, modifying the popular wrapText() function that is already presented here. I'm using the prototyping feature of JavaScript so that you can call the function from the canvas context.
Basic usage:
Here's a demonstration I put together:
http://jsfiddle.net/7RdbL/
我刚刚扩展了 CanvasRenderingContext2D,添加了两个函数:mlFillText 和 mlStrokeText。
您可以在GitHub中找到最新版本:
使用此功能,您可以在框中填充/描边miltiline文本。您可以垂直和水平对齐文本。 (它考虑了
\n
并且还可以证明文本的合理性)。原型为:
其中
vAlign
可以是:top
、center
或button
以及
hAlign
> 可以是:left
、center
、right
或justify
您可以在此处测试该库:http://jsfiddle.net/4WRZj/1/
这是库的代码:
这是使用示例:
I just extended the
CanvasRenderingContext2D
adding two functions: mlFillText and mlStrokeText.You can find the last version in GitHub:
With this functions you can fill / stroke miltiline text in a box. You can align the text verticaly and horizontaly. (It takes in account
\n
's and can also justify the text).The prototypes are:
Where
vAlign
can be:top
,center
orbutton
And
hAlign
can be:left
,center
,right
orjustify
You can test the lib here: http://jsfiddle.net/4WRZj/1/
Here is the code of the library:
And here is the use example:
我在这里为这种情况创建了一个小型库: Canvas-Txt
它以多行形式呈现文本,并且它提供了不错的对齐模式。
< /a>
为了使用它,您需要安装它或使用 CDN。
安装
JavaScript
这将在一个不可见的框中呈现文本,其位置/尺寸为:
Example Fiddle
I created a tiny library for this scenario here: Canvas-Txt
It renders text in multi-line and it offers decent alignment modes.
In order to use this, you will need to either install it or use a CDN.
Installation
JavaScript
This will render text in an invisible box with position/dimensions of:
Example Fiddle
我使用 javascript 开发了一个解决方案。它并不漂亮,但对我有用:
希望有帮助!
Using javascript I developed a solution. It isn't beautiful but it worked for me:
Hope that helps!
如果您只需要两行文本,则可以将它们拆分为两个不同的 fillText 调用,并为每个调用提供不同的基线。
If you only need two lines of text, you can split them into two different fillText calls and give each one a different baseline.
@Gaby Petrioli 非常有帮助。
我扩展了他的代码以提供对换行符
\n
的支持。此外,通常情况下,获取边界框的尺寸很有用,因此multiMeasureText()
同时返回宽度和高度。您可以在此处查看代码: http://jsfiddle.net/jeffchan/WHgaY/76/
The code for word-wrapping (breaking at spaces) provided by @Gaby Petrioli is very helpful.
I've extended his code to provide support for newline characters
\n
. Also, often times it's useful to have the dimensions of the bounding box, somultiMeasureText()
returns both the width and the height.You can see the code here: http://jsfiddle.net/jeffchan/WHgaY/76/
这是 Colin 的
wrapText()
的一个版本,它还支持使用context.textBaseline = 'middle'
的垂直居中文本:Here's a version of Colin's
wrapText()
that also supports vertically centered text withcontext.textBaseline = 'middle'
:这个问题并不是考虑画布的工作原理。如果您想要换行,只需调整下一个 ctx.fillText 的坐标即可。
This question isn't thinking in terms of how canvas works. If you want a line break just simply adjust the coordinates of your next
ctx.fillText
.有一个维护良好的 JS 库,名为 Canvas-Txt ,它能够处理换行符和文字换行。我发现它比该线程中的所有随机代码片段更有用。
There is a well-maintained JS library called Canvas-Txt that is able to handle line breaks and text wrapping. I found it much more usable than all the random code snippets in this thread.
我认为你仍然可以依赖CSS
幸运的是,通过CSS hack-ardry(请参阅Typography Metrics了解更多修复使用CSS测量的旧实现的方法),我们可以通过测量具有相同字体的a的offsetHeight来找到文本的高度 -属性:
来自:
http://www.html5rocks.com/en/tutorials/canvas/texteffects/
I think you can still rely on CSS
Luckily, through CSS hack-ardry ( seeTypographic Metrics for more ways to fix older implementations of using CSS measurements), we can find the height of the text through measuring the offsetHeight of a with the same font-properties:
from:
http://www.html5rocks.com/en/tutorials/canvas/texteffects/
我创建了 wraptext 库,帮助换行文本以适应视图的限制。
为了换行文本,我们需要实现 2 个逻辑:
虽然这个答案距离问题发布的那一刻还太远,但我希望这对那些有同样问题的人有所帮助。
I have created the wraptext library that helps wrap text to fit the limitations of the view.
To wrap the text, we need to implement 2 logic:
Though this answer is too far from the moment the question was posted, I hope this will be helpful for those who have the same issue.
我认为这也是不可能的,但解决方法是创建一个
元素并使用 Javascript 对其进行定位。
I don't think this is possible neither, but a workaround for this is to create a
<p>
element and position it with Javascript.由于遇到同样的问题,我遇到了这个问题。我正在使用可变字体大小,因此考虑到了这一点:
其中 .noteContent 是用户编辑的 contenteditable div(嵌套在 jQueryeach 函数中),ctx.font 是“14px Arial”(请注意,像素大小优先)
I happened across this due to having the same problem. I'm working with variable font size, so this takes that into account:
where .noteContent is the contenteditable div the user edited (this is nested in a jQuery each function), and ctx.font is "14px Arial" (notice that the pixel size comes first)
这是我在画布中绘制多行文本中心的函数(仅断线,不断字)
如果您想让文本大小适合画布,您还可以查看此处
Here is my function to draw multiple lines of text center in canvas (only break the line, don't break-word)
If you want to fit text size to canvas, you can also check here
Canvas 元素不支持换行符 '\n'、制表符 '\t' 或 << br>>标签。
尝试一下:
或者多行:
Canvas element doesn't support such characters as newline '\n', tab '\t' or < br /> tag.
Try it:
or perhaps multiple lines:
我针对该问题的 ES5 解决方案:
有关该问题的更多信息位于 我的博客。
My ES5 solution for the problem:
More information on the issue is on my blog.