How can I animate a vector path being drawn with Raphael JS?
I have a set of coordinates that I would like to connect using Raphael JS.
On a grid, the coordinates are (x,y sets). I would like to start from one end and "connect the dots" as the user watches. The end product would look something like this:
Picture 9.png http://img213.imageshack.us/img213/8013/picture9my.png
Ideally, I would like to be able to make the paths curved so they would look more like this (coordinates added for reference):
Picture 10.png http://img534.imageshack.us/img534/1789/picture10fc.png
The coordinates are:
26,-6
14,-12
5,-20
11,-28
14,-37
5,-40
I've been searching Google and I have read through this question How to draw a vector path progressively? (Raphael.js) but I am trying to use Raphael.js specifically and the example on that page for Raphael.js does not seem to work nor does it talk about using multiple coordinate points for inputs.
Progressive Paths
Drawing a path progressively is easy to do. I dislike the second-most-accepted answer on this question because it recreates a path at every step, clearing the paper in between. Here's the utility function I've used time and time again:
function drawpath( canvas, pathstr, duration, attr, callback )
{
var guide_path = canvas.path( pathstr ).attr( { stroke: "none", fill: "none" } );
var path = canvas.path( guide_path.getSubpath( 0, 1 ) ).attr( attr );
var total_length = guide_path.getTotalLength( guide_path );
var last_point = guide_path.getPointAtLength( 0 );
var start_time = new Date().getTime();
var interval_length = 50;
var result = path;
var interval_id = setInterval( function()
{
var elapsed_time = new Date().getTime() - start_time;
var this_length = elapsed_time / duration * total_length;
var subpathstr = guide_path.getSubpath( 0, this_length );
attr.path = subpathstr;
path.animate( attr, interval_length );
if ( elapsed_time >= duration )
{
clearInterval( interval_id );
if ( callback != undefined ) callback();
guide_path.remove();
}
}, interval_length );
return result;
}
You can see it in action on my site.
This alone would make animating the progressive path construction of your points in a linear fashion absolutely simple. You'd simply compile your path...
var sequence_path = ["M26,-6", "L14,-12", "L5,-20", "L11,-28", "L14,-37", "L5,-40"];
And then pass it to whatever path animation function you've set up. In my case,
drawpath( paper,
sequence_path,
3500,
{ stroke: 'black', 'stroke-width': 2, 'stroke-opacity': 1, fill: 'none', 'fill-opacity': 0 },
function()
{
alert("All done"); // trigger whatever you want here
} );
Curve Interpolation
Raphael 2.0's Catmull Rom feature makes curving gracefully between your points extremely straightforward (thanks to Erik Dahlström for pointing this out). All you need to do is construct a path using the 'R' command to move between points, and Raphael will do the rest.
function generateInterpolatedPath( points )
{
var path_sequence = [];
path_sequence.push( "M", points[0].x, points[0].y );
path_sequence.push( "R" );
for ( var i = 1; i < points.length; i++ )
{
path_sequence.push( points[i].x, points[i].y );
}
return path_sequence;
}
You can see all the pieces working together here.
You could also use Catmull Rom (see http://raphaeljs.com/reference.html#Paper.path) to get the smooth curve through the given points.
Live demo here (click to assign points, then shift-click to transition to Catmull Rom curve).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With