Javascript 在HTML5画布上绘制旋转文本

Javascript 在HTML5画布上绘制旋转文本,javascript,html,canvas,Javascript,Html,Canvas,我正在开发的web应用程序的一部分要求我创建条形图来显示各种信息。我想,如果用户的浏览器能够,我会使用HTML5画布元素来绘制它们。我在为我的图形绘制线条和线条时没有问题,但是当涉及到标记轴、线条或线条时,我遇到了障碍。如何在画布元素上绘制旋转文本,使其与标记的项目对齐?几个例子包括: 将文本旋转90度计数器 顺时针标记y轴 将文本旋转90度计数器 顺时针在垂直方向上标记条 条形图 将文本旋转任意数量以 在线图上标记线 任何提示都将不胜感激。这里有一个HTML5替代自制的方案:您可以对他们的

我正在开发的web应用程序的一部分要求我创建条形图来显示各种信息。我想,如果用户的浏览器能够,我会使用HTML5画布元素来绘制它们。我在为我的图形绘制线条和线条时没有问题,但是当涉及到标记轴、线条或线条时,我遇到了障碍。如何在画布元素上绘制旋转文本,使其与标记的项目对齐?几个例子包括:

  • 将文本旋转90度计数器 顺时针标记y轴
  • 将文本旋转90度计数器 顺时针在垂直方向上标记条 条形图
  • 将文本旋转任意数量以 在线图上标记线

任何提示都将不胜感激。

这里有一个HTML5替代自制的方案:您可以对他们的方法进行反向工程


你也可以考虑一些类似FLUT()或GCARS:()它不太酷,但完全向后兼容和可怕的易于实现。

像其他人提到的,你可能想看看重用现有的图形解决方案,但是旋转文本不是太难。(对我来说)有点让人困惑的是,你旋转整个上下文,然后在上面画:

ctx.rotate(Math.PI*2/(i*6));
这个。代码是,我相信它是为


请参阅以获得更完整的解决方案。

发布此消息是为了帮助其他有类似问题的人。我用五步方法解决了这个问题——保存上下文、翻译上下文、旋转上下文、绘制文本,然后将上下文恢复到保存的状态

我认为对上下文的翻译和转换就是操纵覆盖在画布上的坐标网格。默认情况下,原点(0,0)从画布的左上角开始。X从左到右增加,Y从上到下增加。如果你用食指和拇指在左手上做一个“L”,然后拇指朝下,将它举到你面前,你的拇指会指向Y的增加方向,食指会指向X的增加方向。我知道这是基本的,但我发现在考虑平移和旋转时它很有用。原因如下:

转换上下文时,将坐标栅格的原点移动到画布上的新位置。旋转上下文时,请考虑将左手制作的“L”沿顺时针方向旋转,旋转量由以弧度表示的原点角度表示。当您选择strokeText或fillText时,请指定相对于新对齐轴的坐标。若要调整文本的方向,使其从下到上可读,您需要将文本平移到下面的位置,在该位置开始标签,旋转-90度,填充或笔划文本,沿旋转的x轴偏移每个标签。像这样的方法应该会奏效:

 context.save();
 context.translate(newx, newy);
 context.rotate(-Math.PI/2);
 context.textAlign = "center";
 context.fillText("Your Label Here", labelXposition, 0);
 context.restore();
.restore()将上下文重置回调用.save()时的状态--用于将内容返回到“正常”状态



虽然这是上一个答案的后续,但它增加了一点(希望如此)

我主要想澄清的是,通常我们想画的东西是
在10,3处画一个矩形

如果我们这样想:
将原点移动到10,3
,然后
在0,0处绘制矩形。
然后我们要做的就是在中间加一个旋转

另一个要点是文本的对齐。在0,0处绘制文本是最容易的,因此使用正确的对齐方式可以让我们在不测量文本宽度的情况下进行绘制

我们仍然应该将文本移动一定量以使其垂直居中,不幸的是canvas没有很好的线条高度支持,所以这是一个猜测和检查的事情(如果有更好的东西,请纠正我)

我创建了3个示例,提供了一个点和一个带有3条对齐线的文本,以显示屏幕上的实际点是字体的位置

var font, lineHeight, x, y;

x = 100;
y = 100;
font = 20;
lineHeight = 15; // this is guess and check as far as I know
this.context.font = font + 'px Arial';


// Right Aligned
this.context.save();
this.context.translate(x, y);
this.context.rotate(-Math.PI / 4);

this.context.textAlign = 'right';
this.context.fillText('right', 0, lineHeight / 2);

this.context.restore();

this.context.fillStyle = 'red';
this.context.fillRect(x, y, 2, 2);


// Center
this.context.fillStyle = 'black';
x = 150;
y = 100;

this.context.save();
this.context.translate(x, y);
this.context.rotate(-Math.PI / 4);

this.context.textAlign = 'center';
this.context.fillText('center', 0, lineHeight / 2);

this.context.restore();

this.context.fillStyle = 'red';
this.context.fillRect(x, y, 2, 2);


// Left
this.context.fillStyle = 'black';
x = 200;
y = 100;

this.context.save();
this.context.translate(x, y);
this.context.rotate(-Math.PI / 4);

this.context.textAlign = 'left';
this.context.fillText('left', 0, lineHeight / 2);

this.context.restore();

this.context.fillStyle = 'red';
this.context.fillRect(x, y, 2, 2);


this.context.fillText('right',0,lineHeight/2)
基本上是
0,0
,除了我们稍微移动一下,使文本居中于点附近

Funkodebat发布了一个很棒的解决方案,我已经多次引用了它。 尽管如此,每当我需要这个时,我发现自己都在编写自己的工作模型。 所以,这是我的工作模式。。。更加清晰

首先,文本的高度等于像素字体大小。 现在,这是我不久前读到的东西,它在我的计算中得到了解决。我不确定这是否适用于所有字体,但它似乎适用于Arial和无衬线字体

此外,为了确保将所有文本都放在画布中(并且不要修剪“p”的尾部),您需要设置context.textb基线*

您将在代码中看到,我们正在围绕文本中心旋转文本。 为此,我们需要将context.textAlign=“center”context.textbeliness设置为底部,否则,我们将删除部分文本

为什么要调整画布的大小? 我通常有一张画布,但没有附加到页面上。我用它来画我所有的旋转文本,然后我把它画到另一个画布上,我显示它。 例如,您可以使用此画布绘制图表的所有标签(一个接一个),并将隐藏的画布绘制到需要标签的图表画布上(
context.drawImage(HiddenCavas,0,0);

重要提示:在测量文本之前设置字体,并在调整画布大小后将所有样式重新应用于上下文。调整画布大小时,画布的上下文将完全重置

希望这有帮助

var c=document.getElementById(“myCanvas”);
var ctx=c.getContext(“2d”);
变量字体,文本,x,y;
text=“密西西比”;
//测量前设置字体大小
font=20;
ctx.font=font+'px Arial,无衬线';
//获取文本的宽度
var度量=ctx.measure