Friday, July 16, 2010

Manual Method for Getting Inkscape SVG into Raphaël.js

‹prev | My Chain | next›

Continuing my Inkscape-to-raphaël.js work today, I pick up with attempting to fix this:



As mentioned yesterday, I believe that misalignment is caused by the presence of transform attributes in the SVG code generated by Inkscape. It is also a bit odd that the SVG elements are shifted down the page. My goal today is to eliminate both problems.

First up, I select all objects in all layers (the legs & feet are in a different layer so I can draw walking). The keyboard shortcut for this is Ctrl-Alt-A. Frustratingly, there is not a merge layers option in Inkscape, but I do without. The easiest problem to solve is the positioning. With all of the objects visible, I open the Align and Distribute Objects dialog, check the "Treat selection as group option", then align the elements to the top and left of the page:



With my "player" positioned starting from the top-left, I am ready to try to eliminate the transformation attribute from the generated SVG. Originally, I had hoped that a flatten-layers option might solve the transformation issue—that the layers were somehow transformed relative to each other.

After some fiddling, I realize that this is not the case. Inkscape applies the transform attribute whenever you move or resize an element. Ugh. So the question now is, do I try to get raphaël to apply those transforms or do I try to get Inkscape to remove them? I opt for the latter. I believe that I could get raphaël to honor a significant subset of Inkscape's transform attribute via the animate and scale methods (and I may give that a go another day). But it feels weird to tell raphaël to draw different parts of a player all over the game board and then shift and resize them immediately.

Fortunately, I am able to get Inkscape to drop the transforms on all of the elements. With all objects still selected, I choose Path -> Simplify (Ctrl-L). I am uncertain if the resulting path really is as simple as possible (they look longer in the generated SVG), but there are no more transform attributes in the resulting SVG which is all that I really care about.

I manually extract the d (path in raphaël) and style (attr) attributes into Javascript objects. I then re-use the draw_object function from yesterday to add them to my raphaël paper:
var paper = Raphael("container", 500, 500);

var circle = {
style:"fill:#ff0000;fill-rule:evenodd;stroke:#5c5c5c;stroke-width:2.99999332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none",
d:"m 21.675008,12.17018 c 0.21712,5.550669 -5.103955,10.720313 -10.690296,9.973244 -4.863131,-0.474753 -8.9298055,-5.025377 -8.774656,-9.92725 -0.04523,-4.5368508 3.2420352,-9.0449809 7.805525,-9.8568376 3.975851,-0.8424912 8.391473,1.1047958 10.3049,4.7247316 0.885057,1.5376501 1.375438,3.308943 1.354527,5.086112 z"
}
draw_object(circle);

var rf_standing = { ... }
draw_object(rf_standing);

var lf_standing = { ... };
draw_object(lf_standing);

var rl_standing = { ... };
draw_object(rl_standing);

var ll_standing = { ... };
draw_object(ll_standing);
Reloading yesterday's test page, I find:



Ah, much better. The legs, however are hovering over both the player body and the feet. Looks as though I was not terribly consistent about the order in which I declared the body parts. I re-arrange the order to match the order in which they are defined in the Inkscape SVG:
var ll_standing = { ... };
draw_object(ll_standing);

var lf_standing = { ... };
draw_object(lf_standing);

var rl_standing = { ... };
draw_object(rl_standing);

var rf_standing = { .. }
draw_object(rf_standing);

var circle = { ... }
draw_object(circle);
That gets me the same player that I had drawn in Inkscape now into my Raphaël paper:



That's a good stopping point for today. Up tomorrow: animating the player walking.


Day #166

No comments:

Post a Comment