A Demo drawing a complex path using uniformly spaced points:
http://jsfiddle.net/m1erickson/2fodu9pa/
An overview of Uniform Speed
"Speed" is defined as distance per unit of time.
"Uniform Speed" is therefore traveling a consistent specified distance per unit of time.
So, moving along your path at 2 pixels per 1/60th second would be an example of moving at a uniform speed.
To travel 2 pixels you must calculate a point along your path that is 2 pixels from your last point.
Incrementally drawing a path that contains lines & curves at a uniform speed requires hundreds of small calculations.
Here's how to determine an array of points that are spaced at evenly spaced along your path:
Divide your path into their segments: line, quadratic curve, Bezier curve, line.
Calculate many (300+) points along each segment using the math formula that defines each segment (see formulas below) and put those points in an array.
Sequentially walk along each point and calculate the distance between points (see formula below).
Keep a total of the accumulated distance traveled along the points.
When the current point traveled reaches the specified length, save that point in a second array.
Then to animate the path incrementally you can create an animation loop that draws a line to each next point in the second array.
Note: If you keep the specified distance small enough (eg 1-2 pixels), then the lines drawn appear curved where necessary.
Here are Formula that support this method:
Calculate Points along Line:
// T is an interval between 0.00 and 1.00
// To divide a Line into 300 parts you would call the function 300 times
// with T increasing 1.00/300 each time
function getLineXYatPercent(startPt,endPt,T) {
var dx = endPt.x-startPt.x;
var dy = endPt.y-startPt.y;
var X = startPt.x + dx*T;
var Y = startPt.y + dy*T;
return( {x:X,y:Y} );
}
Calculate Points along Quadratic Curve:
// T is an interval between 0.00 and 1.00
// To divide a Quadratic Curve into 300 parts you would call the function 300 times
// with T increasing 1.00/300 each time
function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x;
var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y;
return( {x:x,y:y} );
}
Calculate Points along Bezier Curve:
// T is an interval between 0.00 and 1.00
// To divide a BezierCurve into 300 parts you would call the function 300 times
// with T increasing 1.00/300 each time
function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
// cubic helper formula at T distance
function CubicN(T, a,b,c,d) {
var t2 = T * T;
var t3 = t2 * T;
return a + (-a * 3 + T * (3 * a - a * T)) * T
+ (3 * b + T * (-6 * b + b * 3 * T)) * T
+ (c * 3 - c * 3 * T) * t2
+ d * t3;
}
Distance between 2 points:
var dx=point2.x-point1.x;
var dy=point2.y-point1.y;
var distance=Math.sqrt(dx*dx+dy*dy);
Good luck with your project!