Finding the position of a point along a path in Raphael
I'm doing an animation in Raphael which involves a couple of quadratic Bezier lines emerging from a div and animating along a path towards a couple of child elements. I want the curves going to each child element to kinda draw themselves little by little until they get to the final point. The way I go around this is the following:
1) Create a central thread for the whole animation
2) In each frame, increase a variable, currentLength, by a certain amount
3) In each frame, find the current point at each curve by using getPointAtLength
4) In each frame, move a little dot to this point
5) In each frame, lineTo the new position of the little dot - straight line, but there's enough frames that the end result still looks nice and quadratic and curvy
This all works like an absolute charm except for one thing - getPointAtLength seems to be WAY slow. I've tried like 10 different approaches to this problem and the above mentioned solution is the quickest one I've come up with so far. They all work - but the inclusion of getPointAtLength makes it way too slow. Using animateAlong with a dot and then lineTo with the coordinates of that dot is not too much better, first cause it creates as many threads as there are child nodes and because it simply isn't much quicker.
Please help! Read my message, understand it, help me find a solution! getPointAtLength seems waaaaaaaaaaaay too slow - call it once every frame for 40 frames for 7 lines and 开发者_JAVA百科it makes everything slow to a crawl. Any help would be appreciated.
Raphael has a built-in animateAlong
method (http://raphaeljs.com/reference.html#animateAlong). Define your path, and then have a helper object move along the path.
Then, using the onAnimation
method (http://raphaeljs.com/reference.html#onAnimation). This method calls a function every step of the animation, and you can define the callback function to draw the portion of the curve that the helper object has reached (with the getSubpath
method).
var p = r.path("M10,50c0,50,80-50,80,0c0,50-80-50-80,0z"),
t = 4000, // length of timeout
i = p.getTotalLength()/4000, // length of path to move each time
j = 0, // counter
p2 = r.path(),
e = r.ellipse(10, 50, 1,1).attr({stroke: "none", fill: "#f00"}).onAnimation(function () {
p2.attr({path: p.getSubpath(0, j*i)});
j++;
}).animateAlong(p, t, function() {
console.log(j);
});
});
I know it gets a bit complicated, but essentially you work out how far along the path the helper object goes each step of the way (i
), and then as the counter loops (j
) you move another fraction along the path.
I'm not sure Raphael will redraw every millisecond, but there should be a way to work out how many stages there are in the animation. animateAlong
has a callback function that I have used to log j
when the animation has finished, so you can see exactly how many animation stages there are.
精彩评论