Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing rotated text on a HTML5 canvas

Part of a web application I'm developing requires me to create bar graphs to display various information. I figured, if the user's browser is capable, I would draw them using the HTML5 canvas element. I have no problem drawing lines and bars for my graphs, but when it comes to labeling the axes, the bars, or the lines I ran into a snag. How do I draw rotated text onto a canvas element so that it lines up with the item it is labeling? A couple examples include:

  • Rotate text 90 degrees counter clockwise to label the y-axis
  • Rotate text 90 degrees counter clockwise to label bars on a vertical bar graph
  • Rotate text an arbitrary amount to label lines on a line graph

Any pointers would be appreciated.

like image 802
Sparafusile Avatar asked Jul 02 '10 17:07

Sparafusile


People also ask

How do you rotate elements in canvas?

Introduction to JavaScript rotate() canvas APIThe rotate() method allows you to rotate a drawing object on the canvas. The rotate() method accepts a rotation angle in radians. If the angle is positive, the rotation is clockwise. In case the angle is negative, the rotation is counterclockwise.

How do I make text vertical in canvas?

Place your mouse pointer on the circle arrow and press and hold the left mouse button. Drag the text while holding down the button – you should see it begin to rotate proportionally to your movement.

How do you rotate a canvas in HTML?

The HTML canvas rotate() Method is used to rotate the drawing by given angle. Note that the rotation will only work on those canvas that made after the rotation was done. Parameter Values: angle: It store the rotation angle in radian.

How do you rotate a Rectanger in canvas?

To do that you need to first context. translate to the rect's centerpoint before rotating. // move the rotation point to the center of the rect ctx. translate( x+width/2, y+height/2 ); // rotate the rect ctx.


2 Answers

Posting this in an effort to help others with similar problems. I solved this issue with a five step approach -- save the context, translate the context, rotate the context, draw the text, then restore the context to its saved state.

I think of translations and transforms to the context as manipulating the coordinate grid overlaid on the canvas. By default the origin (0,0) starts in the upper left hand corner of the canvas. X increases from left to right, Y increases from top to bottom. If you make an "L" w/ your index finger and thumb on your left hand and hold it out in front of you with your thumb down, your thumb would point in the direction of increasing Y and your index finger would point in the direction of increasing X. I know it's elementary, but I find it helpful when thinking about translations and rotations. Here's why:

When you translate the context, you move the origin of the coordinate grid to a new location on the canvas. When you rotate the context, think of rotating the "L" you made with your left hand in a clockwise direction the amount indicated by the angle you specify in radians about the origin. When you strokeText or fillText, specify your coordinates in relation to the newly aligned axes. To orient your text so it's readable from bottom to top, you would translate to a position below where you want to start your labels, rotate by -90 degrees and fill or strokeText, offsetting each label along the rotated x axis. Something like this should work:

 context.save();  context.translate(newx, newy);  context.rotate(-Math.PI/2);  context.textAlign = "center";  context.fillText("Your Label Here", labelXposition, 0);  context.restore(); 

.restore() resets the context back to the state it had when you called .save() -- handy for returning things back to "normal".


like image 66
user631644 Avatar answered Oct 02 '22 13:10

user631644


Like others have mentioned, you probably want to look at reusing an existing graphing solution, but rotating text isn't too difficult. The somewhat confusing bit (to me) is that you rotate the whole context and then draw on it:

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

The angle is in radians. The code is taken from this example, which I believe was made for the transformations part of the MDC canvas tutorial.

Please see the answer below for a more complete solution.

like image 20
robertc Avatar answered Oct 02 '22 13:10

robertc