Monday, July 19, 2010

Combining Raphaël.js Animations

‹prev | My Chain | next›

Yesterday, I got a simple animation of a player walking working in raphaël.js:



I have all of the parts of the player moving simultaneously to simulate the walking motion. What I would like to do today is move the player across the screen while continuing the walking motion. I am not even sure if this is possible, but there is one way to find out...

For the walking animation, I am building up walking and standing data structures, then running them through two functions to draw the player and animate it:
var player = draw_object(standing);
animate_object(player, walking);
The player returned from draw_object is a Javascript object, keyed by the names of body parts (body, left leg, right foot, etc.). As of yesterday, the animate_object function iterates through each body part to animate each individually. I hope to do the same today with a translate_object function that takes the x-y coordinate that mark the end of the walk and a duration for the walk:
var player = draw_object(standing);
animate_object(player, walking);
translate_object(player, 250, 250, 5*1000);
So what should the tranlate_object function do to each body part?
function translate_object(obj, x, y, seconds) {
for (var part in obj) {
// What goes here?
};
}
I cannot simply use the translate method built-in to raphaël—it moves objects immediately rather than making a timed animation. There is the animate method. I know that works because I am already using it in the animate_object function to make the walking animation. Can I add another animate on top of that? Again one way to find out...
function translate_object(obj, x, y, seconds) {
for (var part in obj) {
obj[part].animate({cx: x, cy: y}, seconds);
};
}
Well it does not cancel out the walking animation, but unfortunately it does not apply any motion either. Eventually, I try to apply the animation to the body by hand in the console, which does not work either. It does change the coordinates at which raphaël thinks the thing is at, but no movement takes place:



Hmm. That seems kind of like a bug. I will investigate more another day. For now I would really like to see if I can move the player while the animation continues. But first, how to move the player?

Fortunately, I have solved that problem before—using animateAlong to move objects. That involves assembling an SVG lineto path to animate motion along. Using my hard-earned knowledge of SVG paths from last night, I eventually come up with:
function translate_object(obj, x, y, seconds) {
// offset between end coordinates and current location
var x_diff = x - obj.body.getBBox().x;
var y_diff = y - obj.body.getBBox().y;

for (var part in obj) {
// calculate path starting from absolute coordinates and moving
// relatively from there by the offset
var p = "M " + obj[part].getBBox().x + " " + obj[part].getBBox().y +
" l " + x_diff + " " + y_diff;

// animate along that path
obj[part].animateAlong(p, seconds);
};
}
That works to move the player about the screen, but the walking animation is cancelled:



Bummer. It would have been nice if the two animations could have been combined, but no such luck. Up tomorrow, I may consider alternatives or move on to other parts of my (fab) game.


Day #169

1 comment:

  1. This is no longer correct. With Raphael 2.1 you can independently do animate({transform:"T100,0},100) and animate({path:"New path"}, 100)

    ReplyDelete