8

Has anyone used .animateWith() in Raphael to successfully keep fast animations in sync? It is poorly documented. The library's creator has a video demonstration but no code I can find.

I have a Javascript metronome that consists of a line (the arm of the metronome) and a trapezoidal shaped "weight" that will eventually move up and down to signify tempo. I have a working fiddle here, and the lines in question are:

        var ticktock = Raphael.animation({
            "50%": { transform:"R20 " + x + "," + y, easing: "sinoid", callback: function() { tick(this, repeats, done); }},
            "100%": { transform:"R-20 " + x + "," + y, easing: "sinoid", callback: function() { tick(this, repeats, done); }}
        }, interval).repeat(repeats / 2);
        arm.animate(ticktock);
        weight.animateWith(arm, ticktock, ticktock);    

If you check out the fiddle and give it a high tempo and about 20 ticks, you should see the weight lag behind the arm. (Please try it a few times if not -- Murphy's Law etc.) I thought this was precisely what animateWith() prevented. Maybe I am using it incorrectly.

If you look at the Raphael source for the .animateWith() function, you see it syncs the .start param of each animation, FWIW.

Chris Wilson
  • 6,599
  • 8
  • 35
  • 71

1 Answers1

7

From the Raphael documentation:

Parameters:

element - [object] element to sync with

anim - [object] animation to sync with

animation - [object] animation object, see Raphael.animation

So I think your code just need to separate the animation and pass that into second parameter for .animateWith():

The animation portion is just:

{
    "50%": { transform:"R20 " + x + "," + y, easing: "sinoid", callback: animationDone },
    "100%": { transform:"R-20 " + x + "," + y, easing: "sinoid", callback: animationDone }
} 

So you can do this:

var animationDone = function() { 
    tick(this, repeats, done); 
};

var ticktockAnimationParam = {
    "50%": { transform:"R20 " + x + "," + y, easing: "sinoid", callback: animationDone },
    "100%": { transform:"R-20 " + x + "," + y, easing: "sinoid", callback: animationDone }
};
var ticktock = Raphael.animation(ticktockAnimationParam, interval).repeat(repeats / 2);
arm.animate(ticktock);
weight.animateWith(arm, ticktockAnimationParam, ticktock);    

See fiddle: http://jsfiddle.net/wDwsW/7/

Fyi , I moved the callback function outside, instead of using anonymous functions.

Amy
  • 7,388
  • 2
  • 20
  • 31
  • Thanks for the look. I'm afraid I'm still getting some fairly significant dislocation at high periods -- try 280 beats per minute -- in Chrome. The documentation makes very little sense to me. The source for the function appears to just match the "start" property of the animations in some animation array. Maybe it just doesn't work? – Chris Wilson Apr 18 '13 at 03:12
  • Source here: https://github.com/DmitryBaranovskiy/raphael/blob/master/raphael.core.js#L4123 – Chris Wilson Apr 18 '13 at 03:13
  • @ChrisWilson Working smoothly for me. Using Chrome also. My machine is 3.2Ghz Intel i5 with 8gb RAM running on OSX 10.8.3 – Amy Apr 18 '13 at 19:18
  • I'm not 100% certain animateWith() works to perfection, but accepting and rewarding bounty bc this does appear to be the correct usage, which was the question. Thank you! – Chris Wilson Apr 24 '13 at 14:27