Saturday, July 17, 2010

Animating Inkscape SVG in Raphaël.js

‹prev | My Chain | next›

Today, I hope to animate the player that I have created from Inkscape in raphaël.js.

Over the past few days, I have worked through the manual process of copying SVG attributes from Inkscape generated documents into raphaël.js. I have to follow a specific checklist to do it right, but a checklist is the first step in automating a process.

The end result of that process is a data structure like this, for the player while standing:
var standing = [
{ label: "left_leg",
style: "fill:none;stroke:#000000;stroke-width:0.99999779px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline",
d: "M 9.7001312,18.93142 C 9.4644309,22.702657 9.2287306,26.473893 8.9930303,30.24513" },

{ label: "left_foot",
style: " ... ",
d: " ... " },

{ label: "right_leg",
style: " ... ",
d: " ... " },

{ label: "right_foot",
style: " ... ",
d: " ... " },

{ label: "body",
style: " ... ",
d: " ... " }
];
It is important that the standing data structure is an array. The order in which the parts are drawn matters. As I found yesterday, if the legs are drawn last, they lay on top of both the player body and the feet. Still, I need a key-like thing in the data structure to identify the body part-I need it so that I can animate it properly. Raphaël is quite happy to animate a body into a leg.

I set up a similar structure for the player walking, again manually copying the attributes from the Inkscape generated SVG:
var walking = [
{ label: "left_leg",
style: " ... ",
d: " ... " },

{ label: "left_foot",
style: " ... ",
d: " ... " },

{ label: "right_leg",
style: " ... ",
d: " ... " },

{ label: "right_foot",
style: " ... ",
d: " ... " },

{ label: "body",
style: " ... ",
d: " ... " }
];
To animate my "player", I create an animate_player function:
function animate_object(obj, attr_list) {
attr_list.forEach(function(attrs) {
var new_attrs = svg_object(attrs.style);
new_attrs['path'] = attrs.d;
obj[attrs.label].animate(new_attrs, 5*1000);
});
}
For each of the body parts in the walking list, I create a Javascript object with the svg_object function (written the other night). I add a path attribute to that object. The style attributes plus the path constitute most, if not all of what can be animated in raphaël.js, so I pass them to the animate() method with a 5 second duration.

I am doing this for each of the individual parts of the player: the body (which does not change), two legs and two feet. I am not sure how well individually animating parts will work, but there is one way to find out:

video

Ooh! That's actually rather nice...

Well, except for the leg on the left spinning around in mid-air. That's just weird. What happened there is that the path being used to describe the leg started at the foot and went up to the body for the walking leg, but started at the body and went down to the foot for the standing leg. Raphaël correctly interprets this to mean that the start of the path changes during the animation.

Sigh.

I will call it a day at this point. The easiest fix is to redraw the leg in Inkscape, making sure to start from the body and move down to the foot. But I think that I will use this as an opportunity to explore a little SVG. I find it all rather mystifying at this point—ripe territory for learning. Tomorrow.


Day #167

2 comments:

  1. Chris
    Maybe "copying SVG attributes from Inkscape generated documents into raphaël.js" would be made more easy by using this?
    http://www.irunmywebsite.com/raphael/SVGTOHTML_LIVE.php
    Just a thought.
    Charles
    http://www.irunmywebsite.com

    ReplyDelete
  2. Charles,

    Heya, Thanks! At this point, I am mostly trying to learn. Once I wrap my brain around this low-level stuff well enough, I'll definitely end up using that or something like it.

    Thanks for the pointer :)

    -Chris

    ReplyDelete