Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raphaël.js animation resume() fails on set

I have this piece of code (on jsfiddle)

var paper = new Raphael('holder', 400, 100);

var set = paper.set();

for(var i = 0; i < 10; i++) {
    var circle = paper.circle((i * 30) + 30, 20, 5);
    circle.attr({ fill: '#ff0' });
    circle.animate(Raphael.animation({ transform: 's2,2' }, 2000).repeat('Infinity'));

    set.push(circle);
}

set.hover(function() {
    set.pause();
}, function() {
    set.resume(); // <- things get nasty here
});​

Now when the mouse enters the set, set.pause() is called correctly and all animations stop.
But when leaving the hover area it doesn't resume the animation(s), instead I get following error in the console:

Uncaught TypeError: Cannot read property 'transform' of undefined

I have no idea why this happens; is anybody able to help?

like image 674
dan-lee Avatar asked Jul 05 '12 16:07

dan-lee


1 Answers

On Safari/Firefox, after some time after hovering out, I received this error message (using the uncompressed source at https://raw.github.com/DmitryBaranovskiy/raphael/master/raphael.js ):

`raphael.js`, line 2946: `e.totalOrigin is undefined`

The only place where totalOrigin is set is the runAnimation function:

line 3072: function runAnimation(anim, element, percent, status, totalOrigin, times) {

Your code calls first elproto.pause() (line 3352), then elproto.resume() (line 3361). pause() sets the paused property to true, resume() deletes this property. But resume also calls the status() method right after deleting the paused flag:

var e = animationElements[i];
if (eve("raphael.anim.resume." + this.id, this, e.anim) !== false) {
    delete e.paused;
    this.status(e.anim, e.status);
}

The strange, work-in-progress elproto.status method (line 3323) is only called by elproto.setTime() and elproto.resume(). This function constructs some complex return value, but no active code uses its return value, only the commented out lines starting at line 2980.

This function also calls the runAnimation function, if it has a value parameter:

 runAnimation(anim, this, -1, mmin(value, 1)     );
          totalOrigin should be passed here! ^^^

Unfortunately, it doesn't pass anything for totalOrigin, and this is the cause of the bug.

I tried adding a totalOrigin parameter based on line 3312:

 runAnimation(anim, this, -1, mmin(value, 1), this.attr());

While it seems to work, it goes buggy.

As a second attempt, I commented out the whole line:

 // runAnimation(anim, this, -1, mmin(value, 1));

Result: it works, but the timing is wrong, probably the animation start time should be updated somewhere.

http://jsfiddle.net/7nGcR/26/ https://raw.github.com/gist/3067995/1e82de48eeacf98697b572efdc74c11a9b1d9d03/gistfile1.js

like image 197
biziclop Avatar answered Sep 28 '22 13:09

biziclop