# Raphaël zoom effect

I started playing with Raphaël and I'm wondering if somebody could do the code review of what I have so far and maybe give me some tips how to improve it. Basically what I'm trying to accomplish is the zoom-in/zoom-out effect on the element when mouseover event is being triggered on the element. The effect should paused when mouseout event is triggered. Here is what I have so far:

var paper = new Raphael(document.getElementById('container'), 500, 500);
var dot = paper.circle(100, 100, 15);

dot.attr({fill: "#ff0000"});

// is there a better way to do this?
var animation = Raphael.animation({r: 25}, 1000, function () {
this.animate({r: 15}, 1000, function () {
this.animate(animation);
});
});

dot.mouseover(function () {
dot.animate(animation);
});

dot.mouseout(function () {
this.pause();
this.animate({r: 15}, 500);
});


You can also see the demo here: http://jsfiddle.net/KEg8y/

If I understood your intention correctly, the code already works fine. However, as you are learning Raphaël, there are two minor things you could consider. Firstly, you can chain your methods when setting attributes via .attr():

var dot = paper.circle(100, 100, 15).attr({fill: "#ff0000"});


Secondly, note is that Raphaël provides the .hover() method for when you intend to use both .mouseover() and .mouseout(). Also, in your .mouseover() call, this is dot:

dot.hover(function () {
this.animate(animation);
}, function () {
this.pause();
this.animate({r: 15}, 500);
});


In my opinion, the middle part can stay as it is. However, when chaining more animations together, the nested functions could become difficult to read and understand. This is one suggestion to chain such animations in another way:

var paper = new Raphael(document.getElementById('container'), 500, 500);
var dot = paper.circle(100, 100, 15).attr({fill: "#ff0000"});

var steps = [
{params: {r: 25}, ms: 1200},
{params: {r: 35}, ms: 300},
{params: {r: 15}, ms: 800}
];

var animator = function() {
var step = steps.shift();
steps.push(step);
this.animate(step.params, step.ms, animator);
}

dot.hover(function () {
animator.call(this);
}, function () {
this.pause();
this.animate({r: 15}, 500);
});


This way, additional steps can be included into the array without further nesting any callbacks. Also, now there is only one function object animator being reused for the callbacks. The animator takes the first step from the list of steps and puts it back at the end of the array. Then, that same step is performed as animation with the animator as its callback. Note that animator is called on dot dynamically in the first .hover() function, so that the first this.animate() is called on the right object.

I have forked your fiddle: http://jsfiddle.net/rHPDP/