Monday, May 17, 2010

Stopping Animation in Raphaël.js

‹prev | My Chain | next›

Last night I was able to get animation with raphaël.js working in my (fab) game. Tonight I want to stop it.

More to the point, I want to stop the animation of my player walking the room when I click somewhere else in the room. If I am already half way to my destination when I click, I want the animation to halt immediately. The player should then move from that location to the click event. Currently that is not happening:



I had already gotten this working with my low-level<canvas> code. I even have a method on Player that stops the walk before restarting to a new destination. In the new raphaël.js branch, it is not doing much:
Player.prototype.stop = function () {
console.debug("try to stop()");
};
That seems like a good place to get started. First up, I think I will try stop(), an undocumented raphaël.js method that halts animations:
Player.prototype.stop = function () {
console.debug("try to stop()");
this.drawable.stop();
};
Recall that drawable is how Player remembers the raphaël element (circle in this case).

That seems to halt the animation, but it is hard to know for sure. A second click event starts the animation right back up starting from the wrong coordinates. Recall also that the walk_to method sets the coordinates of a Player to the destination:
Player.prototype.walk_to = function(x, y) {
var self = this;
var p = "M"+ this.x + " " + this.y +
"L" + x + " " + y;
this.drawable.animateAlong(p, 3000);
this.x = x;
this.y = y;

};
In the case of the second click before the Player reaches the destination, those coordinates are wrong, messing up the next walk_to. What I need is a way to know the location on the raphaël.js element when the animation is stopped. Since I am already reaching under the raphaël.js API, I will go just a bit further to access the center-x / center-y attribute of my drawable element:
 Player.prototype.stop = function () {
console.debug("try to stop()");
this.drawable.stop();
this.x = this.drawable.attrs.cx;
this.y = this.drawable.attrs.cy;

};
I could have used the getBBox method as well, but then I would have to calculate the center-x / center-y value. Why bother when I can reach into attrs for it? True, there is something to be said for staying within the exposed API, but I have already given up on that when I called stop in the first place.

With that, my raphaël.js room can now animate movement even when I change my mind mid-walk:



Up tomorrow, it is retrospective time. Then I need to make sure that my raphaël-based frontend is still talking nicely to my fab.js backend.

Day #106

2 comments:

  1. Thanks for this. Raphael's stop() is not documented, so this was a major help.

    ReplyDelete
  2. Thanks. Same here. I had a case where calling stop() fixed my animation issues.

    ReplyDelete