Reputation: 5503
I have a Raphaël text object that I would like to rotate around an axis some distance away and also rotate the text accordingly so it stays horizontal. I know this is possible using SVG transformation matrices, but the author of Raphaël has stated that they won't be a part of the toolkit anytime soon. Here's some code of what I'd like to do:
txt_obj = paper.text(100, 100, "Hello!");
txt_obj.rotate(90, 100, 200); // rotate text so it is sideways at (200,200)
txt_obj.rotate(-90); // rotate text back to horizontal
Unfortunately, the second rotate command obliterates the translation and rotation accomplished by the first.
If I were doing straight SVG I could do something like this:
<g transform="rotate(90, 100, 200)">
<text x="100" y="100" transform="rotate(-90, 100, 100)">Hello!</text>
</g>
However, I don't believe that Raphaël supports the svg g
element.
Ideally I'd like to animate the operation, but I'll take it one step at a time for right now.
Upvotes: 0
Views: 4588
Reputation: 46
This is an old question but I just fought my way through it so I thought I'd share my answer.
You can access the SVG object directly, even inside your Raphael calls, thusly:
this.node.getAttribute('x')
or
this.node.getAttribute('transform')
The second one is what gets us what we need. The trouble with rotating text with Raphael is all it does is set the transform in the SVG:
<text x="600" y="606.240234375" text-anchor="middle" style="text-anchor: middle;
font: normal normal normal 10px/normal Arial; font-family: Arial; font-weight: 900;
font-size: 18px; " font="10px "Arial"" stroke="none" fill="#000000"
font-family="Arial" font-weight="900" font-size="18px" transform="rotate(45 600 600)">
<tspan style="-webkit-user-select: none; cursor: pointer; ">FOOBAR</tspan></text>
Multiple calls to .rotate() overwrite previous settings so finally there's only one call to rotate in the SVG transform. But we can add our own transforms by accessing the attribute directly. Transforms seem to be performed in reverse order (or something -- I honestly haven't thought about it too hard) so you put your additional rotation last if you want it to go first:
<script>
(function (raphael) {
$(function () {
var paper = raphael("raphael_div", 500, 500);
upside_down_text = paper.text(100,100,'UPSIDE DOWN')
.attr('font-family','Arial')
.attr('font-size','24px');
upside_down_text.rotate(25,250,250); // rotate using Raphael
// But first we want to rotate 180 degrees.
height = upside_down_text.getBBox().height;
upside_down_text.node.setAttribute('transform',
upside_down_text.node.getAttribute('transform')+
' rotate(180 '+
upside_down_text.node.getAttribute('x')+
' '+
(upside_down_text.node.getAttribute('y')-(height/2))+
')');
});
})(Raphael.ninja());
</script>
<div id="raphael_div"></div>
Upvotes: 3