在HTML5canvas上绘制旋转的文字

我正在开发的Web应用程序的一部分,需要我创build条形图来显示各种信息。 我想,如果用户的浏览器是有能力的,我会使用HTML5canvas元素来绘制它们。 我没有问题为我的graphics绘制线条,但是在标记轴线,条形或线条时遇到了一个障碍。 如何将旋转的文字绘制到canvas元素上,以便它与所标记的项目alignment? 几个例子包括:

  • 将文本逆时针旋转90度以标记y轴
  • 将文本逆时针旋转90度以在垂直条形图上标记条形
  • 将文本旋转任意大小以标记折线图上的线条

任何指针将不胜感激。

和其他人一样,您可能想要重新使用现有的graphics解决scheme,但是旋转文本不是太困难。 有点混乱的位(对我来说)是,你旋转整个上下文,然后绘制它:

ctx.rotate(Math.PI*2/(i*6)); 

angular度以弧度表示 。 代码取自这个例子 ,我相信这是为MDCcanvas教程的转换部分 。

请参阅下面的答案以获得更完整的解决scheme。

发布这个努力来帮助其他类似问题的人。 我用五步法解决了这个问题 – 保存上下文,翻译上下文,旋转上下文,绘制文本,然后将上下文恢复到保存的状态。

我想到的翻译和转换的上下文作为操纵覆盖在canvas上的坐标网格。 默认情况下,原点(0,0)从canvas的左上angular开始。 X从左到右增加,Y从上到下增加。 如果用左手的食指和拇指做“L”,并用拇指向下握住拇指,拇指指向Y方向,食指指向方向增加X.我知道这是基本的,但我觉得它有助于思考翻译和旋转。 原因如下:

翻译上下文时,将坐标网格的原点移动到canvas上的新位置。 当旋转上下文时,考虑用左手旋转“L”,顺时针方向旋转由弧度指定的angular度所指示的量。 当您使用strokeText或fillText时,请指定与新alignment轴相关的坐标。 为了使您的文本的方向从底部到顶部可读,您可以将它们翻译到您想要开始标签的位置,旋转-90度并填充或strokeText,沿旋转的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()时的状态 – 方便将事件返回到“normal”。


虽然这是前面的答案的后续行动,但它增加了一点(希望)。

主要是我想澄清的是,通常我们会想到draw a rectangle at 10, 3东西draw a rectangle at 10, 3

所以如果我们这样想: move origin to 10, 3 ,然后draw rectangle at 0, 0 。 然后,我们所要做的就是在两者之间添加一个旋转。

另一个重点是文本的alignment。 在0,0处绘制文本最容易,所以使用正确的alignment方式可以让我们在不测量文本宽度的情况下做到这一点。

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

我创build了3个例子,提供了一个点和一个带有3个alignment的文本,以显示屏幕上的实际点是字体的位置。

在这里输入图像说明

 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 ,除了我们略微移动的文字在中心点附近居中

这是一个HTML5的替代自制软件: http : //www.rgraph.net/你也许可以逆向工程他们的方法….

你也可以考虑像Flot( http://code.google.com/p/flot/ )或GCharts:( http://www.maxb.net/scripts/jgcharts/include/demo/#1 )它不是相当酷,但完全向后兼容和可怕的易于实现。