Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I animate a vector path being drawn with Raphael JS?

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.

like image 266
Steve Brown Avatar asked Oct 25 '12 14:10

Steve Brown


Video Answer


2 Answers

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.

like image 65
Kevin Nielsen Avatar answered Sep 23 '22 15:09

Kevin Nielsen


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).

like image 40
Erik Dahlström Avatar answered Sep 23 '22 15:09

Erik Dahlström